-
Notifications
You must be signed in to change notification settings - Fork 825
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: carry existing container secret config over (#7224)
When a customer selected "don't update secrets" when deploying changes to a containers resource, the existing secrets config was removed rather than retained. This change adds logic to parse the existing secret config and apply it to the updated template
- Loading branch information
1 parent
afbaa08
commit b2f3bf7
Showing
3 changed files
with
113 additions
and
3 deletions.
There are no files selected for viewing
60 changes: 60 additions & 0 deletions
60
...ests__/provider-utils/awscloudformation/utils/containers/set-existing-secret-arns.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import { setExistingSecretArns } from '../../../../../provider-utils/awscloudformation/utils/containers/set-existing-secret-arns'; | ||
|
||
describe('set existing secret arns', () => { | ||
it('does nothing if no template found', () => { | ||
const secretMap = new Map<string, string>(); | ||
setExistingSecretArns(secretMap, {}); | ||
expect(secretMap.size).toBe(0); | ||
}); | ||
|
||
it('does nothing if template does not have secrets', () => { | ||
const mockTemplate = { | ||
Resources: { | ||
TaskDefinition: { | ||
Type: 'AWS::ECS::TaskDefinition', | ||
Properties: { | ||
ContainerDefinitions: [ | ||
{ | ||
Secrets: [], | ||
}, | ||
], | ||
}, | ||
}, | ||
}, | ||
}; | ||
const secretMap = new Map<string, string>(); | ||
setExistingSecretArns(secretMap, mockTemplate); | ||
expect(secretMap.size).toBe(0); | ||
}); | ||
|
||
it('adds all secrets to secret map', () => { | ||
const mockTemplate = { | ||
Resources: { | ||
TaskDefinition: { | ||
Type: 'AWS::ECS::TaskDefinition', | ||
Properties: { | ||
ContainerDefinitions: [ | ||
{ | ||
Secrets: [ | ||
{ | ||
Name: 'SOMETHING', | ||
ValueFrom: 'some:secretsmanager:arn', | ||
}, | ||
], | ||
}, | ||
], | ||
}, | ||
}, | ||
}, | ||
}; | ||
const secretMap = new Map<string, string>(); | ||
setExistingSecretArns(secretMap, mockTemplate); | ||
expect(secretMap.size).toBe(1); | ||
expect(secretMap.entries().next().value).toMatchInlineSnapshot(` | ||
Array [ | ||
"SOMETHING", | ||
"some:secretsmanager:arn", | ||
] | ||
`); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
42 changes: 42 additions & 0 deletions
42
...ory-api/src/provider-utils/awscloudformation/utils/containers/set-existing-secret-arns.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
import { $TSAny } from 'amplify-cli-core'; | ||
import _ from 'lodash'; | ||
/** | ||
* Check if the template contains existing secret configuration and if so, add it to the secretsMap | ||
* The secrets configuration is stored in the template in the following format | ||
* { | ||
* "Resources": { | ||
"TaskDefinition": { | ||
"Type": "AWS::ECS::TaskDefinition", | ||
"Properties": { | ||
"ContainerDefinitions": [ | ||
{ | ||
"Secrets": [ | ||
{ | ||
"Name": "SECRETNAME", | ||
"ValueFrom": "<some secrets manager arn>" | ||
} | ||
} | ||
} | ||
] | ||
} | ||
} | ||
} | ||
*/ | ||
export const setExistingSecretArns = (secretsMap: Map<string, string>, cfnObj: $TSAny) => { | ||
if (_.isEmpty(cfnObj)) { | ||
return; | ||
} | ||
const taskDef = Object.values(cfnObj?.Resources) // get all the resources | ||
.find((value: $TSAny) => value?.Type === 'AWS::ECS::TaskDefinition') as $TSAny; // find the task definition | ||
const containerDefs = taskDef?.Properties?.ContainerDefinitions as $TSAny[]; // pull out just the container definitions | ||
if (!Array.isArray(containerDefs)) { | ||
return; | ||
} | ||
containerDefs | ||
.map(def => def?.Secrets) // get the secrets array | ||
.filter(secrets => !_.isEmpty(secrets)) // filter out defs that don't contain secrets | ||
.flat(1) // merge nested secrets array into one array | ||
.filter(secretDef => !!secretDef?.Name) // make sure the name is defined | ||
.filter(secretDef => !!secretDef.ValueFrom) // make sure the arn is defined | ||
.forEach(secretDef => secretsMap.set(secretDef.Name, secretDef.ValueFrom)); // add it to the secretsMap map | ||
}; |