Icu 11022 update dynamic credentials in sb form (#1901)
This commit is contained in:
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;
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user