-
Notifications
You must be signed in to change notification settings - Fork 4k
/
Copy pathimported-role.ts
94 lines (82 loc) · 3.71 KB
/
imported-role.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
import { Construct } from 'constructs';
import { FeatureFlags, Names, Resource, Token, TokenComparison, Annotations } from '../../../core';
import { IAM_IMPORTED_ROLE_STACK_SAFE_DEFAULT_POLICY_NAME } from '../../../cx-api';
import { Grant } from '../grant';
import { IManagedPolicy } from '../managed-policy';
import { Policy } from '../policy';
import { PolicyStatement } from '../policy-statement';
import { IComparablePrincipal, IPrincipal, ArnPrincipal, AddToPrincipalPolicyResult, PrincipalPolicyFragment } from '../principals';
import { IRole, FromRoleArnOptions } from '../role';
import { AttachedPolicies } from '../util';
export interface ImportedRoleProps extends FromRoleArnOptions {
readonly roleArn: string;
readonly roleName: string;
readonly account?: string;
}
export class ImportedRole extends Resource implements IRole, IComparablePrincipal {
public readonly grantPrincipal: IPrincipal = this;
public readonly principalAccount?: string;
public readonly assumeRoleAction: string = 'sts:AssumeRole';
public readonly policyFragment: PrincipalPolicyFragment;
public readonly roleArn: string;
public readonly roleName: string;
private readonly attachedPolicies = new AttachedPolicies();
private readonly defaultPolicyName?: string;
private defaultPolicy?: Policy;
constructor(scope: Construct, id: string, props: ImportedRoleProps) {
super(scope, id, {
account: props.account,
});
this.roleArn = props.roleArn;
this.roleName = props.roleName;
this.policyFragment = new ArnPrincipal(this.roleArn).policyFragment;
this.defaultPolicyName = props.defaultPolicyName;
this.principalAccount = props.account;
}
public addToPolicy(statement: PolicyStatement): boolean {
return this.addToPrincipalPolicy(statement).statementAdded;
}
public addToPrincipalPolicy(statement: PolicyStatement): AddToPrincipalPolicyResult {
if (!this.defaultPolicy) {
const useUniqueName = FeatureFlags.of(this).isEnabled(IAM_IMPORTED_ROLE_STACK_SAFE_DEFAULT_POLICY_NAME);
const defaultDefaultPolicyName = useUniqueName
? `Policy${Names.uniqueId(this)}`
: 'Policy';
const policyName = this.defaultPolicyName ?? defaultDefaultPolicyName;
this.defaultPolicy = new Policy(this, policyName, useUniqueName ? { policyName } : undefined);
this.attachInlinePolicy(this.defaultPolicy);
}
this.defaultPolicy.addStatements(statement);
return { statementAdded: true, policyDependable: this.defaultPolicy };
}
public attachInlinePolicy(policy: Policy): void {
const thisAndPolicyAccountComparison = Token.compareStrings(this.env.account, policy.env.account);
const equalOrAnyUnresolved = thisAndPolicyAccountComparison === TokenComparison.SAME ||
thisAndPolicyAccountComparison === TokenComparison.BOTH_UNRESOLVED ||
thisAndPolicyAccountComparison === TokenComparison.ONE_UNRESOLVED;
if (equalOrAnyUnresolved) {
this.attachedPolicies.attach(policy);
policy.attachToRole(this);
}
}
public addManagedPolicy(policy: IManagedPolicy): void {
Annotations.of(this).addWarningV2('@aws-cdk/aws-iam:importedRoleManagedPolicyNotAdded', `Not adding managed policy: ${policy.managedPolicyArn} to imported role: ${this.roleName}`);
}
public grantPassRole(identity: IPrincipal): Grant {
return this.grant(identity, 'iam:PassRole');
}
public grantAssumeRole(identity: IPrincipal): Grant {
return this.grant(identity, 'sts:AssumeRole');
}
public grant(grantee: IPrincipal, ...actions: string[]): Grant {
return Grant.addToPrincipal({
grantee,
actions,
resourceArns: [this.roleArn],
scope: this,
});
}
public dedupeString(): string | undefined {
return `ImportedRole:${this.roleArn}`;
}
}