feat: 🎸 scope policy association api changes (#2086)

scope policy association API changes
This commit is contained in:
Dharini Jeeva authored and GitHub committed 2024-01-12 11:29:19 -08:00
1 parent 1cb3b708a2
commit eefb9eba4f
7 files changed
+164 -6

No files matched your search

@@ -49,4 +49,9 @@ export default class GeneratedScopeModel extends BaseModel {
description: 'Current version number of this resource.',
})
version;
@attr('string', {
description: 'The ID of the associated storage policy',
})
storage_policy_id;
}
+1
View File
@@ -5,4 +5,5 @@
import GeneratedPolicyModel from '../generated/models/policy';
export const TYPE_POLICY = 'storage';
export default class PolicyModel extends GeneratedPolicyModel {}
+44
View File
@@ -46,4 +46,48 @@ export default class ScopeModel extends GeneratedScopeModel {
set isProject(value) {
if (value) this.type = scopeTypes.project;
}
/**
* Attach policy via the `attach-staorage-policy` method.
* @param {[string]} policyId
* @param {object} options
* @param {object} options.adapterOptions
* @return {Promise}
*/
attachStoragePolicy(policyId, options = { adapterOptions: {} }) {
const defaultAdapterOptions = {
method: 'attach-storage-policy',
policyId,
};
// There is no "deep merge" in ES.
return this.save({
...options,
adapterOptions: {
...defaultAdapterOptions,
...options.adapterOptions,
},
});
}
/**
* Detaches policy via the `detach-storage-policy` method.
* @param {[string]} policyId
* @param {object} options
* @param {object} options.adapterOptions
* @return {Promise}
*/
detachStoragePolicy(policyId, options = { adapterOptions: {} }) {
const defaultAdapterOptions = {
method: 'detach-storage-policy',
policyId,
};
// There is no "deep merge" in ES.
return this.save({
...options,
adapterOptions: {
...defaultAdapterOptions,
...options.adapterOptions,
},
});
}
}
+35
View File
@@ -0,0 +1,35 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
*/
import ApplicationSerializer from './application';
export default class ScopeSerializer extends ApplicationSerializer {
// =methods
serialize(snapshot) {
let serialized = super.serialize(...arguments);
const policyId = snapshot?.adapterOptions?.policyId;
if (policyId) {
serialized = this.serializeWithStoragePolicy(snapshot, policyId);
}
return serialized;
}
/**
* Returns a payload containing only version and storage policy id,
* rather than existing instances on the model.
* @param {Snapshot} snapshot
* @param {[string]} hostSetIDs
* @return {object}
*/
serializeWithStoragePolicy(snapshot, policyId) {
return {
version: snapshot.attr('version'),
storage_policy_id: policyId,
};
}
}
+6
View File
@@ -0,0 +1,6 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
*/
export { default } from 'api/serializers/scope';
+73 -5
View File
@@ -27,27 +27,27 @@ module('Unit | Model | scope', function (hooks) {
// check integrity of scope relationships
assert.notOk(await scopes[0].get('scope'), 'Global scope has no parent');
assert.strictEqual(
await scopes.objectAt(1).get('scope.scope_id'),
await scopes.at(1).get('scope.scope_id'),
'global',
'Org 1 parent scope is global',
);
assert.strictEqual(
await scopes.objectAt(2).get('scope.scope_id'),
await scopes.at(2).get('scope.scope_id'),
'global',
'Org 2 parent scope is global',
);
assert.strictEqual(
await scopes.objectAt(3).get('scope.scope_id'),
await scopes.at(3).get('scope.scope_id'),
'o_1',
'Project 1 parent scope is org 1',
);
assert.strictEqual(
await scopes.objectAt(4).get('scope.scope_id'),
await scopes.at(4).get('scope.scope_id'),
'o_1',
'Project 2 parent scope is org 1',
);
assert.strictEqual(
await scopes.objectAt(5).get('scope.scope_id'),
await scopes.at(5).get('scope.scope_id'),
'o_2',
'Project 3 parent scope is org 2',
);
@@ -68,4 +68,72 @@ module('Unit | Model | scope', function (hooks) {
assert.notOk(model.isOrg);
assert.ok(model.isProject);
});
test('it has an `attachStoragePolicy` method that targets a specific POST API endpoint and serialization', async function (assert) {
assert.expect(1);
this.server.post(
'/v1/scopes/123abc:attach-storage-policy',
(schema, request) => {
const body = JSON.parse(request.requestBody);
assert.deepEqual(body, {
storage_policy_id: 'abc',
version: 1,
});
return { id: '123abc' };
},
);
const store = this.owner.lookup('service:store');
store.push({
data: {
id: '123abc',
type: 'scope',
attributes: {
name: 'scope',
description: 'Description',
storage_policy_id: 'abc',
version: 1,
scope: {
scope_id: 'o_1',
type: 'scope',
},
},
},
});
const model = store.peekRecord('scope', '123abc');
await model.attachStoragePolicy('abc');
});
test('it has a `detachStoragePolicy` method that targets a specific POST API endpoint and serialization', async function (assert) {
assert.expect(1);
this.server.post(
'/v1/scopes/123abc:detach-storage-policy',
(schema, request) => {
const body = JSON.parse(request.requestBody);
assert.deepEqual(body, {
storage_policy_id: 'abc',
version: 1,
});
return { id: '123abc' };
},
);
const store = this.owner.lookup('service:store');
store.push({
data: {
id: '123abc',
type: 'scope',
attributes: {
name: 'Target',
description: 'Description',
storage_policy_id: 'abc',
version: 1,
scope: {
scope_id: 'o_1',
type: 'scope',
},
},
},
});
const model = store.peekRecord('scope', '123abc');
await model.detachStoragePolicy('abc');
});
});
@@ -53,7 +53,6 @@ export default class FormPolicySelectionComponent extends Component {
return false;
}
}
//actions
/**
* Handles custom input changes