From cd96313857b09a008b1b7b5031a3d9c67c661149 Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Corvo Date: Thu, 20 Jan 2022 08:32:13 -0800 Subject: [PATCH 01/15] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20Add=20fields=20to?= =?UTF-8?q?=20host-catalog=20model?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add new fields to host-catalog model for plugin type host-catalog. Fields are corresponding to Azure and Aws plugins. --- .../addon/generated/models/host-catalog.js | 60 ++++++++++ addons/api/addon/serializers/host-catalog.js | 41 +++++++ addons/api/app/serializers/host-catalog.js | 1 + .../unit/serializers/host-catalog-test.js | 108 ++++++++++++++++++ 4 files changed, 210 insertions(+) create mode 100644 addons/api/addon/serializers/host-catalog.js create mode 100644 addons/api/app/serializers/host-catalog.js create mode 100644 addons/api/tests/unit/serializers/host-catalog-test.js diff --git a/addons/api/addon/generated/models/host-catalog.js b/addons/api/addon/generated/models/host-catalog.js index f1f78db34..ac1b023b6 100644 --- a/addons/api/addon/generated/models/host-catalog.js +++ b/addons/api/addon/generated/models/host-catalog.js @@ -54,4 +54,64 @@ export default class GeneratedHostCatalogModel extends BaseModel { readOnly: true, }) plugin; + + @attr('boolean', { + isNestedAttribute: true, + description: '', + }) + disable_credential_rotation; + + // Azure specific + @attr('string', { + isNestedAttribute: true, + description: '', + }) + region; + + @attr('string', { + isNestedAttribute: true, + readOnly: true, + description: '', + }) + access_key_id; + + @attr('string', { + isNestedAttribute: true, + readOnly: true, + description: '', + }) + secret_access_key; + + // AWS specific + @attr('string', { + isNestedAttribute: true, + description: '', + }) + tenant_id; + + @attr('string', { + isNestedAttribute: true, + description: '', + }) + client_id; + + @attr('string', { + isNestedAttribute: true, + description: '', + }) + subscription_id; + + @attr('string', { + isNestedAttribute: true, + readOnly: true, + description: '', + }) + secret_id; + + @attr('string', { + isNestedAttribute: true, + readOnly: true, + description: '', + }) + secret_value; } diff --git a/addons/api/addon/serializers/host-catalog.js b/addons/api/addon/serializers/host-catalog.js new file mode 100644 index 000000000..9681b6155 --- /dev/null +++ b/addons/api/addon/serializers/host-catalog.js @@ -0,0 +1,41 @@ +import ApplicationSerializer from './application'; + +export default class HostCatalogSerializer extends ApplicationSerializer { + // =methods + serialize(snapshot) { + const serialized = super.serialize(...arguments); + switch (snapshot.record.type) { + case 'static': + return this.serializeStatic(...arguments); + case 'plugin': + return this.serializeDynamic(...arguments); + default: + return serialized; + } + } + + serializeStatic() { + const serialized = super.serialize(...arguments); + // Delete unnecessary fields for static host-catalog + delete serialized.attributes; + return serialized; + } + + serializeDynamic(snapshot) { + const { isAWS, isAzure } = snapshot.record; + const serialized = super.serialize(...arguments); + + // Is a Aws plugin, delete all the Azure attributes + if (isAWS) { + delete serialized.attributes.region; + } + + // Is an Azure plugin, delete all the Aws attributes + if (isAzure) { + delete serialized.attributes.tenant_id; + delete serialized.attributes.client_id; + delete serialized.attributes.subscription_id; + } + return serialized; + } +} diff --git a/addons/api/app/serializers/host-catalog.js b/addons/api/app/serializers/host-catalog.js new file mode 100644 index 000000000..e2818e2c7 --- /dev/null +++ b/addons/api/app/serializers/host-catalog.js @@ -0,0 +1 @@ +export { default } from 'api/serializers/host-catalog'; diff --git a/addons/api/tests/unit/serializers/host-catalog-test.js b/addons/api/tests/unit/serializers/host-catalog-test.js new file mode 100644 index 000000000..d889a52b9 --- /dev/null +++ b/addons/api/tests/unit/serializers/host-catalog-test.js @@ -0,0 +1,108 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Serializer | host catalog', function (hooks) { + setupTest(hooks); + + // Replace this with your real tests. + test('it exists', function (assert) { + let store = this.owner.lookup('service:store'); + let serializer = store.serializerFor('host-catalog'); + + assert.ok(serializer); + }); + + test('it serializes records', function (assert) { + let store = this.owner.lookup('service:store'); + let record = store.createRecord('host-catalog', {}); + + let serializedRecord = record.serialize(); + + assert.ok(serializedRecord); + }); + + test('it serializes a static host-catalog as expected', async function (assert) { + assert.expect(1); + const store = this.owner.lookup('service:store'); + const serializer = store.serializerFor('host-catalog'); + const record = store.createRecord('host-catalog', { + name: 'static', + description: 'this is a static host-catalog', + type: 'static', + attributes: { + disable_credential_rotation: true, + tenant_id: 'a1b2c3', + }, + }); + const snapshot = record._createSnapshot(); + const serializedRecord = serializer.serialize(snapshot); + const expectedResult = { + name: 'static', + description: 'this is a static host-catalog', + type: 'static', + }; + assert.deepEqual(serializedRecord, expectedResult); + }); + + test('it serializes an AWS plugin as expected, ignoring read-only and azure fields', async function (assert) { + assert.expect(1); + const store = this.owner.lookup('service:store'); + const serializer = store.serializerFor('host-catalog'); + const record = store.createRecord('host-catalog', { + name: 'Aws', + description: 'this is a Aws plugin host-catalog', + type: 'plugin', + plugin: { name: 'aws' }, // Read-only field + disable_credential_rotation: true, + tenant_id: 'a1b2c3', + fake_field: 'testing fake field', + client_id: 'a1b2c3', + subscription_id: 'a1b2c3', + region: 'spain', + secret_id: 'a1b2c3', // Read-only field + access_key_id: '1a2b3c', // Azure specific field + }); + const snapshot = record._createSnapshot(); + const serializedRecord = serializer.serialize(snapshot); + const expectedResult = { + name: 'Aws', + description: 'this is a Aws plugin host-catalog', + type: 'plugin', + attributes: { + disable_credential_rotation: true, + tenant_id: 'a1b2c3', + client_id: 'a1b2c3', + subscription_id: 'a1b2c3', + }, + }; + assert.deepEqual(serializedRecord, expectedResult); + }); + + test('it serializes an Azure plugin as expected, ignoring read-only and Aws fields', async function (assert) { + assert.expect(1); + const store = this.owner.lookup('service:store'); + const serializer = store.serializerFor('host-catalog'); + const record = store.createRecord('host-catalog', { + name: 'Azure', + description: 'this is a Azure plugin host-catalog', + type: 'plugin', + plugin: { name: 'azure' }, // Read-only field + disable_credential_rotation: true, + region: 'spain', + access_key_id: 'a1b2c3', // Read-only field + fake_field: 'testing fake field', + }); + const snapshot = record._createSnapshot(); + const serializedRecord = serializer.serialize(snapshot); + const expectedResult = { + name: 'Azure', + description: 'this is a Azure plugin host-catalog', + type: 'plugin', + attributes: { + disable_credential_rotation: true, + region: 'spain', + }, + }; + assert.deepEqual(serializedRecord, expectedResult); + }); +}); From 9558f2e48089ce4f569693806919e962338a9759 Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Corvo Date: Thu, 20 Jan 2022 12:55:31 -0800 Subject: [PATCH 02/15] Modify serializer test to not test field exclusion. Add to mirage more host-catalogs. Add to mirage new fields per host-catalog --- .../generated/factories/host-catalog.js | 61 ++++++++++++++++++- addons/api/mirage/scenarios/default.js | 2 +- .../unit/serializers/host-catalog-test.js | 7 --- 3 files changed, 61 insertions(+), 9 deletions(-) diff --git a/addons/api/mirage/generated/factories/host-catalog.js b/addons/api/mirage/generated/factories/host-catalog.js index fa8135226..14dcbb306 100644 --- a/addons/api/mirage/generated/factories/host-catalog.js +++ b/addons/api/mirage/generated/factories/host-catalog.js @@ -1,6 +1,22 @@ import { Factory } from 'ember-cli-mirage'; -import { random, date, datatype } from 'faker'; +import { random, date, datatype, address } from 'faker'; +/** + * + * @param {object} plugin + * @returns + */ +function isAzurePlugin(plugin) { + if (plugin && plugin.name === 'azure') { + return true; + } +} + +function isAwsPlugin(plugin) { + if (plugin && plugin.name === 'aws') { + return true; + } +} /** * GeneratedHostCatalogModelFactory */ @@ -20,4 +36,47 @@ export default Factory.extend({ }; } }, + disable_credential_rotation: () => datatype.boolean(), + // Azure specific fields + region: function () { + if (isAzurePlugin(this.plugin)) { + return address.state(); + } + }, + access_key_id: function () { + if (isAzurePlugin(this.plugin)) { + return datatype.hexaDecimal(8); + } + }, + secret_access_key: function () { + if (isAzurePlugin(this.plugin)) { + return datatype.string(12); + } + }, + // AWS specific fields + tenant_id: function () { + if (isAwsPlugin(this.plugin)) { + return datatype.hexaDecimal(6); + } + }, + client_id: function () { + if (isAwsPlugin(this.plugin)) { + return datatype.hexaDecimal(6); + } + }, + subscription_id: function () { + if (isAwsPlugin(this.plugin)) { + return datatype.hexaDecimal(8); + } + }, + secret_id: function () { + if (isAwsPlugin(this.plugin)) { + return datatype.hexaDecimal(6); + } + }, + secret_value: function () { + if (isAwsPlugin(this.plugin)) { + return datatype.string(12); + } + }, }); diff --git a/addons/api/mirage/scenarios/default.js b/addons/api/mirage/scenarios/default.js index 9291f8a3e..51175f672 100644 --- a/addons/api/mirage/scenarios/default.js +++ b/addons/api/mirage/scenarios/default.js @@ -46,7 +46,7 @@ export default function (server) { // Other resources server.schema.scopes.where({ type: 'project' }).models.forEach((scope) => { - server.createList('host-catalog', 2, { scope }, 'withChildren'); + server.createList('host-catalog', 4, { scope }, 'withChildren'); server.createList('credential-store', 3, { scope }, 'withAssociations'); server.createList('target', 2, { scope }, 'withAssociations'); // Sessions have target data. Create it after targets. diff --git a/addons/api/tests/unit/serializers/host-catalog-test.js b/addons/api/tests/unit/serializers/host-catalog-test.js index d889a52b9..135c6db2e 100644 --- a/addons/api/tests/unit/serializers/host-catalog-test.js +++ b/addons/api/tests/unit/serializers/host-catalog-test.js @@ -29,10 +29,6 @@ module('Unit | Serializer | host catalog', function (hooks) { name: 'static', description: 'this is a static host-catalog', type: 'static', - attributes: { - disable_credential_rotation: true, - tenant_id: 'a1b2c3', - }, }); const snapshot = record._createSnapshot(); const serializedRecord = serializer.serialize(snapshot); @@ -55,12 +51,10 @@ module('Unit | Serializer | host catalog', function (hooks) { plugin: { name: 'aws' }, // Read-only field disable_credential_rotation: true, tenant_id: 'a1b2c3', - fake_field: 'testing fake field', client_id: 'a1b2c3', subscription_id: 'a1b2c3', region: 'spain', secret_id: 'a1b2c3', // Read-only field - access_key_id: '1a2b3c', // Azure specific field }); const snapshot = record._createSnapshot(); const serializedRecord = serializer.serialize(snapshot); @@ -90,7 +84,6 @@ module('Unit | Serializer | host catalog', function (hooks) { disable_credential_rotation: true, region: 'spain', access_key_id: 'a1b2c3', // Read-only field - fake_field: 'testing fake field', }); const snapshot = record._createSnapshot(); const serializedRecord = serializer.serialize(snapshot); From 1889dd00909a26e465cec6c6d8ba74cf0f3c0005 Mon Sep 17 00:00:00 2001 From: Randall Morey Date: Thu, 20 Jan 2022 16:47:46 -0500 Subject: [PATCH 03/15] chore: tweak dynamic fields serialization --- .../addon/generated/models/host-catalog.js | 8 ++- addons/api/addon/serializers/host-catalog.js | 53 +++++++++++-------- .../unit/serializers/host-catalog-test.js | 43 ++++++++++----- 3 files changed, 67 insertions(+), 37 deletions(-) diff --git a/addons/api/addon/generated/models/host-catalog.js b/addons/api/addon/generated/models/host-catalog.js index ac1b023b6..eb8b84342 100644 --- a/addons/api/addon/generated/models/host-catalog.js +++ b/addons/api/addon/generated/models/host-catalog.js @@ -55,13 +55,16 @@ export default class GeneratedHostCatalogModel extends BaseModel { }) plugin; + // AWS & Azure + @attr('boolean', { isNestedAttribute: true, description: '', }) disable_credential_rotation; - // Azure specific + // AWS specific + @attr('string', { isNestedAttribute: true, description: '', @@ -82,7 +85,8 @@ export default class GeneratedHostCatalogModel extends BaseModel { }) secret_access_key; - // AWS specific + // Azure specific + @attr('string', { isNestedAttribute: true, description: '', diff --git a/addons/api/addon/serializers/host-catalog.js b/addons/api/addon/serializers/host-catalog.js index 9681b6155..0bb99d19b 100644 --- a/addons/api/addon/serializers/host-catalog.js +++ b/addons/api/addon/serializers/host-catalog.js @@ -1,41 +1,52 @@ import ApplicationSerializer from './application'; +const fieldsByType = { + aws: [ + 'disable_credential_rotation', + 'region', + 'access_key_id', + 'secret_access_key', + ], + azure: [ + 'disable_credential_rotation', + 'tenant_id', + 'client_id', + 'subscription_id', + 'secret_id', + 'secret_value', + ], +}; + export default class HostCatalogSerializer extends ApplicationSerializer { // =methods serialize(snapshot) { const serialized = super.serialize(...arguments); - switch (snapshot.record.type) { + switch (snapshot.record.compositeType) { case 'static': return this.serializeStatic(...arguments); - case 'plugin': - return this.serializeDynamic(...arguments); default: return serialized; } } + serializeAttribute(snapshot, json, key, attribute) { + const value = super.serializeAttribute(...arguments); + const { isPlugin, compositeType } = snapshot.record; + const { options } = attribute; + // Nested conditionals for readability + // This deletes any fields that don't belong to the record type + if (isPlugin && options.isNestedAttribute && json.attributes) { + // The key must be included in the fieldsByType list above + if (!fieldsByType[compositeType].includes(key)) + delete json.attributes[key]; + } + return value; + } + serializeStatic() { const serialized = super.serialize(...arguments); // Delete unnecessary fields for static host-catalog delete serialized.attributes; return serialized; } - - serializeDynamic(snapshot) { - const { isAWS, isAzure } = snapshot.record; - const serialized = super.serialize(...arguments); - - // Is a Aws plugin, delete all the Azure attributes - if (isAWS) { - delete serialized.attributes.region; - } - - // Is an Azure plugin, delete all the Aws attributes - if (isAzure) { - delete serialized.attributes.tenant_id; - delete serialized.attributes.client_id; - delete serialized.attributes.subscription_id; - } - return serialized; - } } diff --git a/addons/api/tests/unit/serializers/host-catalog-test.js b/addons/api/tests/unit/serializers/host-catalog-test.js index 135c6db2e..5cf3480fc 100644 --- a/addons/api/tests/unit/serializers/host-catalog-test.js +++ b/addons/api/tests/unit/serializers/host-catalog-test.js @@ -40,33 +40,37 @@ module('Unit | Serializer | host catalog', function (hooks) { assert.deepEqual(serializedRecord, expectedResult); }); - test('it serializes an AWS plugin as expected, ignoring read-only and azure fields', async function (assert) { + test('it serializes an AWS plugin as expected, ignoring read-only and Azure fields', async function (assert) { assert.expect(1); const store = this.owner.lookup('service:store'); const serializer = store.serializerFor('host-catalog'); const record = store.createRecord('host-catalog', { - name: 'Aws', + compositeType: 'aws', + name: 'AWS', description: 'this is a Aws plugin host-catalog', - type: 'plugin', - plugin: { name: 'aws' }, // Read-only field disable_credential_rotation: true, + // these are AWS fields and should be included + region: 'spain', + access_key_id: 'foobars', + secret_access_key: 'testing', + // these are Azure fields and should be excluded tenant_id: 'a1b2c3', client_id: 'a1b2c3', subscription_id: 'a1b2c3', - region: 'spain', - secret_id: 'a1b2c3', // Read-only field + secret_id: 'a1b2c3', + secret_value: 'a1b2c3', }); const snapshot = record._createSnapshot(); const serializedRecord = serializer.serialize(snapshot); const expectedResult = { - name: 'Aws', + name: 'AWS', description: 'this is a Aws plugin host-catalog', type: 'plugin', attributes: { disable_credential_rotation: true, - tenant_id: 'a1b2c3', - client_id: 'a1b2c3', - subscription_id: 'a1b2c3', + region: 'spain', + access_key_id: 'foobars', + secret_access_key: 'testing', }, }; assert.deepEqual(serializedRecord, expectedResult); @@ -77,13 +81,20 @@ module('Unit | Serializer | host catalog', function (hooks) { const store = this.owner.lookup('service:store'); const serializer = store.serializerFor('host-catalog'); const record = store.createRecord('host-catalog', { + compositeType: 'azure', name: 'Azure', description: 'this is a Azure plugin host-catalog', - type: 'plugin', - plugin: { name: 'azure' }, // Read-only field disable_credential_rotation: true, + // these are AWS fields and should be included region: 'spain', - access_key_id: 'a1b2c3', // Read-only field + access_key_id: 'foobars', + secret_access_key: 'testing', + // these are Azure fields and should be excluded + tenant_id: 'a1b2c3', + client_id: 'a1b2c3', + subscription_id: 'a1b2c3', + secret_id: 'a1b2c3', + secret_value: 'a1b2c3', }); const snapshot = record._createSnapshot(); const serializedRecord = serializer.serialize(snapshot); @@ -93,7 +104,11 @@ module('Unit | Serializer | host catalog', function (hooks) { type: 'plugin', attributes: { disable_credential_rotation: true, - region: 'spain', + tenant_id: 'a1b2c3', + client_id: 'a1b2c3', + subscription_id: 'a1b2c3', + secret_id: 'a1b2c3', + secret_value: 'a1b2c3', }, }; assert.deepEqual(serializedRecord, expectedResult); From cd60c0bbc3fc5a6129205cac2b4be6bce292acfb Mon Sep 17 00:00:00 2001 From: Randall Morey Date: Thu, 20 Jan 2022 17:20:24 -0500 Subject: [PATCH 04/15] chore: add writeOnce field support --- addons/api/addon/generated/models/host-catalog.js | 8 ++++---- addons/api/addon/serializers/application.js | 2 ++ addons/api/tests/unit/serializers/host-catalog-test.js | 4 ++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/addons/api/addon/generated/models/host-catalog.js b/addons/api/addon/generated/models/host-catalog.js index eb8b84342..6c5770790 100644 --- a/addons/api/addon/generated/models/host-catalog.js +++ b/addons/api/addon/generated/models/host-catalog.js @@ -73,14 +73,14 @@ export default class GeneratedHostCatalogModel extends BaseModel { @attr('string', { isNestedAttribute: true, - readOnly: true, + writeOnce: true, description: '', }) access_key_id; @attr('string', { isNestedAttribute: true, - readOnly: true, + writeOnce: true, description: '', }) secret_access_key; @@ -107,14 +107,14 @@ export default class GeneratedHostCatalogModel extends BaseModel { @attr('string', { isNestedAttribute: true, - readOnly: true, + writeOnce: true, description: '', }) secret_id; @attr('string', { isNestedAttribute: true, - readOnly: true, + writeOnce: true, description: '', }) secret_value; diff --git a/addons/api/addon/serializers/application.js b/addons/api/addon/serializers/application.js index cb61f1a34..26d215219 100644 --- a/addons/api/addon/serializers/application.js +++ b/addons/api/addon/serializers/application.js @@ -43,6 +43,8 @@ export default class ApplicationSerializer extends RESTSerializer { if (type === 'string' && json[key] === '') json[key] = null; // Do not serialize read-only attributes. if (options.readOnly) delete json[key]; + // Only serialize write-once fields on create. + if (options.writeOnce && !snapshot.record.isNew) delete json[key]; // Version is sent only if it has a non-nullish value if (key === 'version') { if (json[key] === null || json[key] === undefined) delete json[key]; diff --git a/addons/api/tests/unit/serializers/host-catalog-test.js b/addons/api/tests/unit/serializers/host-catalog-test.js index 5cf3480fc..e56024cd6 100644 --- a/addons/api/tests/unit/serializers/host-catalog-test.js +++ b/addons/api/tests/unit/serializers/host-catalog-test.js @@ -40,7 +40,7 @@ module('Unit | Serializer | host catalog', function (hooks) { assert.deepEqual(serializedRecord, expectedResult); }); - test('it serializes an AWS plugin as expected, ignoring read-only and Azure fields', async function (assert) { + test('it serializes an AWS plugin as expected, ignoring Azure fields', async function (assert) { assert.expect(1); const store = this.owner.lookup('service:store'); const serializer = store.serializerFor('host-catalog'); @@ -76,7 +76,7 @@ module('Unit | Serializer | host catalog', function (hooks) { assert.deepEqual(serializedRecord, expectedResult); }); - test('it serializes an Azure plugin as expected, ignoring read-only and Aws fields', async function (assert) { + test('it serializes an Azure plugin as expected, ignoring AWS fields', async function (assert) { assert.expect(1); const store = this.owner.lookup('service:store'); const serializer = store.serializerFor('host-catalog'); From d8aaddfccacd0258955fb8f8aa62367308e64d09 Mon Sep 17 00:00:00 2001 From: Randall Morey Date: Fri, 21 Jan 2022 12:43:45 -0500 Subject: [PATCH 05/15] chore: convert writeOnce to writeOnly --- addons/api/addon/generated/models/host-catalog.js | 8 ++++---- addons/api/addon/serializers/application.js | 6 ++++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/addons/api/addon/generated/models/host-catalog.js b/addons/api/addon/generated/models/host-catalog.js index 6c5770790..8ef67e385 100644 --- a/addons/api/addon/generated/models/host-catalog.js +++ b/addons/api/addon/generated/models/host-catalog.js @@ -73,14 +73,14 @@ export default class GeneratedHostCatalogModel extends BaseModel { @attr('string', { isNestedAttribute: true, - writeOnce: true, + writeOnly: true, description: '', }) access_key_id; @attr('string', { isNestedAttribute: true, - writeOnce: true, + writeOnly: true, description: '', }) secret_access_key; @@ -107,14 +107,14 @@ export default class GeneratedHostCatalogModel extends BaseModel { @attr('string', { isNestedAttribute: true, - writeOnce: true, + writeOnly: true, description: '', }) secret_id; @attr('string', { isNestedAttribute: true, - writeOnce: true, + writeOnly: true, description: '', }) secret_value; diff --git a/addons/api/addon/serializers/application.js b/addons/api/addon/serializers/application.js index 26d215219..570e76ceb 100644 --- a/addons/api/addon/serializers/application.js +++ b/addons/api/addon/serializers/application.js @@ -43,8 +43,6 @@ export default class ApplicationSerializer extends RESTSerializer { if (type === 'string' && json[key] === '') json[key] = null; // Do not serialize read-only attributes. if (options.readOnly) delete json[key]; - // Only serialize write-once fields on create. - if (options.writeOnce && !snapshot.record.isNew) delete json[key]; // Version is sent only if it has a non-nullish value if (key === 'version') { if (json[key] === null || json[key] === undefined) delete json[key]; @@ -207,6 +205,10 @@ export default class ApplicationSerializer extends RESTSerializer { const scopeID = get(normalizedHash, 'scope.id'); if (scopeID) normalizedHash.scope.scope_id = scopeID; normalizedHash = this.normalizeNestedAttributes(typeClass, normalizedHash); + // Delete any lingering values on write-only fields + typeClass.attributes.forEach((attribute) => { + if (attribute.options.writeOnly) hash[attribute.name] = null; + }); return super.normalize(typeClass, normalizedHash); } From bab8c8ea44f09e28121af2212f7ff3b89555cebe Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Corvo Date: Fri, 21 Jan 2022 09:49:48 -0800 Subject: [PATCH 06/15] Add update tests for serializer --- .../unit/serializers/host-catalog-test.js | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/addons/api/tests/unit/serializers/host-catalog-test.js b/addons/api/tests/unit/serializers/host-catalog-test.js index e56024cd6..72437ee60 100644 --- a/addons/api/tests/unit/serializers/host-catalog-test.js +++ b/addons/api/tests/unit/serializers/host-catalog-test.js @@ -113,4 +113,83 @@ module('Unit | Serializer | host catalog', function (hooks) { }; assert.deepEqual(serializedRecord, expectedResult); }); + + test('it serializes aws correctly on update', function (assert) { + assert.expect(1); + const store = this.owner.lookup('service:store'); + const serializer = store.serializerFor('host-catalog'); + store.push({ + data: { + id: '1', + type: 'host-catalog', + attributes: { + type: 'plugin', + name: 'aws', + description: 'test description', + plugin: { + name: 'aws', + }, + region: 'andorra', + access_key_id: 'foobars', + secret_access_key: 'testing', + }, + }, + }); + const record = store.peekRecord('host-catalog', '1'); + const snapshot = record._createSnapshot(); + const expectedResult = { + type: 'plugin', + name: 'aws', + description: 'test description', + attributes: { + disable_credential_rotation: false, + region: 'andorra', + access_key_id: 'foobars', + secret_access_key: 'testing', + }, + }; + const serializedRecord = serializer.serialize(snapshot); + assert.deepEqual(serializedRecord, expectedResult); + }); + + test('it serializes azure correctly on update', function (assert) { + assert.expect(1); + const store = this.owner.lookup('service:store'); + const serializer = store.serializerFor('host-catalog'); + store.push({ + data: { + id: '2', + type: 'host-catalog', + attributes: { + type: 'plugin', + name: 'azure', + description: 'test description', + plugin: { + name: 'azure', + }, + tenant_id: 'a1b2c3', + client_id: 'foobars12', + subscription_id: 'barsfoo21', + // these are Azure read-only fields and should NOT be included on update + secret_id: 'secretBar12', + secret_value: 'secretValue21', + }, + }, + }); + const record = store.peekRecord('host-catalog', '2'); + const snapshot = record._createSnapshot(); + const expectedResult = { + type: 'plugin', + name: 'azure', + description: 'test description', + attributes: { + disable_credential_rotation: false, + tenant_id: 'a1b2c3', + client_id: 'foobars12', + subscription_id: 'barsfoo21', + }, + }; + const serializedRecord = serializer.serialize(snapshot); + assert.deepEqual(serializedRecord, expectedResult); + }); }); From 72dcd0d3aeff7787640615237d4ee910991a7bf8 Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Corvo Date: Fri, 21 Jan 2022 09:57:36 -0800 Subject: [PATCH 07/15] Fix unit test for azure host-catalog plugin --- addons/api/tests/unit/serializers/host-catalog-test.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/addons/api/tests/unit/serializers/host-catalog-test.js b/addons/api/tests/unit/serializers/host-catalog-test.js index 72437ee60..a2664a1ed 100644 --- a/addons/api/tests/unit/serializers/host-catalog-test.js +++ b/addons/api/tests/unit/serializers/host-catalog-test.js @@ -187,6 +187,8 @@ module('Unit | Serializer | host catalog', function (hooks) { tenant_id: 'a1b2c3', client_id: 'foobars12', subscription_id: 'barsfoo21', + secret_id: 'secretBar12', + secret_value: 'secretValue21', }, }; const serializedRecord = serializer.serialize(snapshot); From cc07df580631ac852d40f4a058a88006999b2569 Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Corvo Date: Fri, 21 Jan 2022 09:57:58 -0800 Subject: [PATCH 08/15] Delete old comment --- addons/api/tests/unit/serializers/host-catalog-test.js | 1 - 1 file changed, 1 deletion(-) diff --git a/addons/api/tests/unit/serializers/host-catalog-test.js b/addons/api/tests/unit/serializers/host-catalog-test.js index a2664a1ed..8b076860b 100644 --- a/addons/api/tests/unit/serializers/host-catalog-test.js +++ b/addons/api/tests/unit/serializers/host-catalog-test.js @@ -170,7 +170,6 @@ module('Unit | Serializer | host catalog', function (hooks) { tenant_id: 'a1b2c3', client_id: 'foobars12', subscription_id: 'barsfoo21', - // these are Azure read-only fields and should NOT be included on update secret_id: 'secretBar12', secret_value: 'secretValue21', }, From 6eccb0ea6cfac169ac7f75dae9e4b30a59885a13 Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Corvo Date: Fri, 21 Jan 2022 10:05:04 -0800 Subject: [PATCH 09/15] Simplified tests code --- .../unit/serializers/host-catalog-test.js | 37 +++++-------------- 1 file changed, 10 insertions(+), 27 deletions(-) diff --git a/addons/api/tests/unit/serializers/host-catalog-test.js b/addons/api/tests/unit/serializers/host-catalog-test.js index 8b076860b..df3f8efc8 100644 --- a/addons/api/tests/unit/serializers/host-catalog-test.js +++ b/addons/api/tests/unit/serializers/host-catalog-test.js @@ -6,44 +6,38 @@ module('Unit | Serializer | host catalog', function (hooks) { // Replace this with your real tests. test('it exists', function (assert) { - let store = this.owner.lookup('service:store'); - let serializer = store.serializerFor('host-catalog'); + const store = this.owner.lookup('service:store'); + const serializer = store.serializerFor('host-catalog'); assert.ok(serializer); }); test('it serializes records', function (assert) { - let store = this.owner.lookup('service:store'); - let record = store.createRecord('host-catalog', {}); + const store = this.owner.lookup('service:store'); + const record = store.createRecord('host-catalog', {}); - let serializedRecord = record.serialize(); - - assert.ok(serializedRecord); + assert.ok(record.serialize()); }); test('it serializes a static host-catalog as expected', async function (assert) { assert.expect(1); const store = this.owner.lookup('service:store'); - const serializer = store.serializerFor('host-catalog'); const record = store.createRecord('host-catalog', { name: 'static', description: 'this is a static host-catalog', type: 'static', }); - const snapshot = record._createSnapshot(); - const serializedRecord = serializer.serialize(snapshot); const expectedResult = { name: 'static', description: 'this is a static host-catalog', type: 'static', }; - assert.deepEqual(serializedRecord, expectedResult); + assert.deepEqual(record.serialize(), expectedResult); }); test('it serializes an AWS plugin as expected, ignoring Azure fields', async function (assert) { assert.expect(1); const store = this.owner.lookup('service:store'); - const serializer = store.serializerFor('host-catalog'); const record = store.createRecord('host-catalog', { compositeType: 'aws', name: 'AWS', @@ -60,8 +54,6 @@ module('Unit | Serializer | host catalog', function (hooks) { secret_id: 'a1b2c3', secret_value: 'a1b2c3', }); - const snapshot = record._createSnapshot(); - const serializedRecord = serializer.serialize(snapshot); const expectedResult = { name: 'AWS', description: 'this is a Aws plugin host-catalog', @@ -73,13 +65,12 @@ module('Unit | Serializer | host catalog', function (hooks) { secret_access_key: 'testing', }, }; - assert.deepEqual(serializedRecord, expectedResult); + assert.deepEqual(record.serialize(), expectedResult); }); test('it serializes an Azure plugin as expected, ignoring AWS fields', async function (assert) { assert.expect(1); const store = this.owner.lookup('service:store'); - const serializer = store.serializerFor('host-catalog'); const record = store.createRecord('host-catalog', { compositeType: 'azure', name: 'Azure', @@ -96,8 +87,6 @@ module('Unit | Serializer | host catalog', function (hooks) { secret_id: 'a1b2c3', secret_value: 'a1b2c3', }); - const snapshot = record._createSnapshot(); - const serializedRecord = serializer.serialize(snapshot); const expectedResult = { name: 'Azure', description: 'this is a Azure plugin host-catalog', @@ -111,13 +100,12 @@ module('Unit | Serializer | host catalog', function (hooks) { secret_value: 'a1b2c3', }, }; - assert.deepEqual(serializedRecord, expectedResult); + assert.deepEqual(record.serialize(), expectedResult); }); test('it serializes aws correctly on update', function (assert) { assert.expect(1); const store = this.owner.lookup('service:store'); - const serializer = store.serializerFor('host-catalog'); store.push({ data: { id: '1', @@ -136,7 +124,6 @@ module('Unit | Serializer | host catalog', function (hooks) { }, }); const record = store.peekRecord('host-catalog', '1'); - const snapshot = record._createSnapshot(); const expectedResult = { type: 'plugin', name: 'aws', @@ -148,14 +135,12 @@ module('Unit | Serializer | host catalog', function (hooks) { secret_access_key: 'testing', }, }; - const serializedRecord = serializer.serialize(snapshot); - assert.deepEqual(serializedRecord, expectedResult); + assert.deepEqual(record.serialize(), expectedResult); }); test('it serializes azure correctly on update', function (assert) { assert.expect(1); const store = this.owner.lookup('service:store'); - const serializer = store.serializerFor('host-catalog'); store.push({ data: { id: '2', @@ -176,7 +161,6 @@ module('Unit | Serializer | host catalog', function (hooks) { }, }); const record = store.peekRecord('host-catalog', '2'); - const snapshot = record._createSnapshot(); const expectedResult = { type: 'plugin', name: 'azure', @@ -190,7 +174,6 @@ module('Unit | Serializer | host catalog', function (hooks) { secret_value: 'secretValue21', }, }; - const serializedRecord = serializer.serialize(snapshot); - assert.deepEqual(serializedRecord, expectedResult); + assert.deepEqual(record.serialize(), expectedResult); }); }); From cd02f6aec31b1635a5be7637fd0934cb7e1df186 Mon Sep 17 00:00:00 2001 From: Randall Morey Date: Fri, 21 Jan 2022 15:22:59 -0500 Subject: [PATCH 10/15] chore: add isNestedSecret support --- addons/api/addon/serializers/application.js | 35 ++++++++++++++++++--- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/addons/api/addon/serializers/application.js b/addons/api/addon/serializers/application.js index 570e76ceb..6713f0069 100644 --- a/addons/api/addon/serializers/application.js +++ b/addons/api/addon/serializers/application.js @@ -56,6 +56,12 @@ export default class ApplicationSerializer extends RESTSerializer { json.attributes[key] = json[key]; delete json[key]; } + // Push nested secrets down into the secrets key + if (options.isNestedSecret && json[key]) { + if (!json.secrets) json.secrets = {}; + json.secrets[key] = json[key]; + delete json[key]; + } return value; } @@ -205,10 +211,7 @@ export default class ApplicationSerializer extends RESTSerializer { const scopeID = get(normalizedHash, 'scope.id'); if (scopeID) normalizedHash.scope.scope_id = scopeID; normalizedHash = this.normalizeNestedAttributes(typeClass, normalizedHash); - // Delete any lingering values on write-only fields - typeClass.attributes.forEach((attribute) => { - if (attribute.options.writeOnly) hash[attribute.name] = null; - }); + normalizedHash = this.normalizeNestedSecrets(typeClass, normalizedHash); return super.normalize(typeClass, normalizedHash); } @@ -228,7 +231,6 @@ export default class ApplicationSerializer extends RESTSerializer { * @return {Object} */ normalizeNestedAttributes(typeClass, hash) { - const normalizedHash = copy(hash, true); typeClass.attributes.forEach((attribute) => { const { isNestedAttribute } = attribute.options; const attributeValue = normalizedHash.attributes?.[attribute.name]; @@ -238,4 +240,27 @@ export default class ApplicationSerializer extends RESTSerializer { }); return normalizedHash; } + + /** + * If an attribute is declared with the `isNestedSecret` option, it will + * be explicitly unset in the incoming payload to `null`. This helps ensure + * secret values do not linger in the UI. + * + * For example: + * `@attr('string', { isNestedSecret: true }) superSecretShhh;` + * + * @param {Model} typeClass + * @param {Object} hash + * @return {Object} + */ + normalizeNestedSecrets(typeClass, hash) { + typeClass.attributes.forEach((attribute) => { + const { + name, + options: { isNestedSecret }, + } = attribute; + if (isNestedSecret) normalizedHash[name] = null; + }); + return normalizedHash; + } } From 44ea5e329b8e5fe1f038f03d2534394a50ef1a8e Mon Sep 17 00:00:00 2001 From: Randall Morey Date: Fri, 21 Jan 2022 15:24:38 -0500 Subject: [PATCH 11/15] chore: always delete nested secrets from main payload --- addons/api/addon/serializers/application.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/addons/api/addon/serializers/application.js b/addons/api/addon/serializers/application.js index 6713f0069..6ad34b4d9 100644 --- a/addons/api/addon/serializers/application.js +++ b/addons/api/addon/serializers/application.js @@ -57,9 +57,11 @@ export default class ApplicationSerializer extends RESTSerializer { delete json[key]; } // Push nested secrets down into the secrets key - if (options.isNestedSecret && json[key]) { - if (!json.secrets) json.secrets = {}; - json.secrets[key] = json[key]; + if (options.isNestedSecret) { + if (json[key]) { + if (!json.secrets) json.secrets = {}; + json.secrets[key] = json[key]; + } delete json[key]; } return value; From 712607cb0cf8c026d8e5595a78d631e928d8a8be Mon Sep 17 00:00:00 2001 From: Randall Morey Date: Fri, 21 Jan 2022 15:26:27 -0500 Subject: [PATCH 12/15] fix: variable name --- addons/api/addon/serializers/application.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/addons/api/addon/serializers/application.js b/addons/api/addon/serializers/application.js index 6ad34b4d9..29f3fa1b4 100644 --- a/addons/api/addon/serializers/application.js +++ b/addons/api/addon/serializers/application.js @@ -235,12 +235,12 @@ export default class ApplicationSerializer extends RESTSerializer { normalizeNestedAttributes(typeClass, hash) { typeClass.attributes.forEach((attribute) => { const { isNestedAttribute } = attribute.options; - const attributeValue = normalizedHash.attributes?.[attribute.name]; + const attributeValue = hash.attributes?.[attribute.name]; if (isNestedAttribute && attributeValue) { - normalizedHash[attribute.name] = attributeValue; + hash[attribute.name] = attributeValue; } }); - return normalizedHash; + return hash; } /** @@ -261,8 +261,8 @@ export default class ApplicationSerializer extends RESTSerializer { name, options: { isNestedSecret }, } = attribute; - if (isNestedSecret) normalizedHash[name] = null; + if (isNestedSecret) hash[name] = null; }); - return normalizedHash; + return hash; } } From 614be72a6e4a8135f92c4dbe086e4f1131501a44 Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Corvo Date: Fri, 21 Jan 2022 12:55:04 -0800 Subject: [PATCH 13/15] Add isNestedSecret option to model, add secrets field to model, add isNestedSecert serialization. Change tests to the last changes --- addons/api/addon/generated/models/host-catalog.js | 13 +++++++++---- addons/api/addon/serializers/host-catalog.js | 7 +++++++ .../api/tests/unit/serializers/host-catalog-test.js | 8 ++++++++ 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/addons/api/addon/generated/models/host-catalog.js b/addons/api/addon/generated/models/host-catalog.js index 8ef67e385..f786b4568 100644 --- a/addons/api/addon/generated/models/host-catalog.js +++ b/addons/api/addon/generated/models/host-catalog.js @@ -44,6 +44,11 @@ export default class GeneratedHostCatalogModel extends BaseModel { }) attributes; + @attr({ + description: 'Secrets specific to the plugin type', + }) + secrets; + @attr('number', { description: 'Current version number of this resource.', }) @@ -72,14 +77,14 @@ export default class GeneratedHostCatalogModel extends BaseModel { region; @attr('string', { - isNestedAttribute: true, + isNestedSecret: true, writeOnly: true, description: '', }) access_key_id; @attr('string', { - isNestedAttribute: true, + isNestedSecret: true, writeOnly: true, description: '', }) @@ -106,14 +111,14 @@ export default class GeneratedHostCatalogModel extends BaseModel { subscription_id; @attr('string', { - isNestedAttribute: true, + isNestedSecret: true, writeOnly: true, description: '', }) secret_id; @attr('string', { - isNestedAttribute: true, + isNestedSecret: true, writeOnly: true, description: '', }) diff --git a/addons/api/addon/serializers/host-catalog.js b/addons/api/addon/serializers/host-catalog.js index 0bb99d19b..77c78c680 100644 --- a/addons/api/addon/serializers/host-catalog.js +++ b/addons/api/addon/serializers/host-catalog.js @@ -40,6 +40,12 @@ export default class HostCatalogSerializer extends ApplicationSerializer { if (!fieldsByType[compositeType].includes(key)) delete json.attributes[key]; } + // This deletes any fields that don't belong to the record type + if (isPlugin && options.isNestedSecret && json.secrets) { + if (!fieldsByType[compositeType].includes(key)) delete json.secrets[key]; + } + + // new one for isNestedSecret return value; } @@ -47,6 +53,7 @@ export default class HostCatalogSerializer extends ApplicationSerializer { const serialized = super.serialize(...arguments); // Delete unnecessary fields for static host-catalog delete serialized.attributes; + delete serialized.secrets; return serialized; } } diff --git a/addons/api/tests/unit/serializers/host-catalog-test.js b/addons/api/tests/unit/serializers/host-catalog-test.js index df3f8efc8..018f1a1d8 100644 --- a/addons/api/tests/unit/serializers/host-catalog-test.js +++ b/addons/api/tests/unit/serializers/host-catalog-test.js @@ -61,6 +61,8 @@ module('Unit | Serializer | host catalog', function (hooks) { attributes: { disable_credential_rotation: true, region: 'spain', + }, + secrets: { access_key_id: 'foobars', secret_access_key: 'testing', }, @@ -96,6 +98,8 @@ module('Unit | Serializer | host catalog', function (hooks) { tenant_id: 'a1b2c3', client_id: 'a1b2c3', subscription_id: 'a1b2c3', + }, + secrets: { secret_id: 'a1b2c3', secret_value: 'a1b2c3', }, @@ -131,6 +135,8 @@ module('Unit | Serializer | host catalog', function (hooks) { attributes: { disable_credential_rotation: false, region: 'andorra', + }, + secrets: { access_key_id: 'foobars', secret_access_key: 'testing', }, @@ -170,6 +176,8 @@ module('Unit | Serializer | host catalog', function (hooks) { tenant_id: 'a1b2c3', client_id: 'foobars12', subscription_id: 'barsfoo21', + }, + secrets: { secret_id: 'secretBar12', secret_value: 'secretValue21', }, From 12bb8203c2a0936f833e2c6e629a1dc3d0983015 Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Corvo Date: Fri, 21 Jan 2022 14:45:21 -0800 Subject: [PATCH 14/15] Change mirage attributes to factory --- .../addon/generated/models/host-catalog.js | 9 --- addons/api/mirage/factories/host-catalog.js | 21 +++++++ .../generated/factories/host-catalog.js | 60 +------------------ 3 files changed, 22 insertions(+), 68 deletions(-) diff --git a/addons/api/addon/generated/models/host-catalog.js b/addons/api/addon/generated/models/host-catalog.js index f786b4568..0591352e2 100644 --- a/addons/api/addon/generated/models/host-catalog.js +++ b/addons/api/addon/generated/models/host-catalog.js @@ -44,11 +44,6 @@ export default class GeneratedHostCatalogModel extends BaseModel { }) attributes; - @attr({ - description: 'Secrets specific to the plugin type', - }) - secrets; - @attr('number', { description: 'Current version number of this resource.', }) @@ -78,14 +73,12 @@ export default class GeneratedHostCatalogModel extends BaseModel { @attr('string', { isNestedSecret: true, - writeOnly: true, description: '', }) access_key_id; @attr('string', { isNestedSecret: true, - writeOnly: true, description: '', }) secret_access_key; @@ -112,14 +105,12 @@ export default class GeneratedHostCatalogModel extends BaseModel { @attr('string', { isNestedSecret: true, - writeOnly: true, description: '', }) secret_id; @attr('string', { isNestedSecret: true, - writeOnly: true, description: '', }) secret_value; diff --git a/addons/api/mirage/factories/host-catalog.js b/addons/api/mirage/factories/host-catalog.js index 75bcc3928..f7c82a20d 100644 --- a/addons/api/mirage/factories/host-catalog.js +++ b/addons/api/mirage/factories/host-catalog.js @@ -1,6 +1,7 @@ import factory from '../generated/factories/host-catalog'; import { trait } from 'ember-cli-mirage'; import permissions from '../helpers/permissions'; +import { datatype, address } from 'faker'; export default factory.extend({ authorized_actions: () => @@ -16,6 +17,26 @@ export default factory.extend({ 'host-sets': ['create', 'list'], }; }, + attributes() { + if (this.plugin) { + switch (this.plugin.name) { + case 'aws': + return { + tenant_id: datatype.hexaDecimal(6), + client_id: datatype.hexaDecimal(6), + subscription_id: datatype.hexaDecimal(8), + secret_id: datatype.hexaDecimal(6), + secret_value: datatype.string(12), + }; + case 'azure': + return { + region: address.state(), + access_key_id: datatype.hexaDecimal(8), + secret_access_key: datatype.string(12), + }; + } + } + }, withChildren: trait({ afterCreate(hostCatalog, server) { const { scope, type } = hostCatalog; diff --git a/addons/api/mirage/generated/factories/host-catalog.js b/addons/api/mirage/generated/factories/host-catalog.js index 14dcbb306..20601e2f3 100644 --- a/addons/api/mirage/generated/factories/host-catalog.js +++ b/addons/api/mirage/generated/factories/host-catalog.js @@ -1,22 +1,6 @@ import { Factory } from 'ember-cli-mirage'; -import { random, date, datatype, address } from 'faker'; +import { random, date, datatype } from 'faker'; -/** - * - * @param {object} plugin - * @returns - */ -function isAzurePlugin(plugin) { - if (plugin && plugin.name === 'azure') { - return true; - } -} - -function isAwsPlugin(plugin) { - if (plugin && plugin.name === 'aws') { - return true; - } -} /** * GeneratedHostCatalogModelFactory */ @@ -37,46 +21,4 @@ export default Factory.extend({ } }, disable_credential_rotation: () => datatype.boolean(), - // Azure specific fields - region: function () { - if (isAzurePlugin(this.plugin)) { - return address.state(); - } - }, - access_key_id: function () { - if (isAzurePlugin(this.plugin)) { - return datatype.hexaDecimal(8); - } - }, - secret_access_key: function () { - if (isAzurePlugin(this.plugin)) { - return datatype.string(12); - } - }, - // AWS specific fields - tenant_id: function () { - if (isAwsPlugin(this.plugin)) { - return datatype.hexaDecimal(6); - } - }, - client_id: function () { - if (isAwsPlugin(this.plugin)) { - return datatype.hexaDecimal(6); - } - }, - subscription_id: function () { - if (isAwsPlugin(this.plugin)) { - return datatype.hexaDecimal(8); - } - }, - secret_id: function () { - if (isAwsPlugin(this.plugin)) { - return datatype.hexaDecimal(6); - } - }, - secret_value: function () { - if (isAwsPlugin(this.plugin)) { - return datatype.string(12); - } - }, }); From ffb00c708f19f3a9c78873c89289e3924646a7e2 Mon Sep 17 00:00:00 2001 From: Carlos Alcaide Corvo Date: Mon, 24 Jan 2022 10:01:17 -0800 Subject: [PATCH 15/15] Refactor mirage factory. Rephrase test description. Refactor some tests to not test secret fields --- addons/api/mirage/factories/host-catalog.js | 34 +++++++++---------- .../generated/factories/host-catalog.js | 1 - .../unit/serializers/host-catalog-test.js | 21 +++--------- 3 files changed, 21 insertions(+), 35 deletions(-) diff --git a/addons/api/mirage/factories/host-catalog.js b/addons/api/mirage/factories/host-catalog.js index f7c82a20d..3179f2c99 100644 --- a/addons/api/mirage/factories/host-catalog.js +++ b/addons/api/mirage/factories/host-catalog.js @@ -18,23 +18,23 @@ export default factory.extend({ }; }, attributes() { - if (this.plugin) { - switch (this.plugin.name) { - case 'aws': - return { - tenant_id: datatype.hexaDecimal(6), - client_id: datatype.hexaDecimal(6), - subscription_id: datatype.hexaDecimal(8), - secret_id: datatype.hexaDecimal(6), - secret_value: datatype.string(12), - }; - case 'azure': - return { - region: address.state(), - access_key_id: datatype.hexaDecimal(8), - secret_access_key: datatype.string(12), - }; - } + switch (this.plugin?.name) { + case 'aws': + return { + disable_credential_rotation: datatype.boolean(), + tenant_id: datatype.hexaDecimal(6), + client_id: datatype.hexaDecimal(6), + subscription_id: datatype.hexaDecimal(8), + secret_id: datatype.hexaDecimal(6), + secret_value: datatype.string(12), + }; + case 'azure': + return { + disable_credential_rotation: datatype.boolean(), + region: address.state(), + access_key_id: datatype.hexaDecimal(8), + secret_access_key: datatype.string(12), + }; } }, withChildren: trait({ diff --git a/addons/api/mirage/generated/factories/host-catalog.js b/addons/api/mirage/generated/factories/host-catalog.js index 20601e2f3..fa8135226 100644 --- a/addons/api/mirage/generated/factories/host-catalog.js +++ b/addons/api/mirage/generated/factories/host-catalog.js @@ -20,5 +20,4 @@ export default Factory.extend({ }; } }, - disable_credential_rotation: () => datatype.boolean(), }); diff --git a/addons/api/tests/unit/serializers/host-catalog-test.js b/addons/api/tests/unit/serializers/host-catalog-test.js index 018f1a1d8..d82869348 100644 --- a/addons/api/tests/unit/serializers/host-catalog-test.js +++ b/addons/api/tests/unit/serializers/host-catalog-test.js @@ -35,7 +35,7 @@ module('Unit | Serializer | host catalog', function (hooks) { assert.deepEqual(record.serialize(), expectedResult); }); - test('it serializes an AWS plugin as expected, ignoring Azure fields', async function (assert) { + test('it serializes a new aws plugin as expected, ignoring azure fields', async function (assert) { assert.expect(1); const store = this.owner.lookup('service:store'); const record = store.createRecord('host-catalog', { @@ -70,7 +70,7 @@ module('Unit | Serializer | host catalog', function (hooks) { assert.deepEqual(record.serialize(), expectedResult); }); - test('it serializes an Azure plugin as expected, ignoring AWS fields', async function (assert) { + test('it serializes a new azure record as expected, ignoring aws fields', async function (assert) { assert.expect(1); const store = this.owner.lookup('service:store'); const record = store.createRecord('host-catalog', { @@ -78,7 +78,6 @@ module('Unit | Serializer | host catalog', function (hooks) { name: 'Azure', description: 'this is a Azure plugin host-catalog', disable_credential_rotation: true, - // these are AWS fields and should be included region: 'spain', access_key_id: 'foobars', secret_access_key: 'testing', @@ -107,7 +106,7 @@ module('Unit | Serializer | host catalog', function (hooks) { assert.deepEqual(record.serialize(), expectedResult); }); - test('it serializes aws correctly on update', function (assert) { + test('it serializes an existing aws record correctly', function (assert) { assert.expect(1); const store = this.owner.lookup('service:store'); store.push({ @@ -122,8 +121,6 @@ module('Unit | Serializer | host catalog', function (hooks) { name: 'aws', }, region: 'andorra', - access_key_id: 'foobars', - secret_access_key: 'testing', }, }, }); @@ -136,15 +133,11 @@ module('Unit | Serializer | host catalog', function (hooks) { disable_credential_rotation: false, region: 'andorra', }, - secrets: { - access_key_id: 'foobars', - secret_access_key: 'testing', - }, }; assert.deepEqual(record.serialize(), expectedResult); }); - test('it serializes azure correctly on update', function (assert) { + test('it serializes an existing azure record correctly', function (assert) { assert.expect(1); const store = this.owner.lookup('service:store'); store.push({ @@ -161,8 +154,6 @@ module('Unit | Serializer | host catalog', function (hooks) { tenant_id: 'a1b2c3', client_id: 'foobars12', subscription_id: 'barsfoo21', - secret_id: 'secretBar12', - secret_value: 'secretValue21', }, }, }); @@ -177,10 +168,6 @@ module('Unit | Serializer | host catalog', function (hooks) { client_id: 'foobars12', subscription_id: 'barsfoo21', }, - secrets: { - secret_id: 'secretBar12', - secret_value: 'secretValue21', - }, }; assert.deepEqual(record.serialize(), expectedResult); });