Skip to content

Commit

Permalink
feat: Make roleName available on IRole (#1589)
Browse files Browse the repository at this point in the history
The `iam.Policy` class expected to be provided (concrete) `Role` instances,
making it unusable when all that is available is an `IRole` (as should be in
most situations). This changes the API to accept an `IRole` instead, increasing
the usability.
  • Loading branch information
RomainMuller authored Jan 22, 2019
1 parent 2b491d4 commit 9128390
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 6 deletions.
2 changes: 1 addition & 1 deletion packages/@aws-cdk/assert/lib/assertions/have-resource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class HaveResourceAssertion extends Assertion<StackInspector> {
}

public assertUsing(inspector: StackInspector): boolean {
for (const logicalId of Object.keys(inspector.value.Resources)) {
for (const logicalId of Object.keys(inspector.value.Resources || {})) {
const resource = inspector.value.Resources[logicalId];
if (resource.Type === this.resourceType) {
const propsToCheck = this.part === ResourcePart.Properties ? resource.Properties : resource;
Expand Down
4 changes: 4 additions & 0 deletions packages/@aws-cdk/aws-iam/lib/lazy-role.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ export class LazyRole extends cdk.Construct implements IRole {
return this.instantiate().roleId;
}

public get roleName(): string {
return this.instantiate().roleName;
}

/**
* Returns a Principal object representing the ARN of this role.
*/
Expand Down
8 changes: 4 additions & 4 deletions packages/@aws-cdk/aws-iam/lib/policy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Construct, IDependable, Token } from '@aws-cdk/cdk';
import { Group } from './group';
import { CfnPolicy } from './iam.generated';
import { PolicyDocument, PolicyPrincipal, PolicyStatement } from './policy-document';
import { Role } from './role';
import { IRole } from './role';
import { User } from './user';
import { generatePolicyName, undefinedIfEmpty } from './util';

Expand Down Expand Up @@ -62,7 +62,7 @@ export interface PolicyProps {
* Roles to attach this policy to.
* You can also use `attachToRole(role)` to attach this policy to a role.
*/
roles?: Role[];
roles?: IRole[];

/**
* Groups to attach this policy to.
Expand Down Expand Up @@ -99,7 +99,7 @@ export class Policy extends Construct implements IDependable {
*/
public readonly dependencyElements: IDependable[];

private readonly roles = new Array<Role>();
private readonly roles = new Array<IRole>();
private readonly users = new Array<User>();
private readonly groups = new Array<Group>();

Expand Down Expand Up @@ -156,7 +156,7 @@ export class Policy extends Construct implements IDependable {
/**
* Attaches this policy to a role.
*/
public attachToRole(role: Role) {
public attachToRole(role: IRole) {
if (this.roles.find(r => r === role)) { return; }
this.roles.push(role);
role.attachInlinePolicy(this);
Expand Down
11 changes: 10 additions & 1 deletion packages/@aws-cdk/aws-iam/lib/role.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Construct, IConstruct, IDependable, Output } from '@aws-cdk/cdk';
import { Construct, IConstruct, IDependable, Output, Stack } from '@aws-cdk/cdk';
import { CfnRole } from './iam.generated';
import { IPrincipal, Policy } from './policy';
import { ArnPrincipal, PolicyDocument, PolicyPrincipal, PolicyStatement } from './policy-document';
Expand Down Expand Up @@ -223,6 +223,11 @@ export interface IRole extends IConstruct, IPrincipal, IDependable {
*/
readonly roleId: string;

/**
* Returns the name of this role.
*/
readonly roleName: string;

/**
* Export this role to another stack.
*/
Expand Down Expand Up @@ -295,6 +300,10 @@ class ImportedRole extends Construct implements IRole {
return this._roleId;
}

public get roleName() {
return Stack.find(this).parseArn(this.roleArn).resourceName!;
}

public export() {
return this.props;
}
Expand Down
59 changes: 59 additions & 0 deletions packages/@aws-cdk/aws-iam/test/test.lazy-role.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { expect, haveResource, haveResourceLike } from '@aws-cdk/assert';
import cdk = require('@aws-cdk/cdk');
import nodeunit = require('nodeunit');
import iam = require('../lib');

export = nodeunit.testCase({
'creates no resource when unused'(test: nodeunit.Test) {
// GIVEN
const stack = new cdk.Stack();

// WHEN
new iam.LazyRole(stack, 'Lazy', {
assumedBy: new iam.ServicePrincipal('test.amazonaws.com')
});

// THEN
expect(stack).notTo(haveResourceLike('AWS::IAM::Role'));
test.done();
},

'creates the resource when a property is read'(test: nodeunit.Test) {
// GIVEN
const stack = new cdk.Stack();

// WHEN
const roleArn = new iam.LazyRole(stack, 'Lazy', {
assumedBy: new iam.ServicePrincipal('test.amazonaws.com')
}).roleArn;

// THEN
test.notEqual(roleArn, null);
expect(stack).to(haveResource('AWS::IAM::Role', {
AssumeRolePolicyDocument: {
Version: '2012-10-17',
Statement: [{
Action: 'sts:AssumeRole',
Effect: 'Allow',
Principal: { Service: 'test.amazonaws.com' }
}]
}
}));
test.done();
},

'returns appropriate roleName'(test: nodeunit.Test) {
// GIVEN
const stack = new cdk.Stack();

// WHEN
const role = new iam.LazyRole(stack, 'Lazy', {
assumedBy: new iam.ServicePrincipal('test.amazonaws.com')
});

// THEN
test.deepEqual(stack.node.resolve(role.roleName),
{ Ref: 'Lazy399F7F48'});
test.done();
}
});
11 changes: 11 additions & 0 deletions packages/@aws-cdk/aws-iam/test/test.role.ts
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,17 @@ export = {

test.deepEqual(stack.node.resolve(importedRole.roleArn), { 'Fn::ImportValue': 'MyRoleRoleArn3388B7E2' });
test.deepEqual(stack.node.resolve(importedRole.roleId), { 'Fn::ImportValue': 'MyRoleRoleIdF7B258D8' });
test.deepEqual(stack.node.resolve(importedRole.roleName), {
'Fn::Select': [ 1, {
'Fn::Split': [ '/', {
'Fn::Select': [ 5, {
'Fn::Split': [ ':', {
'Fn::ImportValue': 'MyRoleRoleArn3388B7E2'
} ]
} ]
} ]
} ]
});
test.done();
}
};

0 comments on commit 9128390

Please sign in to comment.