Icu 11022 update dynamic credentials in sb form (#1901)

This commit is contained in:
Dharini Jeeva authored and GitHub committed 2023-09-18 14:23:30 -07:00
1 parent 4910070c95
commit 78d1e09a0d
8 files changed
+112 -33

No files matched your search

@@ -73,12 +73,6 @@ export default class GeneratedStorageBucketModel extends BaseModel {
})
region;
@attr('string', {
readOnly: true,
isNestedAttribute: true,
})
secrets_hmac;
@attr('boolean', {
isNestedAttribute: true,
description: 'If set to `true`, credential rotation is not performed.',
@@ -120,7 +114,6 @@ export default class GeneratedStorageBucketModel extends BaseModel {
@attr('object-as-array', {
isNestedAttribute: true,
description: 'The role tags to use.',
useLabels: true,
})
role_tags;
}
+1 -1
View File
@@ -36,7 +36,7 @@ export default class StorageBucketModel extends GeneratedStorageBucketModel {
* @type {string}
*/
get credentialType() {
if (this.role_arn) {
if (this.role_arn && !this.access_key_id) {
return TYPE_CREDENTIAL_DYNAMIC;
} else {
return TYPE_CREDENTIAL_STATIC;
+42 -9
View File
@@ -4,29 +4,62 @@
*/
import ApplicationSerializer from './application';
import { TYPE_CREDENTIAL_DYNAMIC } from '../models/storage-bucket';
const fieldsByCredentialType = {
static: [
'access_key_id',
'secret_access_key',
'region',
'disable_credential_rotation',
],
dynamic: [
'role_arn',
'role_external_id',
'role_session_name',
'role_tags',
'disable_credential_rotation',
'region',
],
};
export default class StorageBucketSerializer extends ApplicationSerializer {
serialize(snapshot) {
const serialized = super.serialize(...arguments);
//Dynamic credentials do not allow credential rotation, and the API requires this field to be
//sent along with the dynamic credential fields
if (serialized.attributes.role_arn) {
serialized.attributes.disable_credential_rotation = true;
}
const { credentialType } = snapshot.record;
if (!snapshot.record.isNew) {
delete serialized.bucket_name;
delete serialized.bucket_prefix;
}
if (credentialType === TYPE_CREDENTIAL_DYNAMIC) {
serialized.attributes.disable_credential_rotation = true;
}
return serialized;
}
serializeAttribute(snapshot, json, key, attribute) {
const value = super.serializeAttribute(...arguments);
const { credentialType } = snapshot.record;
const { options } = attribute;
// This deletes any fields that don't belong to the record's credential type
if (options.isNestedAttribute && json.attributes) {
// The key must be included in the fieldsByType list above
if (!fieldsByCredentialType[credentialType].includes(key))
//API requires these fields to be null
json.attributes[key] = null;
}
return value;
}
normalize(typeClass, hash, ...rest) {
const normalizedHash = structuredClone(hash);
const normalized = super.normalize(typeClass, normalizedHash, ...rest);
// Remove secret fields so we don't track them after creating/updating
normalized.data.attributes.access_key_id = null;
normalized.data.attributes.secret_access_key = null;
return normalized;
if (normalizedHash?.secrets?.access_key_id) {
delete normalizedHash.secrets.access_key_id;
delete normalizedHash.secrets.secret_access_key;
}
return super.normalize(typeClass, normalizedHash, ...rest);
}
}
+1 -3
View File
@@ -696,10 +696,8 @@ function routes() {
name: plugin_name,
};
}
// Remove the secrets and add the hmac in the response
// Remove the secrets
delete attrs.secrets;
attrs.secrets_hmac = faker.git.commitSha();
return storageBuckets.create(attrs);
}
@@ -35,7 +35,6 @@ module('Unit | Serializer | storage bucket', function (hooks) {
region: 'eu-west-1',
access_key_id: 'foobars',
secret_access_key: 'testing',
secrets_hmac: 'hmac',
disable_credential_rotation: true,
role_arn: null,
role_external_id: null,
@@ -78,7 +77,6 @@ module('Unit | Serializer | storage bucket', function (hooks) {
region: 'eu-west-1',
access_key_id: '',
secret_access_key: '',
secrets_hmac: 'hmac',
disable_credential_rotation: true,
role_arn: 'arn',
role_external_id: 'Example987',
@@ -106,7 +104,7 @@ module('Unit | Serializer | storage bucket', function (hooks) {
};
assert.deepEqual(record.serialize(), expectedResult);
});
test('it serializes when updating correctly', async function (assert) {
test('it serializes when updating a storage bucket with static credential correctly', async function (assert) {
assert.expect(1);
const store = this.owner.lookup('service:store');
const serializer = store.serializerFor('storage-bucket');
@@ -125,13 +123,8 @@ module('Unit | Serializer | storage bucket', function (hooks) {
region: 'eu-west-1',
access_key_id: 'foobars',
secret_access_key: 'testing',
secrets_hmac: 'hmac',
disable_credential_rotation: true,
version: 1,
role_arn: null,
role_external_id: null,
role_session_name: null,
role_tags: [],
},
},
});
@@ -161,6 +154,57 @@ module('Unit | Serializer | storage bucket', function (hooks) {
assert.deepEqual(serializedRecord, expectedResult);
});
test('it serializes when updating a storage bucket with dynamic credential correctly', async function (assert) {
assert.expect(1);
const store = this.owner.lookup('service:store');
const serializer = store.serializerFor('storage-bucket');
store.push({
data: {
id: '1',
type: 'storage-bucket',
attributes: {
type: TYPE_STORAGE_BUCKET_PLUGIN,
compositeType: TYPE_STORAGE_BUCKET_PLUGIN_AWS_S3,
name: 'AWS',
description: 'this has an aws plugin',
bucket_name: 'bucketname',
bucket_prefix: 'bucketprefix',
worker_filter: 'workerfilter',
region: 'eu-west-1',
disable_credential_rotation: true,
version: 1,
role_arn: 'arn',
role_external_id: 'Example987',
role_session_name: 'my-session',
role_tags: [
{ key: 'Project', value: 'Automation' },
{ key: 'foo', value: 'bar' },
],
},
},
});
const record = store.peekRecord('storage-bucket', '1');
const snapshot = record._createSnapshot();
const serializedRecord = serializer.serialize(snapshot);
const expectedResult = {
name: 'AWS',
description: 'this has an aws plugin',
type: TYPE_STORAGE_BUCKET_PLUGIN,
worker_filter: 'workerfilter',
attributes: {
region: 'eu-west-1',
disable_credential_rotation: true,
role_arn: 'arn',
role_external_id: 'Example987',
role_session_name: 'my-session',
role_tags: { Project: 'Automation', foo: 'bar' },
},
version: 1,
};
assert.deepEqual(serializedRecord, expectedResult);
});
test('it normalizes correctly', function (assert) {
assert.expect(1);
const store = this.owner.lookup('service:store');
@@ -179,7 +223,6 @@ module('Unit | Serializer | storage bucket', function (hooks) {
region: 'eu-west-1',
disable_credential_rotation: true,
},
secrets_hmac: 'this is secret',
};
const normalized = serializer.normalizeSingleResponse(
store,
@@ -200,7 +243,6 @@ module('Unit | Serializer | storage bucket', function (hooks) {
bucket_name: 'bucketname',
bucket_prefix: 'bucketprefix',
worker_filter: 'workerfilter',
secrets_hmac: 'this is secret',
region: 'eu-west-1',
disable_credential_rotation: true,
access_key_id: null,
@@ -5,7 +5,7 @@
<Rose::Form
@onSubmit={{@submit}}
@cancel={{@cancel}}
@cancel={{this.cancel}}
@disabled={{@model.isSaving}}
@showEditToggle={{if @model.isNew false true}}
as |form|
@@ -113,4 +113,17 @@ export default class FormStorageBucketComponent extends Component {
this.args.model.disable_credential_rotation =
!this.args.model.disable_credential_rotation;
}
/**
* Call passed cancel function.
* Unset selected credentials.
*/
@action
cancel() {
this.args.cancel();
// Reset the tracked variable after rollback
this.selectedCredentialType = this.args.model.credentialType;
this.showDynamicCredentials =
this.args.model.credentialType === TYPE_CREDENTIAL_DYNAMIC;
}
}
@@ -14,12 +14,12 @@ export default class ScopesScopeStorageBucketsStorageBucketRoute extends Route {
// =methods
/**
* Load a user in current scope.
* Load a storage bucket in current scope.
* @param {object} params
* @param {string} params.storage_bucket_id
* @return {StorageBucketModel}
*/
async model({ storage_bucket_id }) {
model({ storage_bucket_id }) {
return this.store.findRecord('storage-bucket', storage_bucket_id);
}
}