Types for aws host catalogs (#2514)
assume role dynamic AWS credentials
This commit is contained in:
1 parent
0d55812f64
commit
965e82473d
11 files changed
+538
-89
No files matched your search
@@ -66,7 +66,6 @@ export default class GeneratedHostCatalogModel extends BaseModel {
|
||||
// AWS specific
|
||||
|
||||
@attr('string', {
|
||||
for: 'plugin',
|
||||
description:
|
||||
'An expression used to filter the workers that have network access to a service that is hosting the external object store.',
|
||||
})
|
||||
@@ -78,6 +77,7 @@ export default class GeneratedHostCatalogModel extends BaseModel {
|
||||
})
|
||||
region;
|
||||
|
||||
// AWS static credentials
|
||||
@attr('string', {
|
||||
isNestedSecret: true,
|
||||
description: '',
|
||||
@@ -90,6 +90,31 @@ export default class GeneratedHostCatalogModel extends BaseModel {
|
||||
})
|
||||
secret_access_key;
|
||||
|
||||
// AWS dynamic credentials
|
||||
@attr('string', {
|
||||
isNestedAttribute: true,
|
||||
description: 'The role ARN to use.',
|
||||
})
|
||||
role_arn;
|
||||
|
||||
@attr('string', {
|
||||
isNestedAttribute: true,
|
||||
description: 'The role external ID to use.',
|
||||
})
|
||||
role_external_id;
|
||||
|
||||
@attr('string', {
|
||||
isNestedAttribute: true,
|
||||
description: 'The role session to use.',
|
||||
})
|
||||
role_session_name;
|
||||
|
||||
@attr('object-as-array', {
|
||||
isNestedAttribute: true,
|
||||
description: 'The role tags to use.',
|
||||
})
|
||||
role_tags;
|
||||
|
||||
// Azure specific
|
||||
|
||||
@attr('string', {
|
||||
|
||||
@@ -19,9 +19,18 @@ export const TYPES_HOST_CATALOG_PLUGIN = [
|
||||
TYPE_HOST_CATALOG_PLUGIN_AZURE,
|
||||
];
|
||||
|
||||
export const TYPE_CREDENTIAL_STATIC = 'static-credential';
|
||||
export const TYPE_CREDENTIAL_DYNAMIC = 'dynamic-credential';
|
||||
|
||||
export const TYPES_CREDENTIALS = Object.freeze([
|
||||
TYPE_CREDENTIAL_STATIC,
|
||||
TYPE_CREDENTIAL_DYNAMIC,
|
||||
]);
|
||||
|
||||
export default class HostCatalogModel extends GeneratedHostCatalogModel {
|
||||
// =attributes
|
||||
|
||||
#credentialType;
|
||||
/**
|
||||
* True if the host catalog is static.
|
||||
* @type {boolean}
|
||||
@@ -38,6 +47,29 @@ export default class HostCatalogModel extends GeneratedHostCatalogModel {
|
||||
return this.type === 'plugin';
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a value from credentialType
|
||||
* @type {string}
|
||||
*/
|
||||
get credentialType() {
|
||||
if (!this.#credentialType) {
|
||||
if (this.role_arn) {
|
||||
this.#credentialType = TYPE_CREDENTIAL_DYNAMIC;
|
||||
} else {
|
||||
this.#credentialType = TYPE_CREDENTIAL_STATIC;
|
||||
}
|
||||
}
|
||||
return this.#credentialType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a value to credentialType
|
||||
* @type {string}
|
||||
*/
|
||||
set credentialType(type) {
|
||||
this.#credentialType = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* True if the host catalog is an unknown type.
|
||||
* @type {boolean}
|
||||
|
||||
@@ -4,30 +4,53 @@
|
||||
*/
|
||||
|
||||
import ApplicationSerializer from './application';
|
||||
import {
|
||||
TYPE_HOST_CATALOG_PLUGIN_AWS,
|
||||
TYPE_HOST_CATALOG_PLUGIN_AZURE,
|
||||
} from '../models/host-catalog';
|
||||
|
||||
const fieldsByType = {
|
||||
aws: [
|
||||
'disable_credential_rotation',
|
||||
'region',
|
||||
// These fields are Azure specific
|
||||
const azureFields = [
|
||||
'disable_credential_rotation',
|
||||
'tenant_id',
|
||||
'client_id',
|
||||
'subscription_id',
|
||||
'secret_id',
|
||||
'secret_value',
|
||||
];
|
||||
|
||||
// These fields are AWS specific, AWS provider now has two credentialTypes: static and dynamic [not to be confused with static and dynamic host-catalogs]
|
||||
const AWSfieldsWithCredentialType = {
|
||||
'static-credential': [
|
||||
'access_key_id',
|
||||
'secret_access_key',
|
||||
'region',
|
||||
'disable_credential_rotation',
|
||||
'worker_filter',
|
||||
],
|
||||
azure: [
|
||||
'dynamic-credential': [
|
||||
'role_arn',
|
||||
'role_external_id',
|
||||
'role_session_name',
|
||||
'role_tags',
|
||||
'region',
|
||||
'disable_credential_rotation',
|
||||
'tenant_id',
|
||||
'client_id',
|
||||
'subscription_id',
|
||||
'secret_id',
|
||||
'secret_value',
|
||||
'worker_filter',
|
||||
],
|
||||
};
|
||||
|
||||
export default class HostCatalogSerializer extends ApplicationSerializer {
|
||||
// =methods
|
||||
serialize(snapshot) {
|
||||
const { compositeType } = snapshot.record;
|
||||
const serialized = super.serialize(...arguments);
|
||||
switch (snapshot.record.compositeType) {
|
||||
|
||||
// This is a hack to remove the worker_filter field from the serialized data if the compositeType is not AWS
|
||||
// Ideally we should refactor the model to include the compositeType using `for` attribute
|
||||
if (compositeType !== TYPE_HOST_CATALOG_PLUGIN_AWS) {
|
||||
delete serialized.worker_filter;
|
||||
}
|
||||
|
||||
switch (compositeType) {
|
||||
case 'static':
|
||||
return this.serializeStatic(...arguments);
|
||||
default:
|
||||
@@ -37,31 +60,28 @@ export default class HostCatalogSerializer extends ApplicationSerializer {
|
||||
|
||||
serializeAttribute(snapshot, json, key, attribute) {
|
||||
const value = super.serializeAttribute(...arguments);
|
||||
const { isPlugin, compositeType } = snapshot.record;
|
||||
const { compositeType, credentialType, isPlugin } = snapshot.record;
|
||||
const { options } = attribute;
|
||||
|
||||
// Delete any fields that don't belong to the compositeType
|
||||
if (
|
||||
isPlugin &&
|
||||
json &&
|
||||
options?.for &&
|
||||
!options.for.includes(compositeType) &&
|
||||
!fieldsByType[compositeType].includes(key)
|
||||
) {
|
||||
delete json[key];
|
||||
}
|
||||
const fields =
|
||||
compositeType === TYPE_HOST_CATALOG_PLUGIN_AZURE
|
||||
? azureFields
|
||||
: AWSfieldsWithCredentialType[credentialType];
|
||||
|
||||
// Delete any nested attribute fields that don't belong to the record type
|
||||
if (isPlugin && options.isNestedAttribute && json.attributes) {
|
||||
if (!fieldsByType[compositeType].includes(key)) {
|
||||
if (!fields.includes(key)) {
|
||||
delete json.attributes[key];
|
||||
}
|
||||
}
|
||||
|
||||
// Delete any secret fields that don't belong to the record type
|
||||
if (isPlugin && options.isNestedSecret && json.secrets) {
|
||||
if (!fieldsByType[compositeType].includes(key)) {
|
||||
if (!fields.includes(key)) {
|
||||
delete json.secrets[key];
|
||||
if (json['secrets'] && Object.keys(json.secrets).length === 0) {
|
||||
delete json.secrets;
|
||||
}
|
||||
}
|
||||
}
|
||||
return value;
|
||||
@@ -72,6 +92,7 @@ export default class HostCatalogSerializer extends ApplicationSerializer {
|
||||
// Delete unnecessary fields for static host-catalog
|
||||
delete serialized.attributes;
|
||||
delete serialized.secrets;
|
||||
delete serialized.worker_filter;
|
||||
return serialized;
|
||||
}
|
||||
}
|
||||
@@ -5,6 +5,11 @@
|
||||
|
||||
import { module, test } from 'qunit';
|
||||
import { setupTest } from 'ember-qunit';
|
||||
import {
|
||||
TYPE_HOST_CATALOG_PLUGIN_AWS,
|
||||
TYPE_CREDENTIAL_STATIC,
|
||||
TYPE_CREDENTIAL_DYNAMIC,
|
||||
} from 'api/models/host-catalog';
|
||||
|
||||
module('Unit | Serializer | host catalog', function (hooks) {
|
||||
setupTest(hooks);
|
||||
@@ -31,15 +36,104 @@ module('Unit | Serializer | host catalog', function (hooks) {
|
||||
assert.deepEqual(record.serialize(), expectedResult);
|
||||
});
|
||||
|
||||
test('it serializes a new aws plugin as expected, ignoring azure fields', async function (assert) {
|
||||
test('it serializes a new aws static plugin as expected', async function (assert) {
|
||||
const store = this.owner.lookup('service:store');
|
||||
const record = store.createRecord('host-catalog', {
|
||||
compositeType: 'aws',
|
||||
compositeType: TYPE_HOST_CATALOG_PLUGIN_AWS,
|
||||
credentialType: TYPE_CREDENTIAL_STATIC,
|
||||
name: 'AWS',
|
||||
description: 'this is a Aws plugin host-catalog',
|
||||
disable_credential_rotation: true,
|
||||
worker_filter: 'workerfilter',
|
||||
// these are AWS fields and should be included
|
||||
region: 'west',
|
||||
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',
|
||||
role_arn: 'test',
|
||||
role_external_id: 'test',
|
||||
role_session_name: 'test',
|
||||
role_tags: [
|
||||
{ key: 'Project', value: 'Automation' },
|
||||
{ key: 'foo', value: 'bar' },
|
||||
],
|
||||
});
|
||||
const expectedResult = {
|
||||
name: 'AWS',
|
||||
description: 'this is a Aws plugin host-catalog',
|
||||
type: 'plugin',
|
||||
worker_filter: 'workerfilter',
|
||||
attributes: {
|
||||
disable_credential_rotation: true,
|
||||
region: 'west',
|
||||
},
|
||||
secrets: {
|
||||
access_key_id: 'foobars',
|
||||
secret_access_key: 'testing',
|
||||
},
|
||||
};
|
||||
assert.deepEqual(record.serialize(), expectedResult);
|
||||
});
|
||||
|
||||
test('it serializes a new aws dynamic plugin as expected', async function (assert) {
|
||||
const store = this.owner.lookup('service:store');
|
||||
const record = store.createRecord('host-catalog', {
|
||||
compositeType: TYPE_HOST_CATALOG_PLUGIN_AWS,
|
||||
name: 'AWS',
|
||||
credentialType: TYPE_CREDENTIAL_DYNAMIC,
|
||||
description: 'this is a Aws plugin host-catalog',
|
||||
disable_credential_rotation: true,
|
||||
worker_filter: 'workerfilter',
|
||||
// these are AWS fields and should be included
|
||||
region: 'west',
|
||||
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',
|
||||
role_arn: 'test',
|
||||
role_external_id: 'test',
|
||||
role_session_name: 'test',
|
||||
role_tags: [
|
||||
{ key: 'Project', value: 'Automation' },
|
||||
{ key: 'foo', value: 'bar' },
|
||||
],
|
||||
});
|
||||
const expectedResult = {
|
||||
name: 'AWS',
|
||||
description: 'this is a Aws plugin host-catalog',
|
||||
type: 'plugin',
|
||||
worker_filter: 'workerfilter',
|
||||
attributes: {
|
||||
disable_credential_rotation: true,
|
||||
region: 'west',
|
||||
role_external_id: 'test',
|
||||
role_session_name: 'test',
|
||||
role_arn: 'test',
|
||||
role_tags: { Project: 'Automation', foo: 'bar' },
|
||||
},
|
||||
};
|
||||
assert.deepEqual(record.serialize(), expectedResult);
|
||||
});
|
||||
|
||||
test('it serializes a new aws static plugin as expected, ignoring azure fields', async function (assert) {
|
||||
const store = this.owner.lookup('service:store');
|
||||
const record = store.createRecord('host-catalog', {
|
||||
compositeType: TYPE_HOST_CATALOG_PLUGIN_AWS,
|
||||
name: 'AWS',
|
||||
credentialType: TYPE_CREDENTIAL_STATIC,
|
||||
description: 'this is a Aws plugin host-catalog',
|
||||
disable_credential_rotation: true,
|
||||
worker_filter: 'workerfilter',
|
||||
// these are AWS fields and should be included
|
||||
region: 'spain',
|
||||
access_key_id: 'foobars',
|
||||
secret_access_key: 'testing',
|
||||
@@ -109,6 +203,7 @@ module('Unit | Serializer | host catalog', function (hooks) {
|
||||
data: {
|
||||
id: '1',
|
||||
type: 'host-catalog',
|
||||
credentialType: 'static',
|
||||
attributes: {
|
||||
type: 'plugin',
|
||||
name: 'aws',
|
||||
|
||||
@@ -218,6 +218,17 @@ host-catalog:
|
||||
aws: AWS
|
||||
azure: Azure
|
||||
plugin: Dynamic
|
||||
credential:
|
||||
label: Credential type
|
||||
help: Select the credential type that you want to use.
|
||||
static-credential:
|
||||
edit: Static Credentials
|
||||
label: Use an access key (Static Credentials)
|
||||
help: Use an access key that you have generated in AWS to use with this AWS Host Catalog.
|
||||
dynamic-credential:
|
||||
edit: Dynamic Credentials
|
||||
label: Use Assume Role (Dynamic Credentials)
|
||||
help: Specify an Assume Role used to generate credentials to use with this AWS Host Catalog.
|
||||
form:
|
||||
aws_region:
|
||||
label: AWS Region
|
||||
|
||||
@@ -19,12 +19,18 @@
|
||||
{{on 'input' (set-from-event @model 'name')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'form.name.label'}}</F.Label>
|
||||
<F.HelperText>{{t 'form.name.help'}}</F.HelperText>
|
||||
<F.Label>
|
||||
{{t 'form.name.label'}}
|
||||
</F.Label>
|
||||
<F.HelperText>
|
||||
{{t 'form.name.help'}}
|
||||
</F.HelperText>
|
||||
{{#if @model.errors.name}}
|
||||
<F.Error as |E|>
|
||||
{{#each @model.errors.name as |error|}}
|
||||
<E.Message>{{error.message}}</E.Message>
|
||||
<E.Message>
|
||||
{{error.message}}
|
||||
</E.Message>
|
||||
{{/each}}
|
||||
</F.Error>
|
||||
{{/if}}
|
||||
@@ -38,21 +44,28 @@
|
||||
disabled={{form.disabled}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'form.description.label'}}</F.Label>
|
||||
<F.HelperText>{{t 'form.description.help'}}</F.HelperText>
|
||||
<F.Label>
|
||||
{{t 'form.description.label'}}
|
||||
</F.Label>
|
||||
<F.HelperText>
|
||||
{{t 'form.description.help'}}
|
||||
</F.HelperText>
|
||||
{{#if @model.errors.description}}
|
||||
<F.Error as |E|>
|
||||
{{#each @model.errors.description as |error|}}
|
||||
<E.Message>{{error.message}}</E.Message>
|
||||
<E.Message>
|
||||
{{error.message}}
|
||||
</E.Message>
|
||||
{{/each}}
|
||||
</F.Error>
|
||||
{{/if}}
|
||||
</Hds::Form::Textarea::Field>
|
||||
|
||||
{{#if @model.isNew}}
|
||||
|
||||
<Hds::Form::RadioCard::Group @name='type' as |G|>
|
||||
<G.Legend>{{t 'form.type.label'}}</G.Legend>
|
||||
<G.Legend>
|
||||
{{t 'form.type.label'}}
|
||||
</G.Legend>
|
||||
{{#each this.hostCatalogTypes as |hostCatalogType|}}
|
||||
<G.RadioCard
|
||||
@value={{hostCatalogType}}
|
||||
@@ -61,19 +74,25 @@
|
||||
{{on 'input' (fn @changeType hostCatalogType)}}
|
||||
as |R|
|
||||
>
|
||||
<R.Label>{{t
|
||||
(concat 'resources.host-catalog.types.' hostCatalogType)
|
||||
}}</R.Label>
|
||||
<R.Description>{{t
|
||||
(concat 'resources.host-catalog.help.' hostCatalogType)
|
||||
}}</R.Description>
|
||||
<R.Label>
|
||||
{{t (concat 'resources.host-catalog.types.' hostCatalogType)}}
|
||||
</R.Label>
|
||||
<R.Description>
|
||||
{{t (concat 'resources.host-catalog.help.' hostCatalogType)}}
|
||||
</R.Description>
|
||||
</G.RadioCard>
|
||||
{{/each}}
|
||||
</Hds::Form::RadioCard::Group>
|
||||
<Hds::Form::RadioCard::Group @name='plugin_type' @alignment='center' as |G|>
|
||||
<G.Legend>{{t 'titles.provider'}}</G.Legend>
|
||||
<G.Legend>{{t 'titles.choose-a-provider'}}</G.Legend>
|
||||
<G.HelperText>{{t 'descriptions.choose-a-provider'}}</G.HelperText>
|
||||
<G.Legend>
|
||||
{{t 'titles.provider'}}
|
||||
</G.Legend>
|
||||
<G.Legend>
|
||||
{{t 'titles.choose-a-provider'}}
|
||||
</G.Legend>
|
||||
<G.HelperText>
|
||||
{{t 'descriptions.choose-a-provider'}}
|
||||
</G.HelperText>
|
||||
|
||||
{{#each-in this.mapResourceTypeWithIcon as |pluginType icon|}}
|
||||
<G.RadioCard
|
||||
@@ -83,11 +102,10 @@
|
||||
{{on 'input' (fn @changeType pluginType)}}
|
||||
as |R|
|
||||
>
|
||||
<R.Label>{{t
|
||||
(concat 'resources.host-catalog.types.' pluginType)
|
||||
}}</R.Label>
|
||||
<R.Label>
|
||||
{{t (concat 'resources.host-catalog.types.' pluginType)}}
|
||||
</R.Label>
|
||||
<R.Icon @name={{icon}} />
|
||||
|
||||
</G.RadioCard>
|
||||
{{/each-in}}
|
||||
</Hds::Form::RadioCard::Group>
|
||||
@@ -98,8 +116,11 @@
|
||||
readonly={{true}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'titles.provider'}}</F.Label>
|
||||
<F.HelperText>{{t 'descriptions.provider'}}
|
||||
<F.Label>
|
||||
{{t 'titles.provider'}}
|
||||
</F.Label>
|
||||
<F.HelperText>
|
||||
{{t 'descriptions.provider'}}
|
||||
</F.HelperText>
|
||||
</InfoField>
|
||||
{{/if}}
|
||||
@@ -112,7 +133,9 @@
|
||||
{{on 'input' (set-from-event @model 'region')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'resources.host-catalog.form.aws_region.label'}}</F.Label>
|
||||
<F.Label>
|
||||
{{t 'resources.host-catalog.form.aws_region.label'}}
|
||||
</F.Label>
|
||||
<F.HelperText>
|
||||
{{t 'resources.host-catalog.form.aws_region.help'}}
|
||||
<Hds::Link::Inline @href={{doc-url 'host-catalog.aws.region'}}>
|
||||
@@ -121,39 +144,225 @@
|
||||
</F.HelperText>
|
||||
</Hds::Form::TextInput::Field>
|
||||
|
||||
<Hds::Form::TextInput::Field
|
||||
name='access_key_id'
|
||||
@value={{@model.access_key_id}}
|
||||
@isRequired={{true}}
|
||||
disabled={{form.disabled}}
|
||||
{{on 'input' (set-from-event @model 'access_key_id')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'form.access_key_id.label'}}</F.Label>
|
||||
<F.HelperText>
|
||||
{{t 'form.access_key_id.help'}}
|
||||
<Hds::Link::Inline @href={{doc-url 'host-catalog.aws'}}>
|
||||
{{t 'actions.learn-more'}}
|
||||
</Hds::Link::Inline>
|
||||
</F.HelperText>
|
||||
</Hds::Form::TextInput::Field>
|
||||
{{#if @model.isNew}}
|
||||
<Hds::Form::Radio::Group @layout='vertical' @name='credential_type' as |G|>
|
||||
<G.Legend>
|
||||
{{t 'resources.host-catalog.types.credential.label'}}
|
||||
</G.Legend>
|
||||
<G.HelperText>
|
||||
{{t 'resources.host-catalog.types.credential.help'}}
|
||||
</G.HelperText>
|
||||
|
||||
<Hds::Form::TextInput::Field
|
||||
name='secret_access_key'
|
||||
@value={{@model.secret_access_key}}
|
||||
@isRequired={{true}}
|
||||
disabled={{form.disabled}}
|
||||
{{on 'input' (set-from-event @model 'secret_access_key')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'form.secret_access_key.label'}}</F.Label>
|
||||
<F.HelperText>
|
||||
{{t 'form.secret_access_key.help'}}
|
||||
<Hds::Link::Inline @href={{doc-url 'host-catalog.aws'}}>
|
||||
{{t 'actions.learn-more'}}
|
||||
</Hds::Link::Inline>
|
||||
</F.HelperText>
|
||||
</Hds::Form::TextInput::Field>
|
||||
{{#each this.credentials as |credentialType|}}
|
||||
<G.RadioField
|
||||
name={{credentialType}}
|
||||
@value={{credentialType}}
|
||||
checked={{eq credentialType this.selectedCredentialType}}
|
||||
disabled={{form.disabled}}
|
||||
{{on 'input' (fn this.updateCredentialTypeSelection credentialType)}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>
|
||||
{{t
|
||||
(concat
|
||||
'resources.host-catalog.types.credential.'
|
||||
credentialType
|
||||
'.label'
|
||||
)
|
||||
}}
|
||||
</F.Label>
|
||||
<F.HelperText>
|
||||
{{t
|
||||
(concat
|
||||
'resources.host-catalog.types.credential.'
|
||||
credentialType
|
||||
'.help'
|
||||
)
|
||||
}}
|
||||
</F.HelperText>
|
||||
</G.RadioField>
|
||||
{{/each}}
|
||||
</Hds::Form::Radio::Group>
|
||||
{{else}}
|
||||
<Hds::Form::Fieldset @layout='horizontal' as |F|>
|
||||
<F.Legend>
|
||||
{{t 'resources.host-catalog.types.credential.label'}}
|
||||
</F.Legend>
|
||||
<F.Control>
|
||||
<Hds::Badge
|
||||
@text={{t
|
||||
(concat
|
||||
'resources.host-catalog.types.credential.'
|
||||
this.selectedCredentialType
|
||||
'.edit'
|
||||
)
|
||||
}}
|
||||
/>
|
||||
</F.Control>
|
||||
</Hds::Form::Fieldset>
|
||||
{{/if}}
|
||||
|
||||
{{#if this.showDynamicCredentials}}
|
||||
{{! role_arn }}
|
||||
<Hds::Form::TextInput::Field
|
||||
name='role_arn'
|
||||
@isRequired={{true}}
|
||||
@value={{@model.role_arn}}
|
||||
@isInvalid={{@model.errors.role_arn}}
|
||||
disabled={{form.disabled}}
|
||||
{{on 'input' (set-from-event @model 'role_arn')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>
|
||||
{{t 'resources.storage-bucket.form.role_arn.label'}}
|
||||
</F.Label>
|
||||
<F.HelperText>
|
||||
{{t 'resources.storage-bucket.form.role_arn.help'}}
|
||||
</F.HelperText>
|
||||
{{#if @model.errors.role_arn}}
|
||||
<F.Error as |E|>
|
||||
{{#each @model.errors.role_arn as |error|}}
|
||||
<E.Message>
|
||||
{{error.message}}
|
||||
</E.Message>
|
||||
{{/each}}
|
||||
</F.Error>
|
||||
{{/if}}
|
||||
</Hds::Form::TextInput::Field>
|
||||
|
||||
{{! role_external_id }}
|
||||
<Hds::Form::TextInput::Field
|
||||
name='role_external_id'
|
||||
@isOptional={{true}}
|
||||
@value={{@model.role_external_id}}
|
||||
@isInvalid={{@model.errors.role_external_id}}
|
||||
disabled={{form.disabled}}
|
||||
{{on 'input' (set-from-event @model 'role_external_id')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>
|
||||
{{t 'resources.storage-bucket.form.role_external_id.label'}}
|
||||
</F.Label>
|
||||
<F.HelperText>
|
||||
{{t 'resources.storage-bucket.form.role_external_id.help'}}
|
||||
</F.HelperText>
|
||||
{{#if @model.errors.role_external_id}}
|
||||
<F.Error as |E|>
|
||||
{{#each @model.errors.role_external_id as |error|}}
|
||||
<E.Message>
|
||||
{{error.message}}
|
||||
</E.Message>
|
||||
{{/each}}
|
||||
</F.Error>
|
||||
{{/if}}
|
||||
</Hds::Form::TextInput::Field>
|
||||
|
||||
{{! role_session_name }}
|
||||
<Hds::Form::TextInput::Field
|
||||
name='role_session_name'
|
||||
@isOptional={{true}}
|
||||
@value={{@model.role_session_name}}
|
||||
@isInvalid={{@model.errors.role_session_name}}
|
||||
disabled={{form.disabled}}
|
||||
{{on 'input' (set-from-event @model 'role_session_name')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>
|
||||
{{t 'resources.storage-bucket.form.role_session_name.label'}}
|
||||
</F.Label>
|
||||
<F.HelperText>
|
||||
{{t 'resources.storage-bucket.form.role_session_name.help'}}
|
||||
</F.HelperText>
|
||||
{{#if @model.errors.role_session_name}}
|
||||
<F.Error as |E|>
|
||||
{{#each @model.errors.role_session_name as |error|}}
|
||||
<E.Message>
|
||||
{{error.message}}
|
||||
</E.Message>
|
||||
{{/each}}
|
||||
</F.Error>
|
||||
{{/if}}
|
||||
</Hds::Form::TextInput::Field>
|
||||
|
||||
{{! role_tags }}
|
||||
<Form::Field::ListWrapper
|
||||
@layout='horizontal'
|
||||
@isOptional={{true}}
|
||||
@disabled={{form.disabled}}
|
||||
>
|
||||
<:fieldset as |F|>
|
||||
<F.Legend>
|
||||
{{t 'resources.storage-bucket.form.role_tags.label'}}
|
||||
</F.Legend>
|
||||
<F.HelperText>
|
||||
{{t 'resources.storage-bucket.form.role_tags.help'}}
|
||||
</F.HelperText>
|
||||
|
||||
{{#if @model.errors.role_tags}}
|
||||
<F.Error as |E|>
|
||||
{{#each @model.errors.role_tags as |error|}}
|
||||
<E.Message>
|
||||
{{error.message}}
|
||||
</E.Message>
|
||||
{{/each}}
|
||||
</F.Error>
|
||||
{{/if}}
|
||||
</:fieldset>
|
||||
<:field as |F|>
|
||||
<F.KeyValue
|
||||
@name='role_tags'
|
||||
@options={{@model.role_tags}}
|
||||
@model={{@model}}
|
||||
>
|
||||
<:key as |K|>
|
||||
<K.text />
|
||||
</:key>
|
||||
<:value as |V|>
|
||||
<V.text />
|
||||
</:value>
|
||||
</F.KeyValue>
|
||||
</:field>
|
||||
</Form::Field::ListWrapper>
|
||||
|
||||
{{else}}
|
||||
<Hds::Form::TextInput::Field
|
||||
name='access_key_id'
|
||||
@value={{@model.access_key_id}}
|
||||
@isRequired={{true}}
|
||||
disabled={{form.disabled}}
|
||||
{{on 'input' (set-from-event @model 'access_key_id')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>
|
||||
{{t 'form.access_key_id.label'}}
|
||||
</F.Label>
|
||||
<F.HelperText>
|
||||
{{t 'form.access_key_id.help'}}
|
||||
<Hds::Link::Inline @href={{doc-url 'host-catalog.aws'}}>
|
||||
{{t 'actions.learn-more'}}
|
||||
</Hds::Link::Inline>
|
||||
</F.HelperText>
|
||||
</Hds::Form::TextInput::Field>
|
||||
|
||||
<Hds::Form::TextInput::Field
|
||||
name='secret_access_key'
|
||||
@value={{@model.secret_access_key}}
|
||||
@isRequired={{true}}
|
||||
disabled={{form.disabled}}
|
||||
{{on 'input' (set-from-event @model 'secret_access_key')}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>
|
||||
{{t 'form.secret_access_key.label'}}
|
||||
</F.Label>
|
||||
<F.HelperText>
|
||||
{{t 'form.secret_access_key.help'}}
|
||||
<Hds::Link::Inline @href={{doc-url 'host-catalog.aws'}}>
|
||||
{{t 'actions.learn-more'}}
|
||||
</Hds::Link::Inline>
|
||||
</F.HelperText>
|
||||
</Hds::Form::TextInput::Field>
|
||||
{{/if}}
|
||||
|
||||
<Hds::Form::Textarea::Field
|
||||
name='worker_filter'
|
||||
@@ -175,7 +384,9 @@
|
||||
{{#if @model.errors.worker_filter}}
|
||||
<F.Error as |E|>
|
||||
{{#each @model.errors.worker_filter as |error|}}
|
||||
<E.Message>{{error.message}}</E.Message>
|
||||
<E.Message>
|
||||
{{error.message}}
|
||||
</E.Message>
|
||||
{{/each}}
|
||||
</F.Error>
|
||||
{{/if}}
|
||||
@@ -188,7 +399,9 @@
|
||||
{{on 'change' (fn this.toggleDisableCredentialRotation @model)}}
|
||||
as |F|
|
||||
>
|
||||
<F.Label>{{t 'form.disable_credential_rotation.label'}}</F.Label>
|
||||
<F.Label>
|
||||
{{t 'form.disable_credential_rotation.label'}}
|
||||
</F.Label>
|
||||
</Hds::Form::Checkbox::Field>
|
||||
|
||||
|
||||
|
||||
@@ -8,7 +8,10 @@ import { action } from '@ember/object';
|
||||
import {
|
||||
TYPES_HOST_CATALOG,
|
||||
TYPES_HOST_CATALOG_PLUGIN,
|
||||
TYPES_CREDENTIALS,
|
||||
TYPE_CREDENTIAL_DYNAMIC,
|
||||
} from 'api/models/host-catalog';
|
||||
import { tracked } from '@glimmer/tracking';
|
||||
|
||||
//Note: this is a temporary solution till we have resource type helper in place
|
||||
const icons = ['aws-color', 'azure-color'];
|
||||
@@ -16,6 +19,21 @@ const icons = ['aws-color', 'azure-color'];
|
||||
export default class FormHostCatalogAwsComponent extends Component {
|
||||
// =properties
|
||||
hostCatalogTypes = TYPES_HOST_CATALOG;
|
||||
|
||||
// =attributes
|
||||
@tracked selectedCredentialType = this.args.model.credentialType;
|
||||
|
||||
@tracked showDynamicCredentials =
|
||||
this.args.model.credentialType === TYPE_CREDENTIAL_DYNAMIC;
|
||||
|
||||
/**
|
||||
* returns an array of available credential types
|
||||
* @type {array}
|
||||
*/
|
||||
get credentials() {
|
||||
return TYPES_CREDENTIALS;
|
||||
}
|
||||
|
||||
/**
|
||||
* maps resource type with icon
|
||||
* @type {object}
|
||||
@@ -32,4 +50,19 @@ export default class FormHostCatalogAwsComponent extends Component {
|
||||
toggleDisableCredentialRotation(model) {
|
||||
model.disable_credential_rotation = !model.disable_credential_rotation;
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows to update the credential type
|
||||
* @param type {string}
|
||||
*/
|
||||
@action
|
||||
updateCredentialTypeSelection(type) {
|
||||
this.selectedCredentialType = type;
|
||||
if (type === TYPE_CREDENTIAL_DYNAMIC) {
|
||||
this.showDynamicCredentials = true;
|
||||
} else {
|
||||
this.showDynamicCredentials = false;
|
||||
}
|
||||
this.args.changeCredentialType(type);
|
||||
}
|
||||
}
|
||||
@@ -9,4 +9,5 @@
|
||||
submit=@submit
|
||||
cancel=@cancel
|
||||
changeType=@changeType
|
||||
changeCredentialType=@changeCredentialType
|
||||
}}
|
||||
@@ -424,7 +424,7 @@
|
||||
{{t 'resources.storage-bucket.form.role_tags.label'}}
|
||||
</F.Legend>
|
||||
<F.HelperText>
|
||||
{{t 'resources.storage-bucket.form.role_tags.label'}}
|
||||
{{t 'resources.storage-bucket.form.role_tags.help'}}
|
||||
</F.HelperText>
|
||||
|
||||
{{#if @model.errors.role_tags}}
|
||||
@@ -436,11 +436,18 @@
|
||||
{{/if}}
|
||||
</:fieldset>
|
||||
<:field as |F|>
|
||||
<F.TextInput
|
||||
<F.KeyValue
|
||||
@name='role_tags'
|
||||
@options={{@model.role_tags}}
|
||||
@model={{@model}}
|
||||
/>
|
||||
>
|
||||
<:key as |K|>
|
||||
<K.text />
|
||||
</:key>
|
||||
<:value as |V|>
|
||||
<V.text />
|
||||
</:value>
|
||||
</F.KeyValue>
|
||||
</:field>
|
||||
</Form::Field::ListWrapper>
|
||||
{{/if}}
|
||||
|
||||
@@ -99,4 +99,14 @@ export default class ScopesScopeHostCatalogsIndexController extends Controller {
|
||||
if (type === 'plugin') type = 'aws';
|
||||
this.router.replaceWith({ queryParams: { type } });
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates credential type
|
||||
* @param {model} hostcatalog
|
||||
* @param {string} credentialType
|
||||
*/
|
||||
@action
|
||||
changeCredentialType(hostCatalog, credentialType) {
|
||||
hostCatalog.credentialType = credentialType;
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,7 @@
|
||||
@submit={{fn this.hostCatalogs.save @model}}
|
||||
@cancel={{fn this.hostCatalogs.cancel @model}}
|
||||
@changeType={{this.hostCatalogs.changeType}}
|
||||
@changeCredentialType={{fn this.hostCatalogs.changeCredentialType @model}}
|
||||
/>
|
||||
</page.body>
|
||||
|
||||
|
||||
Reference in new issue
Block a user