Skip to content

Commit

Permalink
Revised hashing strategy for resource shares, updated tests, revised …
Browse files Browse the repository at this point in the history
…documentation
  • Loading branch information
Alex Makoviecki committed Jun 28, 2022
1 parent a986534 commit c785e58
Show file tree
Hide file tree
Showing 14 changed files with 312 additions and 80 deletions.
36 changes: 30 additions & 6 deletions packages/@aws-cdk/aws-servicecatalogappregistry/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,11 +134,23 @@ You can share your AppRegistry applications and attribute groups with AWS Organi
```ts
import * as iam from '@aws-cdk/aws-iam';
declare const application: appreg.Application;
declare const myRole: iam.IRole;
declare const myUser: iam.IUser;
application.shareResource({
accounts: ['123456789012'],
organizations: ['arn:aws:organizations::123456789012:organization/o-<org-ID>'],
roles: [iam.Role.fromRoleName(this, 'DeveloperRole', 'Developer')],
users: [iam.User.fromUserName(this, 'TesterUser', 'Tester')]
organizations: ['arn:aws:organizations::123456789012:organization/o-my-org-id'],
roles: [myRole],
users: [myUser]
});
```

E.g., sharing an application with multiple accounts:

```ts
import * as iam from '@aws-cdk/aws-iam';
declare const application: appreg.Application;
application.shareResource({
accounts: ['123456789012', '234567890123'],
});
```

Expand All @@ -147,10 +159,22 @@ application.shareResource({
```ts
import * as iam from '@aws-cdk/aws-iam';
declare const attributeGroup: appreg.AttributeGroup;
declare const myRole: iam.IRole;
declare const myUser: iam.IUser;
attributeGroup.shareResource({
accounts: ['123456789012'],
organizations: ['arn:aws:organizations::123456789012:organization/o-<org-ID>'],
roles: [iam.Role.fromRoleName(this, 'DeveloperRole', 'Developer')],
users: [iam.User.fromUserName(this, 'TesterUser', 'Tester')]
organizations: ['arn:aws:organizations::123456789012:organization/o-my-org-id'],
roles: [myRole],
users: [myUser]
});
```

E.g., sharing an attribute group with multiple accounts:

```ts
import * as iam from '@aws-cdk/aws-iam';
declare const attributeGroup: appreg.AttributeGroup;
attributeGroup.shareResource({
accounts: ['123456789012', '234567890123'],
});
```
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,11 @@ abstract class ApplicationBase extends cdk.Resource implements IApplication {
/**
* Share application resource with target accounts.
* The application will become available to end users within targets.
* @param shareOptions
* @param shareOptions The options for the share.
*/
public shareResource(shareOptions: ShareOptions): void {
const principals = getPrincipalsforSharing(shareOptions);
const shareName = `RAMShare${hashValues(this.node.addr, ...principals)}`;
const shareName = `RAMShare${this.generateUniqueHash(this.node.addr)}`;
new CfnResourceShare(this, shareName, {
name: shareName,
allowExternalPrincipals: shareOptions.allowExternalPrincipals ?? true,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,14 +59,19 @@ abstract class AttributeGroupBase extends cdk.Resource implements IAttributeGrou

public shareResource(shareOptions: ShareOptions): void {
const principals = getPrincipalsforSharing(shareOptions);
const shareName = `RAMShare${hashValues(this.node.addr, ...principals)}`;
const shareName = `RAMShare${this.generateUniqueHash(this.node.addr)}`;
new CfnResourceShare(this, shareName, {
name: shareName,
allowExternalPrincipals: shareOptions.allowExternalPrincipals ?? true,
principals: principals,
resourceArns: [this.attributeGroupArn],
});
}

/**
* Create a unique id
*/
protected abstract generateUniqueHash(resourceAddress: string): string;
}

/**
Expand All @@ -91,6 +96,10 @@ export class AttributeGroup extends AttributeGroupBase implements IAttributeGrou
class Import extends AttributeGroupBase {
public readonly attributeGroupArn = attributeGroupArn;
public readonly attributeGroupId = attributeGroupId!;

protected generateUniqueHash(resourceAddress: string): string {
return hashValues(this.attributeGroupArn, resourceAddress);
}
}

return new Import(scope, id, {
Expand All @@ -100,6 +109,7 @@ export class AttributeGroup extends AttributeGroupBase implements IAttributeGrou

public readonly attributeGroupArn: string;
public readonly attributeGroupId: string;
private readonly nodeAddress: string;

constructor(scope: Construct, id: string, props: AttributeGroupProps) {
super(scope, id);
Expand All @@ -114,11 +124,16 @@ export class AttributeGroup extends AttributeGroupBase implements IAttributeGrou

this.attributeGroupArn = attributeGroup.attrArn;
this.attributeGroupId = attributeGroup.attrId;
this.nodeAddress = cdk.Names.nodeUniqueId(attributeGroup.node);
}

private validateAttributeGroupProps(props: AttributeGroupProps) {
InputValidator.validateLength(this.node.path, 'attribute group name', 1, 256, props.attributeGroupName);
InputValidator.validateRegex(this.node.path, 'attribute group name', /^[a-zA-Z0-9-_]+$/, props.attributeGroupName);
InputValidator.validateLength(this.node.path, 'attribute group description', 0, 1024, props.description);
}

protected generateUniqueHash(resourceAddress: string): string {
return hashValues(this.nodeAddress, resourceAddress);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export interface ShareOptions {
}

/**
* Generates a unique hash identfifer using SHA256 encryption algorithm
* Generates a unique hash identfifer using SHA256 encryption algorithm.
*/
export function hashValues(...values: string[]): string {
const sha256 = crypto.createHash('sha256');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,29 @@
}
}
},
"TestApplicationRAMShareb83647b4f06a5A88B554": {
"Type": "AWS::RAM::ResourceShare",
"Properties": {
"Name": "RAMShareb83647b4f06a",
"AllowExternalPrincipals": true,
"Principals": [
{
"Fn::GetAtt": [
"MyRoleF48FFE04",
"Arn"
]
}
],
"ResourceArns": [
{
"Fn::GetAtt": [
"TestApplication2FBC585F",
"Arn"
]
}
]
}
},
"TestAttributeGroupB1CB284F": {
"Type": "AWS::ServiceCatalogAppRegistry::AttributeGroup",
"Properties": {
Expand All @@ -62,22 +85,36 @@
"Description": "my attribute group description"
}
},
"TestAttributeGroupRAMShare8ecfad67abc5A7122106": {
"Type": "AWS::RAM::ResourceShare",
"MyRoleF48FFE04": {
"Type": "AWS::IAM::Role",
"Properties": {
"Name": "RAMShare8ecfad67abc5",
"AllowExternalPrincipals": true,
"Principals": [
"arn:aws:iam::279317280375:role/Developer"
],
"ResourceArns": [
{
"Fn::GetAtt": [
"TestAttributeGroupB1CB284F",
"Arn"
]
}
]
"AssumeRolePolicyDocument": {
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"AWS": {
"Fn::Join": [
"",
[
"arn:",
{
"Ref": "AWS::Partition"
},
":iam::",
{
"Ref": "AWS::AccountId"
},
":root"
]
]
}
}
}
],
"Version": "2012-10-17"
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,16 +33,31 @@
"data": "TestApplicationAttributeGroupAssociation4ba7f5842818B8EE1C6F"
}
],
"/integ-servicecatalogappregistry-application/TestApplication/RAMShareb83647b4f06a": [
{
"type": "aws:cdk:logicalId",
"data": "TestApplicationRAMShareb83647b4f06a5A88B554"
}
],
"/integ-servicecatalogappregistry-application/TestAttributeGroup/Resource": [
{
"type": "aws:cdk:logicalId",
"data": "TestAttributeGroupB1CB284F"
}
],
"/integ-servicecatalogappregistry-application/TestAttributeGroup/RAMShare8ecfad67abc5": [
"/integ-servicecatalogappregistry-application/MyRole/Resource": [
{
"type": "aws:cdk:logicalId",
"data": "MyRoleF48FFE04"
}
],
"TestAttributeGroupRAMShare8ecfad67abc5A7122106": [
{
"type": "aws:cdk:logicalId",
"data": "TestAttributeGroupRAMShare8ecfad67abc5A7122106"
"data": "TestAttributeGroupRAMShare8ecfad67abc5A7122106",
"trace": [
"!!DESTRUCTIVE_CHANGES: WILL_DESTROY"
]
}
]
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,37 @@
"fqn": "@aws-cdk/aws-servicecatalogappregistry.CfnAttributeGroupAssociation",
"version": "0.0.0"
}
},
"RAMShareb83647b4f06a": {
"id": "RAMShareb83647b4f06a",
"path": "integ-servicecatalogappregistry-application/TestApplication/RAMShareb83647b4f06a",
"attributes": {
"aws:cdk:cloudformation:type": "AWS::RAM::ResourceShare",
"aws:cdk:cloudformation:props": {
"name": "RAMShareb83647b4f06a",
"allowExternalPrincipals": true,
"principals": [
{
"Fn::GetAtt": [
"MyRoleF48FFE04",
"Arn"
]
}
],
"resourceArns": [
{
"Fn::GetAtt": [
"TestApplication2FBC585F",
"Arn"
]
}
]
}
},
"constructInfo": {
"fqn": "@aws-cdk/aws-ram.CfnResourceShare",
"version": "0.0.0"
}
}
},
"constructInfo": {
Expand Down Expand Up @@ -123,32 +154,6 @@
"fqn": "@aws-cdk/aws-servicecatalogappregistry.CfnAttributeGroup",
"version": "0.0.0"
}
},
"RAMShare8ecfad67abc5": {
"id": "RAMShare8ecfad67abc5",
"path": "integ-servicecatalogappregistry-application/TestAttributeGroup/RAMShare8ecfad67abc5",
"attributes": {
"aws:cdk:cloudformation:type": "AWS::RAM::ResourceShare",
"aws:cdk:cloudformation:props": {
"name": "RAMShare8ecfad67abc5",
"allowExternalPrincipals": true,
"principals": [
"arn:aws:iam::279317280375:role/Developer"
],
"resourceArns": [
{
"Fn::GetAtt": [
"TestAttributeGroupB1CB284F",
"Arn"
]
}
]
}
},
"constructInfo": {
"fqn": "@aws-cdk/aws-ram.CfnResourceShare",
"version": "0.0.0"
}
}
},
"constructInfo": {
Expand All @@ -159,8 +164,50 @@
"MyRole": {
"id": "MyRole",
"path": "integ-servicecatalogappregistry-application/MyRole",
"children": {
"Resource": {
"id": "Resource",
"path": "integ-servicecatalogappregistry-application/MyRole/Resource",
"attributes": {
"aws:cdk:cloudformation:type": "AWS::IAM::Role",
"aws:cdk:cloudformation:props": {
"assumeRolePolicyDocument": {
"Statement": [
{
"Action": "sts:AssumeRole",
"Effect": "Allow",
"Principal": {
"AWS": {
"Fn::Join": [
"",
[
"arn:",
{
"Ref": "AWS::Partition"
},
":iam::",
{
"Ref": "AWS::AccountId"
},
":root"
]
]
}
}
}
],
"Version": "2012-10-17"
}
}
},
"constructInfo": {
"fqn": "@aws-cdk/aws-iam.CfnRole",
"version": "0.0.0"
}
}
},
"constructInfo": {
"fqn": "@aws-cdk/core.Resource",
"fqn": "@aws-cdk/aws-iam.Role",
"version": "0.0.0"
}
}
Expand Down
Loading

0 comments on commit c785e58

Please sign in to comment.