Add permission boundaries to the stack - aws-cloudformation

When I deploy a CDK stack - it creates several roles, both explicitly e.g. via iam.Role construct, and implicitly e.g. when roles are created internally by Level 2 constructs.
Is there a way to attach an existing permission boundary to all the roles being created by the stack - both explicit and implicit?

Yes, through aspects.
You can add the following in bin/app.ts (the file might be named differently):
class ConfigurePermissionBoundary implements IAspect {
visit(node: IConstruct): void {
if (node instanceof CfnRole) {
const stack1 = Stack.of(node);
let policy = stack1.node.tryFindChild('GlobalPermissionBoundaryPolicy') as ManagedPolicy | undefined
if (!policy) {
policy = new ManagedPolicy(stack1, 'GlobalPermissionBoundaryPolicy', {
statements: [new PolicyStatement({
effect: Effect.DENY,
actions: ['sts:*'],
resources: ['*']
})]
})
}
node.permissionsBoundary = policy.managedPolicyArn
}
}
}
Aspects.of(app).add(new ConfigurePermissionBoundary())
Please note that we're adding a managed policy GlobalPermissionBoundaryPolicy that defines the permission boundary once.
Also, the aspect handles both new iam.Role() as well as any new CfnRole() defined by your or library code.

Related

How to retain an object instance across unnamed/differently named scopes?

As shown in the runnable code example below I want to create a named scope wherein a certain instance of an object is resolved regardless of other unnamed scopes that are created after the object is created.
With regard to the documentation found here:
// You can't resolve a per-matching-lifetime-scope component
// if there's no matching scope.
using(var noTagScope = container.BeginLifetimeScope())
{
// This throws an exception because this scope doesn't
// have the expected tag and neither does any parent scope!
var fail = noTagScope.Resolve<Worker>();
}
In my case in the example below a parent scope DOES have a matching tag but it still does not work. Should it?
In the following example scopes are tidy and parent scopes are known - In my application only the root container object is accessible so when a scope is created it is always from the container not the parent scope.
public class User
{
public string Name { get; set; }
}
public class SomeService
{
public SomeService(User user)
{
Console.WriteLine($"Injected user is named {user.Name}");
}
}
class Program
{
private static IContainer container;
private const string USER_IDENTITY_SCOPE = "SOME_NAME";
static void Main(string[] args)
{
BuildContainer();
Run();
Console.ReadKey();
}
private static void BuildContainer()
{
ContainerBuilder builder = new ContainerBuilder();
builder.RegisterType<SomeService>();
builder.RegisterType<User>().InstancePerMatchingLifetimeScope(USER_IDENTITY_SCOPE);
container = builder.Build();
}
private static void Run()
{
using (var outerScope = container.BeginLifetimeScope(USER_IDENTITY_SCOPE))
{
User outerUser = outerScope.Resolve<User>();
outerUser.Name = "Alice"; // User Alice lives in this USER_IDENTITY_SCOPE
SomeService someService = outerScope.Resolve<SomeService>(); // Alice
// Now we want to run a "process" under the identity of a different user
// Inside of the following using block, we want all services that
// receive a User object to receive Bob:
using (var innerSope = container.BeginLifetimeScope(USER_IDENTITY_SCOPE))
{
User innerUser = innerSope.Resolve<User>();
innerUser.Name = "Bob"; // We get a new instance of user as expected. User Bob lives in this USER_IDENTITY_SCOPE
// Scopes happen in my app that are unrelated to user identity - how do I retain User object despite this?
// The following is not a USER_IDENTITY_SCOPE -- We still want Bob to be the User object that is resolved:
using (var unnamedScope = container.BeginLifetimeScope())
{
// Crashes. Desired result: User Bob is injected
SomeService anotherSomeService = unnamedScope.Resolve<SomeService>();
}
}
}
}
}
Using Autofac 4.9.2 / .net core 2.2
In your example, you're launching the unnamed scope from the container, not from a parent with a name:
using (var unnamedScope = container.BeginLifetimeScope())
Switch that to be a child of a scope with a name and it'll work.
using (var unnamedScope = innerScope.BeginLifetimeScope())
I'd also note that you've named these outerScope and innerScope but innerScope is not actually a child of the outerScope so the names are misleading. Technically the two scopes are peers.
container
innerScope (named)
outerScope (named)
unnamedScope
All three are direct children of the container. If you think about sharing the user in terms of scope hierarchy, you'd need to make child scopes from parents that have children.
container
innerScope (named)
unnamedScope
outerScope (named)
unnamedScope
You'll notice inner and outer are still peers - you can't have a parent and a child with the same name, so given inner and outer are both named, they'll never share the same hierarchy except for the container.
I would strongly recommend not trying to bypass a hierarchical model here. For example, say you really are trying to do this:
container
outerScope (named)
unnamedScope
Which might look like this:
using(var outerScope = container.BeginLifetimeScope(USER_IDENTITY_SCOPE))
using(var unnamedScope = container.BeginLifetimeScope())
{
//...
}
This is pretty much what you have in the snippet above. The only common sharing these scopes have is at the container level. If you tried to resolve something from the named scope and pass it to a peer scope, you run the risk of things being disposed out from under you or other weird hard-to-troubleshoot problems. Like if outerScope gets disposed but unnamedScope lives on, you can get into trouble.
// PLEASE DO NOT DO THIS. YOU WILL RUN INTO TROUBLE.
using(var outerScope = container.BeginLifetimeScope(USER_IDENTITY_SCOPE))
{
var user = outerScope.Resolve<User>();
using(var unnamedScope = container.BeginLifetimeScope(b => b.RegisterInstance(user)))
{
//...
}
}
That's bad news waiting to happen, from odd disposal problems to things not sharing the same set of dependencies when you think they should. But, you know, we can give you the gun, it's up to you to not shoot yourself in the foot with it.

Groovy DSLD and ServiceLoader pattern

I have in my Groovy scripts an implicit variable, "services", whose role is to lookup services in a registry.
I can call it with the following syntaxe :
def myService = services.lookup 'com.test.MyService'
The implementation of the lookup method doesn't return an instance of MyService, but a special GroovyObject which delegate missing methods to the service.
I want to tell Eclipse that calls to myService should be delegated to MyService, in order to add to the autocompletion list all methods from MyService. However, I didn't success to implements it with a DSLD definition.
Is it possible to implement such behavior ?
I have used two contributions :
The first one discover every call to services.lookup and populates a map in wormhole
The second one declare every properties in the wormhole map as a global property
A simplified version :
contribute(isMyDSL() & currentType('ServiceProxy') & bind(exprs: assignedVariable(currentType()))) {
def name = exprs[0].leftExpression.name
def classType - exprs[0].arguments.getExpression(0).text /* Introspecting MethodCall */
def services = wormhole.services
if (!services) {
services = [:]
wormhole.services = services
}
services[name] = classType
}
contribute(isMyDSL() & isThisType()) {
wormhole.properties?.each { name, type ->
property name:name, type:type, doc:"OSGI Service: ${type}"
}
}

Group outline nodes

I'm developing an XTEXT 2.0 plugin. I'd like to group some nodes inside my outline in a "virtual" node. Which is the right way to achieve this result?
Currently if i want to group nodes of type "A", in my OutlineTreeProvider I define the following method
protected void _createNode(IOutlineNode parentNode, A node) {
if(this.myContainerNode == null){
A container = S3DFactoryImpl.eINSTANCE.createA();
super._createNode(parentNode, container);
List<IOutlineNode> children = parentNode.getChildren();
this.myContainerNode = children.get(children.size()-1);
}
super._createNode(this.myContainerNode, node);
}
Reading the Xtext 2.0 documentation i saw also that there is a EStructuralFeatureNode. I didn't understand exactly what this type of node is and how to use it. Can you explain what EStructuralFeatureNode is used for?
Many thanks
There are a couple of problems with your code:
this.myContainerNode: There is no guarantee that your provider is a prototype; someone could configure the instance as singleton. Therefore, avoid instance fields.
There are two solutions to this problem:
Search the parent node for your container node whenever you need it (slow but simple)
Add a cache to your instance (see How do I attach some cached information to an Eclipse editor or resource?)
super._createNode(): Don't call the methods with _, always call the plain version (super.createNode()). That method will figure out which overloaded _create* method to call for you. But in your case, you can't call any of these methods because you'd get a loop. Call createEObjectNode() instead.
Lastely, you don't need to create an instance of A (S3DFactoryImpl.eINSTANCE.createA()). Nodes can be backed by model elements but that's optional.
For grouping, I use this class:
public class VirtualOutlineNode extends AbstractOutlineNode {
protected VirtualOutlineNode( IOutlineNode parent, Image image, Object text, boolean isLeaf ) {
super( parent, image, text, isLeaf );
}
}
In your case, the code would look like so:
protected void _createNode(IOutlineNode parentNode, A node) {
VirtualOutlineNode group = findExistingNode();
if( null == group ) {
group = new VirtualOutlineNode( parentNode, null, "Group A", false );
}
// calling super._createNode() or super.createNode() would create a loop
createEObjectNode( group, node );
}

How to work with dependency injection within SOA?

I'm currently using SOA, I've a bunch of Service, (ArticleService, CommentService, UserService, etc..)
I also have a ConfigurationService which is filled from an XML configuration file.
I'm using Zend Framework.
THis configuration service is needed in some of my service, and I'm using dependency injection, is it a good practice, to add ConfigurationService in constructor of most my Service to be able to fetch global configuration?
Thank you for your feedbacks.
I would say, no, don't pass the config container - neither as a service nor as an array nor a Zend_Config instance - in the constructor of your other services. I would keep the injection (whether by constructor or by setter) for those services focused on the actual objects/collaborators/data they actually need.
So, for example, an ArticleService might depend upon an ArticleRepository interface/object or on an ArticleMapper or on a db adapter. Let the constructor/setter signatures for the ArticleService reflect what it truly needs.
Instead, what I would do is during Bootstrap, create some kind of factory object - perhaps as an application resource - that accepts in its constructor your config data/object/service (or even better, the bootstrap instance itself, from which you could get, not just your config data, but also any application resources, like a db adapter, that were created during the bootstrap process). Then write methods on your factory object that create/deliver the other services you need. Internally, the factory maintains a registry of already created services so that it can lazy-create instances where required.
A snippet of what I have in mind might be as follows:
Bootstrap snippet:
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
protected function _initFactory()
{
$factory = new My_Factory($this);
return $factory;
}
}
Then the factory:
class My_Factory
{
protected $_registry;
protected $_bootstrap;
public function __constructor($bootstrap)
{
$this->_bootstrap = $bootstrap;
}
public function getDbAdapter()
{
if (!isset($this->_registry['dbAdapter']){
$this->_bootstrap->bootstrap('db'); // probably using app resource
$this->_registry['dbAdapter'] = $This->_bootstrap->getResource('db');
}
return $this->_registry['dbAdapter'];
}
public function getArticleService()
{
if (!isset($this->_registry['articleService']){
$dbAdapter = $this->getDbAdapter();
$this->_registry['articleService'] = new My_ArticleService($dbAdapter);
}
return $this->_registry['articleService'];
}
public function getTwitterService()
{
if (!isset($this->_registry['twitterService']){
$options = $this->_bootstrap->getOptions();
$user = $options['twitter']['user'];
$pass = $options['twitter']['pass'];
$this->_registry['twitterService'] = new My_TwitterService($user, $pass);
}
return $this->_registry['twitterService'];
}
}
Then in a controller, you could grab an ArticleService instance:
class SomeController extends Zend_Controller_Action
{
protected $_factory;
public function init()
{
$this->_factory = $this->getInvokeArg('bootstrap')->getResource('factory');
}
public function someAction()
{
$articleService = $this->_factory->getArticleService();
$this->view->articles = $articleService->getRecentArticles(5); // for example
}
}
The upshot here is that each service explicitly identifies the collaborators it needs and the factory is a single place that takes care of creating/injecting all those collaborators.
Finally, I confess that I am just spitballing here. To me, this is essentially a rudimentary dependency injection container; in that sense, using a fully-featured DIC - perhaps the Symfony DIC or the new Zend\Di package in ZF2 - might be better. But after many months of struggling with all the best-practice recommendations to inject your dependencies, this is what I have come up with. If it's goofy or just plain wrong, please (please!) straighten me out. ;-)

Replace registration in Autofac

I have an application which does data processing. There is
class Pipeline {
IEnumerable<IFilter> Filters {get; set;}
I register filters implementations as
builder.RegisterType<DiversityFilter>().As<IFilter>();
builder.RegisterType<OverflowFilter>().As<IFilter>();
...
So far so good. Now, for experimentation and fine-tuning I want to be able to override any filter implementation in config file with a program(script) which would read data from stdin, process it and send data to stdout. I've implemented a module with "fileName", "args" and "insteadOf" custom properties, described module in xml and got it called.
In the module I register my "ExecutableFilter" but how do I make it run "instead of" desired service? If I try do it like this:
builder.RegisterType<ExecutableFilter>().As<DiversityFilter>()
then I get an exception " The type 'ExecutableFilter' is not assignable to service 'DiversityFilter'.". Ok, this is logical. But what are my options then?
Once you've overridden the registration for IFilter "After" with your wire-tap, you won't be able to resolve it from the container, as the new registration will be activated instead, hence the circular lookup.
Instead, create and register a module that hooks into the filter's creation, and replaces the instance with the 'wire tapped' one:
class WiretapModule : Module
{
override void AttachToComponentRegistration(
IComponentRegistration registration,
IComponentRegistry registry)
{
if (registration.Services.OfType<KeyedService>().Any(
s => s.ServiceKey == After && s.ServiceType == typeof(IFilter)))
{
registration.Activating += (s, e) => {
e.Instance = new WireTap((IFilter)e.Instance, new ExecuteProvider(fileName, args))
};
}
}
}
(Cross-posted to the Autofac group: https://groups.google.com/forum/#!topic/autofac/yLbTeuCObrU)
What you describe is part container work, part business logic. The challenge is to keep separation of concerns here. IMO, the container should do what it is supposed to do, that is building and serving up instances or collections thereof. It should not do the "instead of" in this case. I would rather "enrich" the services with enough information so that the pipeline make the decision.
The "enrichment" can be accomplished by making the ExecutableFilter implement a more distinct interface.
interface IInsteadOfFilter : IFilter { }
...
builder.RegisterType<ExecutableFilter>().As<IFilter>();
...
class Pipeline
{
IEnumerable<IFilter> Filters {get;set;}
public void DoTheFiltering()
{
var filters = Filters.OfType<IInsteadOfFilter>();
if (!insteadof.Any())
filters = Filters;
foreach(var filter in filters)
{
...
}
}
You could also solve this using the metadata infrastructure, which gives us an even more expressive way of differentiating services.