Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(deadline): validate minimum Deadline version for secrets management #573

Merged
merged 2 commits into from
Oct 21, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 2 additions & 9 deletions packages/aws-rfdk/lib/deadline/lib/render-queue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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).
*/
Expand Down Expand Up @@ -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');
Expand Down
13 changes: 10 additions & 3 deletions packages/aws-rfdk/lib/deadline/lib/repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -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 }),
},
Expand Down
5 changes: 5 additions & 0 deletions packages/aws-rfdk/lib/deadline/lib/version.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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]);
horsmand marked this conversation as resolved.
Show resolved Hide resolved

/**
* This method parses the input string and returns the version object.
*
Expand Down
3 changes: 2 additions & 1 deletion packages/aws-rfdk/lib/deadline/test/render-queue.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ import {
RenderQueueProps,
RenderQueueSecurityGroups,
Repository,
Version,
VersionQuery,
} from '../lib';
import {
Expand Down Expand Up @@ -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', () => {
Expand Down
40 changes: 38 additions & 2 deletions packages/aws-rfdk/lib/deadline/test/repository.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ beforeEach(() => {
}
}

version = new MockVersion([10,1,9,2]);
version = new MockVersion([10,1,19,0]);
horsmand marked this conversation as resolved.
Show resolved Hide resolved
});

test('can create two repositories', () => {
Expand Down Expand Up @@ -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([
Expand Down Expand Up @@ -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', {
Expand Down