From 2eb941fccd24b76ac321d04b1cbbe0302f96dcfa Mon Sep 17 00:00:00 2001 From: Eugene Kozlov Date: Fri, 17 Sep 2021 17:21:40 +0000 Subject: [PATCH] feat(secret): Add min version validation in repository --- .../aws-rfdk/lib/deadline/lib/render-queue.ts | 11 +---- .../aws-rfdk/lib/deadline/lib/repository.ts | 13 ++++-- packages/aws-rfdk/lib/deadline/lib/version.ts | 5 +++ .../lib/deadline/test/render-queue.test.ts | 3 +- .../lib/deadline/test/repository.test.ts | 40 ++++++++++++++++++- 5 files changed, 57 insertions(+), 15 deletions(-) diff --git a/packages/aws-rfdk/lib/deadline/lib/render-queue.ts b/packages/aws-rfdk/lib/deadline/lib/render-queue.ts index 5922d457e..16d7c6270 100644 --- a/packages/aws-rfdk/lib/deadline/lib/render-queue.ts +++ b/packages/aws-rfdk/lib/deadline/lib/render-queue.ts @@ -215,13 +215,6 @@ export class RenderQueue extends RenderQueueBase implements IGrantable { */ private static readonly MINIMUM_LOAD_BALANCING_VERSION = new Version([10, 1, 10, 0]); - // TODO: Update this with the version of Deadline that includes the changes for RFDK Secrets Management. - // This is a temporary minimum version until this feature branch is merged - /** - * The minimum Deadline version required to enable Deadline Secrets Management on the Render Queue. - */ - private static readonly MINIMUM_SECRETS_MANAGEMENT_VERSION = new Version([10, 1, 15, 0]); - /** * Regular expression that validates a hostname (portion in front of the subdomain). */ @@ -423,8 +416,8 @@ export class RenderQueue extends RenderQueueBase implements IGrantable { if (props.repository.secretsManagementSettings.enabled) { const errors = []; - if (props.version.isLessThan(RenderQueue.MINIMUM_SECRETS_MANAGEMENT_VERSION)) { - errors.push(`The supplied Deadline version (${props.version.versionString}) is lower than the minimum required version: ${RenderQueue.MINIMUM_SECRETS_MANAGEMENT_VERSION.toString()}`); + if (props.version.isLessThan(Version.MINIMUM_SECRETS_MANAGEMENT_VERSION)) { + errors.push(`The supplied Deadline version (${props.version.versionString}) does not support Deadline Secrets Management in RFDK. Either upgrade Deadline to the minimum required version (${Version.MINIMUM_SECRETS_MANAGEMENT_VERSION.versionString}) or disable the feature in the Repository's construct properties.`); } if (props.repository.secretsManagementSettings.credentials === undefined) { errors.push('The Repository does not have Secrets Management credentials'); diff --git a/packages/aws-rfdk/lib/deadline/lib/repository.ts b/packages/aws-rfdk/lib/deadline/lib/repository.ts index ffcf2debc..14a88a974 100644 --- a/packages/aws-rfdk/lib/deadline/lib/repository.ts +++ b/packages/aws-rfdk/lib/deadline/lib/repository.ts @@ -77,6 +77,7 @@ import { import { DatabaseConnection } from './database-connection'; import { IHost } from './host-ref'; +import { Version } from './version'; import { VersionQuery } from './version-query'; import { IVersion } from './version-ref'; @@ -584,17 +585,23 @@ export class Repository extends Construct implements IRepository { this.version = props.version; + const meetsMinSecretsVersion = !this.version.isLessThan(Version.MINIMUM_SECRETS_MANAGEMENT_VERSION); + const secretsManagementIsEnabled = props.secretsManagementSettings?.enabled ?? meetsMinSecretsVersion; + + if (secretsManagementIsEnabled && !meetsMinSecretsVersion) { + throw new Error(`The supplied Deadline version (${props.version.versionString}) does not support Deadline Secrets Management in RFDK. Either upgrade Deadline to the minimum required version (${Version.MINIMUM_SECRETS_MANAGEMENT_VERSION.versionString}) or disable the feature in the Repository's construct properties.`); + } + this.secretsManagementSettings = { - enabled: props.secretsManagementSettings?.enabled ?? true, + enabled: secretsManagementIsEnabled, credentials: props.secretsManagementSettings?.credentials ?? - ((props.secretsManagementSettings?.enabled ?? true) ? new Secret(this, 'SMAdminUser', { + (secretsManagementIsEnabled ? new Secret(this, 'SMAdminUser', { description: 'Admin credentials for Deadline Secrets Management', generateSecretString: { excludeCharacters: '\"$&\'()/<>[\\]\`{|}', includeSpace: false, passwordLength: 24, requireEachIncludedType: true, - generateStringKey: 'password', secretStringTemplate: JSON.stringify({ username: Repository.DEFAULT_SECRETS_MANAGEMENT_USERNAME }), }, diff --git a/packages/aws-rfdk/lib/deadline/lib/version.ts b/packages/aws-rfdk/lib/deadline/lib/version.ts index 24e7e8389..10472d642 100644 --- a/packages/aws-rfdk/lib/deadline/lib/version.ts +++ b/packages/aws-rfdk/lib/deadline/lib/version.ts @@ -17,6 +17,11 @@ export class Version implements IPatchVersion { */ public static readonly MINIMUM_SUPPORTED_DEADLINE_VERSION = new Version([10, 1, 9, 2]); + /** + * The minimum Deadline version required to enable Deadline Secrets Management. + */ + public static readonly MINIMUM_SECRETS_MANAGEMENT_VERSION = new Version([10, 1, 19, 0]); + /** * This method parses the input string and returns the version object. * diff --git a/packages/aws-rfdk/lib/deadline/test/render-queue.test.ts b/packages/aws-rfdk/lib/deadline/test/render-queue.test.ts index 893637e2c..ea1af55df 100644 --- a/packages/aws-rfdk/lib/deadline/test/render-queue.test.ts +++ b/packages/aws-rfdk/lib/deadline/test/render-queue.test.ts @@ -76,6 +76,7 @@ import { RenderQueueProps, RenderQueueSecurityGroups, Repository, + Version, VersionQuery, } from '../lib'; import { @@ -2832,7 +2833,7 @@ describe('RenderQueue', () => { // THEN /* eslint-disable-next-line dot-notation */ - .toThrowError(`The supplied Deadline version (${oldVersion.versionString}) is lower than the minimum required version: ${RenderQueue['MINIMUM_SECRETS_MANAGEMENT_VERSION'].toString()}`); + .toThrowError(`The supplied Deadline version (${oldVersion.versionString}) does not support Deadline Secrets Management in RFDK. Either upgrade Deadline to the minimum required version (${Version.MINIMUM_SECRETS_MANAGEMENT_VERSION.versionString}) or disable the feature in the Repository's construct properties.`); }); test('grants read permissions to secrets management credentials', () => { diff --git a/packages/aws-rfdk/lib/deadline/test/repository.test.ts b/packages/aws-rfdk/lib/deadline/test/repository.test.ts index 5023b5f58..64d4dac7e 100644 --- a/packages/aws-rfdk/lib/deadline/test/repository.test.ts +++ b/packages/aws-rfdk/lib/deadline/test/repository.test.ts @@ -112,7 +112,7 @@ beforeEach(() => { } } - version = new MockVersion([10,1,9,2]); + version = new MockVersion([10,1,19,0]); }); test('can create two repositories', () => { @@ -858,7 +858,7 @@ test('repository instance is created with correct installer path version', () => // THEN const script = (repo.node.defaultChild as AutoScalingGroup).userData; - expect(script.render()).toMatch(/10\.1\.9\.2/); + expect(script.render()).toEqual(expect.stringContaining(version.versionString)); }); test.each([ @@ -1208,6 +1208,42 @@ test('throws an error if supplied a MountableEfs with no Access Point', () => { expect(when).toThrow('When using EFS with the Repository, you must provide an EFS Access Point'); }); +test('disable Secrets Management by default when Deadline version is old', () => { + // GIVEN + const newStack = new Stack(app, 'NewStack'); + const oldVersion = new VersionQuery(newStack, 'OldDeadlineVersion', { version: '10.0.0.0' }); + + // WHEN + const repository = new Repository(newStack, 'Repo', { + vpc, + version: oldVersion, + }); + + // THEN + expect(repository.secretsManagementSettings.enabled).toBeFalsy(); + expect(repository.secretsManagementSettings.credentials).toBeUndefined(); +}); + +test('throws when Secrets Management is enabled but deadline version is too low', () => { + // GIVEN + const newStack = new Stack(app, 'NewStack'); + const oldVersion = new VersionQuery(newStack, 'OldDeadlineVersion', { version: '10.0.0.0' }); + + // WHEN + function when() { + new Repository(newStack, 'Repo', { + version: oldVersion, + vpc, + secretsManagementSettings: { + enabled: true, + }, + }); + } + + // THEN + expect(when).toThrow(`The supplied Deadline version (${oldVersion.versionString}) does not support Deadline Secrets Management in RFDK. Either upgrade Deadline to the minimum required version (${Version.MINIMUM_SECRETS_MANAGEMENT_VERSION.versionString}) or disable the feature in the Repository's construct properties.`); +}); + test('imports repository settings', () => { // GIVEN const repositorySettings = new Asset(stack, 'RepositorySettingsAsset', {