MinIO support for Admin UI (#2248)

Add support for MinIO creation form and list
This commit is contained in:
Carlos Alcaide Corvo authored and GitHub committed 2024-04-16 14:17:23 -07:00
1 parent 98c16ad422
commit 0870a8f623
26 files changed
+1332 -597

No files matched your search

@@ -0,0 +1,491 @@
<Rose::Form
@onSubmit={{@submit}}
@cancel={{@cancel}}
@disabled={{@model.isSaving}}
@showEditToggle={{if @model.isNew false true}}
as |form|
>
{{! name }}
<Hds::Form::TextInput::Field
name='name'
@isOptional={{true}}
@value={{@model.name}}
@isInvalid={{@model.errors.name}}
@type='text'
disabled={{form.disabled}}
{{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>
{{#if @model.errors.name}}
<F.Error as |E|>
{{#each @model.errors.name as |error|}}
<E.Message>{{error.message}}</E.Message>
{{/each}}
</F.Error>
{{/if}}
</Hds::Form::TextInput::Field>
{{! description }}
<Hds::Form::Textarea::Field
name='description'
@isOptional={{true}}
@value={{@model.description}}
@isInvalid={{@model.errors.description}}
disabled={{form.disabled}}
as |F|
>
<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>
{{/each}}
</F.Error>
{{/if}}
</Hds::Form::Textarea::Field>
{{! scope }}
{{#if @model.isNew}}
<Hds::Form::Select::Field
name='scope'
@isRequired={{true}}
@width='100%'
disabled={{form.disabled}}
{{on 'change' @updateScope}}
as |F|
>
<F.Label>{{t 'resources.storage-bucket.form.scope.label'}}</F.Label>
<F.HelperText>
{{#if @model.scope}}
{{#if @model.scope.isGlobal}}
{{t 'resources.storage-bucket.form.scope.help_global'}}
{{else if @model.scope.isOrg}}
{{t 'resources.storage-bucket.form.scope.help_org'}}
{{/if}}
{{else}}
{{t 'resources.storage-bucket.form.scope.help'}}
{{/if}}
</F.HelperText>
<F.Options>
<option disabled selected={{not @model.scope}} value=''>
{{t 'titles.choose-an-option'}}
</option>
{{#each @scopes as |scope|}}
<option
value={{scope.model.id}}
selected={{eq scope.model.id @model.scope.scope_id}}
>
{{scope.model.displayName}}
</option>
{{/each}}
</F.Options>
</Hds::Form::Select::Field>
{{else}}
<InfoField
@value={{@model.scopeModel.displayName}}
@icon={{if @model.scopeModel.isGlobal 'globe' 'org'}}
disabled={{form.disabled}}
as |F|
>
<F.Label>{{t 'resources.storage-bucket.form.scope.label'}}</F.Label>
<F.HelperText>
{{#if @model.scopeModel.isGlobal}}
{{t 'resources.storage-bucket.form.scope.help_global'}}
{{else}}
{{t 'resources.storage-bucket.form.scope.help_org'}}
{{/if}}
</F.HelperText>
</InfoField>
{{/if}}
{{! Provider / plugin.name }}
<Hds::Form::RadioCard::Group @name='plugin_type' @alignment='center' as |G|>
<G.Legend>{{t 'titles.provider'}}</G.Legend>
<G.HelperText>{{t 'descriptions.choose-a-provider'}}</G.HelperText>
{{#each @pluginTypes as |pluginType|}}
<G.RadioCard
@value={{pluginType}}
@checked={{eq pluginType @model.compositeType}}
@disabled={{(not @model.isNew)}}
{{on 'input' (fn @changePluginType pluginType)}}
as |R|
>
<R.Label>{{t
(concat 'resources.storage-bucket.plugin-types.' pluginType)
}}</R.Label>
{{#if (eq pluginType 'aws')}}
<R.Icon @name='aws-color' />
{{else}}
<R.Icon @name='cloud-upload' />
{{/if}}
</G.RadioCard>
{{/each}}
</Hds::Form::RadioCard::Group>
{{! bucket_name }}
<Hds::Form::TextInput::Field
name='bucket_name'
@isRequired={{true}}
@value={{@model.bucket_name}}
@isInvalid={{@model.errors.bucket_name}}
disabled={{form.disabled}}
readOnly={{not @model.isNew}}
{{on 'input' (set-from-event @model 'bucket_name')}}
as |F|
>
<F.Label>{{t 'resources.storage-bucket.form.bucket_name.label'}}</F.Label>
<F.HelperText>{{t
'resources.storage-bucket.form.bucket_name.help'
}}</F.HelperText>
{{#if @model.errors.bucket_name}}
<F.Error as |E|>
{{#each @model.errors.bucket_name as |error|}}
<E.Message>{{error.message}}</E.Message>
{{/each}}
</F.Error>
{{/if}}
</Hds::Form::TextInput::Field>
{{! bucket_prefix }}
<Hds::Form::TextInput::Field
name='bucket_prefix'
@isOptional={{true}}
@value={{@model.bucket_prefix}}
@isInvalid={{@model.errors.bucket_prefix}}
disabled={{form.disabled}}
readOnly={{not @model.isNew}}
{{on 'input' (set-from-event @model 'bucket_prefix')}}
as |F|
>
<F.Label>{{t 'resources.storage-bucket.form.bucket_prefix.label'}}</F.Label>
<F.HelperText>{{t
'resources.storage-bucket.form.bucket_prefix.help'
}}</F.HelperText>
{{#if @model.errors.bucket_prefix}}
<F.Error as |E|>
{{#each @model.errors.bucket_prefix as |error|}}
<E.Message>{{error.message}}</E.Message>
{{/each}}
</F.Error>
{{/if}}
</Hds::Form::TextInput::Field>
{{! region }}
<Hds::Form::TextInput::Field
name='region'
@isRequired={{true}}
@value={{@model.region}}
@isInvalid={{@model.errors.region}}
disabled={{form.disabled}}
readOnly={{not @model.isNew}}
{{on 'input' (set-from-event @model 'region')}}
as |F|
>
<F.Label>{{t 'resources.storage-bucket.form.region.label'}}</F.Label>
<F.HelperText>{{t
'resources.storage-bucket.form.region.help'
}}</F.HelperText>
{{#if @model.errors.region}}
<F.Error as |E|>
{{#each @model.errors.region as |error|}}
<E.Message>{{error.message}}</E.Message>
{{/each}}
</F.Error>
{{/if}}
</Hds::Form::TextInput::Field>
{{! credential_type }}
<Hds::Form::RadioCard::Group name='credential_type' as |G|>
<G.Legend>{{t 'resources.storage-bucket.types.credential'}}</G.Legend>
{{#each this.credentials as |credentialType|}}
<G.RadioCard
@name={{credentialType}}
@value={{credentialType}}
@checked={{eq credentialType this.selectedCredentialType}}
@disabled={{form.disabled}}
{{on 'input' (fn this.updateCredentialTypeSelection credentialType)}}
as |R|
>
<R.Label>{{t
(concat 'resources.storage-bucket.types.' credentialType '.title')
}}</R.Label>
<R.Description>{{t
(concat
'resources.storage-bucket.types.' credentialType '.description'
)
}}</R.Description>
</G.RadioCard>
{{/each}}
</Hds::Form::RadioCard::Group>
{{! static credentials fields }}
{{#unless this.showDynamicCredentials}}
{{! Creation }}
{{#if @model.isNew}}
{{! access_key }}
<Hds::Form::TextInput::Field
name='access_key_id'
@type='password'
@isRequired={{true}}
@value={{@model.access_key_id}}
@isInvalid={{@model.errors.secrets}}
@hasVisibilityToggle={{false}}
{{on 'input' (set-from-event @model 'access_key_id')}}
as |F|
>
<F.Label>{{t
'resources.storage-bucket.form.access_key_id.label'
}}</F.Label>
<F.HelperText>{{t
'resources.storage-bucket.form.access_key_id.help'
}}</F.HelperText>
{{#if @model.errors.secrets}}
<F.Error as |E|>
{{#each @model.errors.secrets as |error|}}
<E.Message>{{error.message}}</E.Message>
{{/each}}
</F.Error>
{{/if}}
</Hds::Form::TextInput::Field>
{{! secret_access_key }}
<Hds::Form::TextInput::Field
name='secret_access_key'
@type='password'
@isRequired={{true}}
@value={{@model.secret_access_key}}
@isInvalid={{@model.errors.secrets}}
disabled={{form.disabled}}
@hasVisibilityToggle={{false}}
{{on 'input' (set-from-event @model 'secret_access_key')}}
as |F|
>
<F.Label>{{t
'resources.storage-bucket.form.secret_access_key.label'
}}</F.Label>
<F.HelperText>{{t
'resources.storage-bucket.form.secret_access_key.help'
}}</F.HelperText>
{{#if @model.errors.secrets}}
<F.Error as |E|>
{{#each @model.errors.secrets as |error|}}
<E.Message>{{error.message}}</E.Message>
{{/each}}
</F.Error>
{{/if}}
</Hds::Form::TextInput::Field>
{{! Edit }}
{{else}}
{{! access_key }}
<Form::Field::SecretInput
@name='access_key_id'
@isRequired={{true}}
@value={{@model.access_key_id}}
@isInvalid={{@model.errors.access_key_id}}
@isDisabled={{form.disabled}}
@showEditButton={{true}}
@cancel={{fn @rollbackSecretAttrs 'access_key_id'}}
{{on 'input' (set-from-event @model 'access_key_id')}}
as |F|
>
<F.Label>{{t
'resources.storage-bucket.form.access_key_id.label'
}}</F.Label>
<F.HelperText>{{t
'resources.storage-bucket.form.access_key_id.help'
}}</F.HelperText>
</Form::Field::SecretInput>
{{! secret_access_key }}
<Form::Field::SecretInput
@name='secret_access_key'
@isRequired={{true}}
@value={{@model.secret_access_key}}
@isInvalid={{@model.errors.secret_access_key}}
@isDisabled={{form.disabled}}
@showEditButton={{true}}
@cancel={{fn @rollbackSecretAttrs 'secret_access_key'}}
{{on 'input' (set-from-event @model 'secret_access_key')}}
as |F|
>
<F.Label>{{t
'resources.storage-bucket.form.secret_access_key.label'
}}</F.Label>
<F.HelperText>{{t
'resources.storage-bucket.form.secret_access_key.help'
}}</F.HelperText>
</Form::Field::SecretInput>
{{/if}}
{{/unless}}
{{! dynamic credentials }}
{{#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.label'}}
</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.TextInput
@name='role_tags'
@options={{@model.role_tags}}
@model={{@model}}
/>
</:field>
</Form::Field::ListWrapper>
{{/if}}
{{! worker_filter }}
<Hds::Form::TextInput::Field
name='worker_filter'
@isRequired={{true}}
@value={{@model.worker_filter}}
@isInvalid={{@model.errors.worker_filter}}
disabled={{form.disabled}}
{{on 'input' (set-from-event @model 'worker_filter')}}
as |F|
>
<F.Label>{{t 'resources.storage-bucket.form.worker_filter.label'}}</F.Label>
<F.HelperText>
{{t 'resources.storage-bucket.form.worker_filter.help'}}
<Hds::Link::Inline @href={{doc-url 'storage-bucket.worker-filter'}}>
{{t 'actions.learn-more'}}
</Hds::Link::Inline>
</F.HelperText>
{{#if @model.errors.worker_filter}}
<F.Error as |E|>
{{#each @model.errors.worker_filter as |error|}}
<E.Message>{{error.message}}</E.Message>
{{/each}}
</F.Error>
{{/if}}
</Hds::Form::TextInput::Field>
{{! JUST for static credentials }}
{{#unless this.showDynamicCredentials}}
{{! disable_credential_rotation }}
<Hds::Form::Checkbox::Field
name='disable_credential_rotation'
disabled={{form.disabled}}
checked={{@model.disable_credential_rotation}}
{{on 'change' @toggleDisableCredentialRotation}}
as |F|
>
<F.Label>{{t
'resources.storage-bucket.form.disable_credential_rotation.label'
}}</F.Label>
<F.HelperText>
{{t 'resources.storage-bucket.form.disable_credential_rotation.help'}}
<Hds::Link::Inline
@href={{doc-url 'storage-bucket.disable-credential-rotation'}}
>
{{t 'actions.learn-more'}}
</Hds::Link::Inline>
</F.HelperText>
</Hds::Form::Checkbox::Field>
{{/unless}}
{{! Actions }}
{{#if (can 'save model' @model)}}
<form.actions
@enableEditText={{t 'actions.edit-form'}}
@submitText={{t 'actions.save'}}
@cancelText={{t 'actions.cancel'}}
/>
{{/if}}
</Rose::Form>
@@ -0,0 +1,38 @@
import Component from '@glimmer/component';
import { action } from '@ember/object';
import {
TYPES_CREDENTIALS,
TYPE_CREDENTIAL_DYNAMIC,
} from 'api/models/storage-bucket';
import { tracked } from '@glimmer/tracking';
export default class FormStorageBucketAwsIndexComponent extends Component {
// =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;
}
// =actions
/**
* 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);
}
}
@@ -2,455 +2,18 @@
Copyright (c) HashiCorp, Inc.
SPDX-License-Identifier: MPL-2.0
}}
<Rose::Form
@onSubmit={{@submit}}
@cancel={{this.cancel}}
@disabled={{@model.isSaving}}
@showEditToggle={{if @model.isNew false true}}
as |form|
>
<Hds::Form::TextInput::Field
@isOptional={{true}}
@value={{@model.name}}
@isInvalid={{@model.errors.name}}
@type='text'
name='name'
disabled={{form.disabled}}
{{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>
{{#if @model.errors.name}}
<F.Error as |E|>
{{#each @model.errors.name as |error|}}
<E.Message>{{error.message}}</E.Message>
{{/each}}
</F.Error>
{{/if}}
</Hds::Form::TextInput::Field>
<Hds::Form::Textarea::Field
@isOptional={{true}}
@value={{@model.description}}
@isInvalid={{@model.errors.description}}
name='description'
disabled={{form.disabled}}
as |F|
>
<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>
{{/each}}
</F.Error>
{{/if}}
</Hds::Form::Textarea::Field>
{{#if @model.isNew}}
<Hds::Form::Select::Field
@isRequired={{true}}
@width='100%'
disabled={{form.disabled}}
name='scope'
{{on 'change' this.updateScope}}
as |F|
>
<F.Label>{{t 'resources.storage-bucket.form.scope.label'}}</F.Label>
<F.HelperText>
{{this.scopeFieldDescription}}
</F.HelperText>
<F.Options>
<option disabled hidden selected value=''>
{{t 'titles.choose-an-option'}}
</option>
{{#each @scopes as |scope|}}
<option value={{scope.model.id}}>
{{scope.model.displayName}}
</option>
{{/each}}
</F.Options>
</Hds::Form::Select::Field>
{{else}}
<InfoField
@value={{@model.scopeModel.displayName}}
@icon={{if @model.scopeModel.isGlobal 'globe' 'org'}}
disabled={{form.disabled}}
as |F|
>
<F.Label>{{t 'resources.storage-bucket.form.scope.label'}}</F.Label>
<F.HelperText>
{{#if @model.scopeModel.isGlobal}}
{{t 'resources.storage-bucket.form.scope.help_global'}}
{{else}}
{{t 'resources.storage-bucket.form.scope.help_org'}}
{{/if}}
</F.HelperText>
</InfoField>
{{/if}}
<InfoField
@value={{t 'resources.storage-bucket.titles.amazon_s3'}}
@icon='aws-color'
disabled={{form.disabled}}
as |F|
>
<F.Label>{{t 'titles.provider'}}</F.Label>
<F.HelperText>{{t
'resources.storage-bucket.form.provider.help'
}}</F.HelperText>
</InfoField>
<Hds::Form::TextInput::Field
@isRequired={{true}}
@value={{@model.bucket_name}}
@isInvalid={{@model.errors.bucket_name}}
@type='text'
name='bucket_name'
disabled={{form.disabled}}
readOnly={{not @model.isNew}}
{{on 'input' (set-from-event @model 'bucket_name')}}
as |F|
>
<F.Label>{{t 'resources.storage-bucket.form.bucket_name.label'}}</F.Label>
<F.HelperText>{{t
'resources.storage-bucket.form.bucket_name.help'
}}</F.HelperText>
{{#if @model.errors.bucket_name}}
<F.Error as |E|>
{{#each @model.errors.bucket_name as |error|}}
<E.Message>{{error.message}}</E.Message>
{{/each}}
</F.Error>
{{/if}}
</Hds::Form::TextInput::Field>
<Hds::Form::TextInput::Field
@isOptional={{true}}
@value={{@model.bucket_prefix}}
@isInvalid={{@model.errors.bucket_prefix}}
@type='text'
name='bucket_prefix'
disabled={{form.disabled}}
readOnly={{not @model.isNew}}
{{on 'input' (set-from-event @model 'bucket_prefix')}}
as |F|
>
<F.Label>{{t 'resources.storage-bucket.form.bucket_prefix.label'}}</F.Label>
<F.HelperText>{{t
'resources.storage-bucket.form.bucket_prefix.help'
}}</F.HelperText>
{{#if @model.errors.bucket_prefix}}
<F.Error as |E|>
{{#each @model.errors.bucket_prefix as |error|}}
<E.Message>{{error.message}}</E.Message>
{{/each}}
</F.Error>
{{/if}}
</Hds::Form::TextInput::Field>
<Hds::Form::TextInput::Field
@isRequired={{true}}
@value={{@model.region}}
@isInvalid={{@model.errors.region}}
@type='text'
name='region'
disabled={{form.disabled}}
readOnly={{not @model.isNew}}
{{on 'input' (set-from-event @model 'region')}}
as |F|
>
<F.Label>{{t 'resources.storage-bucket.form.region.label'}}</F.Label>
<F.HelperText>{{t
'resources.storage-bucket.form.region.help'
}}</F.HelperText>
{{#if @model.errors.region}}
<F.Error as |E|>
{{#each @model.errors.region as |error|}}
<E.Message>{{error.message}}</E.Message>
{{/each}}
</F.Error>
{{/if}}
</Hds::Form::TextInput::Field>
<Hds::Form::RadioCard::Group @name='credential_type' as |G|>
<G.Legend>{{t 'resources.storage-bucket.types.credential'}}</G.Legend>
{{#each this.credentials as |credentialType|}}
<G.RadioCard
@name={{credentialType}}
@value={{credentialType}}
@checked={{eq credentialType this.selectedCredentialType}}
@disabled={{form.disabled}}
{{on 'input' (fn this.updateTypeSelection credentialType)}}
as |R|
>
<R.Label>{{t
(concat 'resources.storage-bucket.types.' credentialType '.title')
}}</R.Label>
<R.Description>{{t
(concat
'resources.storage-bucket.types.' credentialType '.description'
)
}}</R.Description>
</G.RadioCard>
{{/each}}
</Hds::Form::RadioCard::Group>
{{#unless this.showDynamicCredentials}}
{{#if @model.isNew}}
<Hds::Form::TextInput::Field
@isRequired={{true}}
@value={{@model.access_key_id}}
@isInvalid={{@model.errors.secrets}}
@type='password'
name='access_key_id'
@hasVisibilityToggle={{false}}
{{on 'input' (set-from-event @model 'access_key_id')}}
as |F|
>
<F.Label>{{t
'resources.storage-bucket.form.access_key_id.label'
}}</F.Label>
<F.HelperText>{{t
'resources.storage-bucket.form.access_key_id.help'
}}</F.HelperText>
{{#if @model.errors.secrets}}
<F.Error as |E|>
{{#each @model.errors.secrets as |error|}}
<E.Message>{{error.message}}</E.Message>
{{/each}}
</F.Error>
{{/if}}
</Hds::Form::TextInput::Field>
<Hds::Form::TextInput::Field
@isRequired={{true}}
@value={{@model.secret_access_key}}
@isInvalid={{@model.errors.secrets}}
@type='password'
name='secret_access_key'
disabled={{form.disabled}}
@hasVisibilityToggle={{false}}
{{on 'input' (set-from-event @model 'secret_access_key')}}
as |F|
>
<F.Label>{{t
'resources.storage-bucket.form.secret_access_key.label'
}}</F.Label>
<F.HelperText>{{t
'resources.storage-bucket.form.secret_access_key.help'
}}</F.HelperText>
{{#if @model.errors.secrets}}
<F.Error as |E|>
{{#each @model.errors.secrets as |error|}}
<E.Message>{{error.message}}</E.Message>
{{/each}}
</F.Error>
{{/if}}
</Hds::Form::TextInput::Field>
{{else}}
<Form::Field::SecretInput
@isRequired={{true}}
@value={{@model.access_key_id}}
@isInvalid={{@model.errors.access_key_id}}
@name='access_key_id'
@isDisabled={{form.disabled}}
@showEditButton={{true}}
@cancel={{fn this.rollbackSecretAttrs 'access_key_id'}}
{{on 'input' (set-from-event @model 'access_key_id')}}
as |F|
>
<F.Label>{{t
'resources.storage-bucket.form.access_key_id.label'
}}</F.Label>
<F.HelperText>{{t
'resources.storage-bucket.form.access_key_id.help'
}}</F.HelperText>
</Form::Field::SecretInput>
<Form::Field::SecretInput
@isRequired={{true}}
@value={{@model.secret_access_key}}
@isInvalid={{@model.errors.secret_access_key}}
@name='secret_access_key'
@isDisabled={{form.disabled}}
@showEditButton={{true}}
@cancel={{fn this.rollbackSecretAttrs 'secret_access_key'}}
{{on 'input' (set-from-event @model 'secret_access_key')}}
as |F|
>
<F.Label>{{t
'resources.storage-bucket.form.secret_access_key.label'
}}</F.Label>
<F.HelperText>{{t
'resources.storage-bucket.form.secret_access_key.help'
}}</F.HelperText>
</Form::Field::SecretInput>
{{/if}}
{{/unless}}
{{#if this.showDynamicCredentials}}
<Hds::Form::TextInput::Field
@isRequired={{true}}
@value={{@model.role_arn}}
@isInvalid={{@model.errors.role_arn}}
@type='text'
name='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>
<Hds::Form::TextInput::Field
@isOptional={{true}}
@value={{@model.role_external_id}}
@isInvalid={{@model.errors.role_external_id}}
@type='text'
name='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>
<Hds::Form::TextInput::Field
@isOptional={{true}}
@value={{@model.role_session_name}}
@isInvalid={{@model.errors.role_session_name}}
@type='text'
name='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>
<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.label'}}
</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.TextInput
@name='role_tags'
@options={{@model.role_tags}}
@model={{@model}}
/>
</:field>
</Form::Field::ListWrapper>
{{/if}}
<Hds::Form::TextInput::Field
@isRequired={{true}}
@value={{@model.worker_filter}}
@isInvalid={{@model.errors.worker_filter}}
@type='text'
name='worker_filter'
disabled={{form.disabled}}
{{on 'input' (set-from-event @model 'worker_filter')}}
as |F|
>
<F.Label>{{t 'resources.storage-bucket.form.worker_filter.label'}}</F.Label>
<F.HelperText>
{{t 'resources.storage-bucket.form.worker_filter.help'}}
<Hds::Link::Inline @href={{doc-url 'storage-bucket.worker-filter'}}>
{{t 'actions.learn-more'}}
</Hds::Link::Inline>
</F.HelperText>
{{#if @model.errors.worker_filter}}
<F.Error as |E|>
{{#each @model.errors.worker_filter as |error|}}
<E.Message>{{error.message}}</E.Message>
{{/each}}
</F.Error>
{{/if}}
</Hds::Form::TextInput::Field>
{{#unless this.showDynamicCredentials}}
<Hds::Form::Checkbox::Field
name='disable_credential_rotation'
disabled={{form.disabled}}
checked={{@model.disable_credential_rotation}}
{{on 'change' this.toggleDisableCredentialRotation}}
as |F|
>
<F.Label>{{t
'resources.storage-bucket.form.disable_credential_rotation.label'
}}</F.Label>
<F.HelperText>
{{t 'resources.storage-bucket.form.disable_credential_rotation.help'}}
<Hds::Link::Inline
@href={{doc-url 'storage-bucket.disable-credential-rotation'}}
>
{{t 'actions.learn-more'}}
</Hds::Link::Inline>
</F.HelperText>
</Hds::Form::Checkbox::Field>
{{/unless}}
{{#if (can 'save model' @model)}}
<form.actions
@enableEditText={{t 'actions.edit-form'}}
@submitText={{t 'actions.save'}}
@cancelText={{t 'actions.cancel'}}
/>
{{/if}}
</Rose::Form>
{{#if @model.type}}
{{component
(concat 'form/storage-bucket/' @model.compositeType)
model=@model
submit=@submit
cancel=@cancel
updateScope=this.updateScope
scopes=@scopes
pluginTypes=this.pluginTypes
changePluginType=@changePluginType
changeCredentialType=@changeCredentialType
rollbackSecretAttrs=this.rollbackSecretAttrs
toggleDisableCredentialRotation=this.toggleDisableCredentialRotation
}}
{{/if}}
@@ -5,64 +5,26 @@
import Component from '@glimmer/component';
import { action } from '@ember/object';
import { tracked } from '@glimmer/tracking';
import { inject as service } from '@ember/service';
import { set } from '@ember/object';
import {
TYPES_CREDENTIALS,
TYPE_CREDENTIAL_DYNAMIC,
TYPES_STORAGE_BUCKET_PLUGIN,
} from 'api/models/storage-bucket';
export default class FormStorageBucketComponent extends Component {
// =attributes
@service intl;
@tracked scopeFieldDescription = this.intl.t(
'resources.storage-bucket.form.scope.help',
);
@tracked selectedCredentialType = this.args.model.credentialType;
@tracked showDynamicCredentials =
this.args.model.credentialType === TYPE_CREDENTIAL_DYNAMIC;
/**
* returns an array of available credential types
* @type {object}
* returns an array of available storage bucket plugin types
*/
get credentials() {
return TYPES_CREDENTIALS;
get pluginTypes() {
return TYPES_STORAGE_BUCKET_PLUGIN;
}
// =actions
/**
* Allows to update the credential type
* @param type {string}
*/
@action
updateTypeSelection(type) {
this.selectedCredentialType = type;
if (type === TYPE_CREDENTIAL_DYNAMIC) {
this.showDynamicCredentials = true;
} else {
this.showDynamicCredentials = false;
}
this.args.changeType(type);
}
updateScopeFieldDescription() {
if (this.args.model.scopeModel.isGlobal) {
this.scopeFieldDescription = this.intl.t(
'resources.storage-bucket.form.scope.help_global',
);
} else {
this.scopeFieldDescription = this.intl.t(
'resources.storage-bucket.form.scope.help_org',
);
}
}
@action
updateScope(event) {
const selectedScopeId = event.target.value;
@@ -70,7 +32,6 @@ export default class FormStorageBucketComponent extends Component {
(element) => element.model.id === selectedScopeId,
).model;
this.args.model.scopeModel = selectedScopeModel;
this.updateScopeFieldDescription();
}
@action
@@ -0,0 +1,353 @@
<Rose::Form
@onSubmit={{@submit}}
@cancel={{@cancel}}
@disabled={{@model.isSaving}}
@showEditToggle={{if @model.isNew false true}}
as |form|
>
{{! name }}
<Hds::Form::TextInput::Field
name='name'
@isOptional={{true}}
@value={{@model.name}}
@isInvalid={{@model.errors.name}}
@type='text'
disabled={{form.disabled}}
{{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>
{{#if @model.errors.name}}
<F.Error as |E|>
{{#each @model.errors.name as |error|}}
<E.Message>{{error.message}}</E.Message>
{{/each}}
</F.Error>
{{/if}}
</Hds::Form::TextInput::Field>
{{! description }}
<Hds::Form::Textarea::Field
name='description'
@isOptional={{true}}
@value={{@model.description}}
@isInvalid={{@model.errors.description}}
disabled={{form.disabled}}
as |F|
>
<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>
{{/each}}
</F.Error>
{{/if}}
</Hds::Form::Textarea::Field>
{{! scope }}
{{#if @model.isNew}}
<Hds::Form::Select::Field
name='scope'
@isRequired={{true}}
@width='100%'
disabled={{form.disabled}}
{{on 'change' @updateScope}}
as |F|
>
<F.Label>{{t 'resources.storage-bucket.form.scope.label'}}</F.Label>
<F.HelperText>
{{#if @model.scope}}
{{#if @model.scope.isGlobal}}
{{t 'resources.storage-bucket.form.scope.help_global'}}
{{else if @model.scope.isOrg}}
{{t 'resources.storage-bucket.form.scope.help_org'}}
{{/if}}
{{else}}
{{t 'resources.storage-bucket.form.scope.help'}}
{{/if}}
</F.HelperText>
<F.Options>
<option disabled selected={{not @model.scope}} value=''>
{{t 'titles.choose-an-option'}}
</option>
{{#each @scopes as |scope|}}
<option
value={{scope.model.id}}
selected={{eq scope.model.id @model.scope.scope_id}}
>
{{scope.model.displayName}}
</option>
{{/each}}
</F.Options>
</Hds::Form::Select::Field>
{{else}}
<InfoField
@value={{@model.scopeModel.displayName}}
@icon={{if @model.scopeModel.isGlobal 'globe' 'org'}}
disabled={{form.disabled}}
as |F|
>
<F.Label>{{t 'resources.storage-bucket.form.scope.label'}}</F.Label>
<F.HelperText>
{{#if @model.scopeModel.isGlobal}}
{{t 'resources.storage-bucket.form.scope.help_global'}}
{{else}}
{{t 'resources.storage-bucket.form.scope.help_org'}}
{{/if}}
</F.HelperText>
</InfoField>
{{/if}}
{{! Provider / plugin.name }}
<Hds::Form::RadioCard::Group @name='plugin_type' @alignment='center' as |G|>
<G.Legend>{{t 'titles.provider'}}</G.Legend>
<G.HelperText>{{t 'descriptions.choose-a-provider'}}</G.HelperText>
{{#each @pluginTypes as |pluginType|}}
<G.RadioCard
@value={{pluginType}}
@checked={{eq pluginType @model.compositeType}}
@disabled={{(not @model.isNew)}}
{{on 'input' (fn @changePluginType pluginType)}}
as |R|
>
<R.Label>{{t
(concat 'resources.storage-bucket.plugin-types.' pluginType)
}}</R.Label>
{{#if (eq pluginType 'aws')}}
<R.Icon @name='aws-color' />
{{else}}
<R.Icon @name='cloud-upload' />
{{/if}}
</G.RadioCard>
{{/each}}
</Hds::Form::RadioCard::Group>
{{! endpoint_url }}
<Hds::Form::TextInput::Field
name='endpoint_url'
@isRequired={{true}}
@value={{@model.endpoint_url}}
@isInvalid={{@model.errors.endpoint_url}}
disabled={{form.disabled}}
readOnly={{not @model.isNew}}
{{on 'input' (set-from-event @model 'endpoint_url')}}
as |F|
>
<F.Label>{{t 'resources.storage-bucket.form.endpoint_url.label'}}</F.Label>
<F.HelperText>{{t
'resources.storage-bucket.form.endpoint_url.help'
}}</F.HelperText>
{{#if @model.errors.endpoint_url}}
<F.Error as |E|>
{{#each @model.errors.endpoint_url as |error|}}
<E.Message>{{error.message}}</E.Message>
{{/each}}
</F.Error>
{{/if}}
</Hds::Form::TextInput::Field>
{{! bucket_name }}
<Hds::Form::TextInput::Field
name='bucket_name'
@isRequired={{true}}
@value={{@model.bucket_name}}
@isInvalid={{@model.errors.bucket_name}}
disabled={{form.disabled}}
readOnly={{not @model.isNew}}
{{on 'input' (set-from-event @model 'bucket_name')}}
as |F|
>
<F.Label>{{t 'resources.storage-bucket.form.bucket_name.label'}}</F.Label>
<F.HelperText>{{t
'resources.storage-bucket.form.bucket_name.help'
}}</F.HelperText>
{{#if @model.errors.bucket_name}}
<F.Error as |E|>
{{#each @model.errors.bucket_name as |error|}}
<E.Message>{{error.message}}</E.Message>
{{/each}}
</F.Error>
{{/if}}
</Hds::Form::TextInput::Field>
{{! region }}
<Hds::Form::TextInput::Field
name='region'
@isOptional={{true}}
@value={{@model.region}}
@isInvalid={{@model.errors.region}}
disabled={{form.disabled}}
readOnly={{not @model.isNew}}
{{on 'input' (set-from-event @model 'region')}}
as |F|
>
<F.Label>{{t 'resources.storage-bucket.form.region.label'}}</F.Label>
<F.HelperText>{{t
'resources.storage-bucket.form.region.help'
}}</F.HelperText>
{{#if @model.errors.region}}
<F.Error as |E|>
{{#each @model.errors.region as |error|}}
<E.Message>{{error.message}}</E.Message>
{{/each}}
</F.Error>
{{/if}}
</Hds::Form::TextInput::Field>
{{! Creation }}
{{#if @model.isNew}}
{{! access_key }}
<Hds::Form::TextInput::Field
name='access_key_id'
@type='password'
@isRequired={{true}}
@value={{@model.access_key_id}}
@isInvalid={{@model.errors.secrets}}
@hasVisibilityToggle={{false}}
{{on 'input' (set-from-event @model 'access_key_id')}}
as |F|
>
<F.Label>
{{t 'resources.storage-bucket.form.access_key_id.label'}}
</F.Label>
<F.HelperText>{{t
'resources.storage-bucket.form.access_key_id.help'
}}</F.HelperText>
{{#if @model.errors.secrets}}
<F.Error as |E|>
{{#each @model.errors.secrets as |error|}}
<E.Message>{{error.message}}</E.Message>
{{/each}}
</F.Error>
{{/if}}
</Hds::Form::TextInput::Field>
{{! secret_access_key }}
<Hds::Form::TextInput::Field
name='secret_access_key'
@type='password'
@isRequired={{true}}
@value={{@model.secret_access_key}}
@isInvalid={{@model.errors.secrets}}
disabled={{form.disabled}}
@hasVisibilityToggle={{false}}
{{on 'input' (set-from-event @model 'secret_access_key')}}
as |F|
>
<F.Label>{{t
'resources.storage-bucket.form.secret_access_key.label'
}}</F.Label>
<F.HelperText>{{t
'resources.storage-bucket.form.secret_access_key.help'
}}</F.HelperText>
{{#if @model.errors.secrets}}
<F.Error as |E|>
{{#each @model.errors.secrets as |error|}}
<E.Message>{{error.message}}</E.Message>
{{/each}}
</F.Error>
{{/if}}
</Hds::Form::TextInput::Field>
{{! Edit }}
{{else}}
{{! access_key }}
<Form::Field::SecretInput
@name='access_key_id'
@isRequired={{true}}
@value={{@model.access_key_id}}
@isInvalid={{@model.errors.access_key_id}}
@isDisabled={{form.disabled}}
@showEditButton={{true}}
@cancel={{fn @rollbackSecretAttrs 'access_key_id'}}
{{on 'input' (set-from-event @model 'access_key_id')}}
as |F|
>
<F.Label>{{t
'resources.storage-bucket.form.access_key_id.label'
}}</F.Label>
<F.HelperText>{{t
'resources.storage-bucket.form.access_key_id.help'
}}</F.HelperText>
</Form::Field::SecretInput>
{{! secret_access_key }}
<Form::Field::SecretInput
@name='secret_access_key'
@isRequired={{true}}
@value={{@model.secret_access_key}}
@isInvalid={{@model.errors.secret_access_key}}
@isDisabled={{form.disabled}}
@showEditButton={{true}}
@cancel={{fn @rollbackSecretAttrs 'secret_access_key'}}
{{on 'input' (set-from-event @model 'secret_access_key')}}
as |F|
>
<F.Label>{{t
'resources.storage-bucket.form.secret_access_key.label'
}}</F.Label>
<F.HelperText>{{t
'resources.storage-bucket.form.secret_access_key.help'
}}</F.HelperText>
</Form::Field::SecretInput>
{{/if}}
{{! worker_filter }}
<Hds::Form::TextInput::Field
name='worker_filter'
@isRequired={{true}}
@value={{@model.worker_filter}}
@isInvalid={{@model.errors.worker_filter}}
disabled={{form.disabled}}
{{on 'input' (set-from-event @model 'worker_filter')}}
as |F|
>
<F.Label>{{t 'resources.storage-bucket.form.worker_filter.label'}}</F.Label>
<F.HelperText>
{{t 'resources.storage-bucket.form.worker_filter.help'}}
<Hds::Link::Inline @href={{doc-url 'storage-bucket.worker-filter'}}>
{{t 'actions.learn-more'}}
</Hds::Link::Inline>
</F.HelperText>
{{#if @model.errors.worker_filter}}
<F.Error as |E|>
{{#each @model.errors.worker_filter as |error|}}
<E.Message>{{error.message}}</E.Message>
{{/each}}
</F.Error>
{{/if}}
</Hds::Form::TextInput::Field>
{{! disable_credential_rotation }}
<Hds::Form::Checkbox::Field
name='disable_credential_rotation'
disabled={{form.disabled}}
checked={{@model.disable_credential_rotation}}
{{on 'change' @toggleDisableCredentialRotation}}
as |F|
>
<F.Label>{{t
'resources.storage-bucket.form.disable_credential_rotation.label'
}}</F.Label>
<F.HelperText>
{{t 'resources.storage-bucket.form.disable_credential_rotation.help'}}
<Hds::Link::Inline
@href={{doc-url 'storage-bucket.disable-credential-rotation'}}
>
{{t 'actions.learn-more'}}
</Hds::Link::Inline>
</F.HelperText>
</Hds::Form::Checkbox::Field>
{{! Actions }}
{{#if (can 'save model' @model)}}
<form.actions
@enableEditText={{t 'actions.edit-form'}}
@submitText={{t 'actions.save'}}
@cancelText={{t 'actions.cancel'}}
/>
{{/if}}
</Rose::Form>
@@ -0,0 +1,78 @@
import Controller from '@ember/controller';
import { inject as service } from '@ember/service';
import { action } from '@ember/object';
import { loading } from 'ember-loading';
import { confirm } from 'core/decorators/confirm';
import { notifySuccess, notifyError } from 'core/decorators/notify';
export default class ScopesScopeStorageBucketsIndexController extends Controller {
// =services
@service router;
// =actions
/**
* Handle save
* @param {StorageBucketModel} storageBucket
*/
@action
@loading
@notifyError(({ message }) => message)
@notifySuccess('notifications.save-success')
async save(storageBucket) {
await storageBucket.save();
await this.router.transitionTo(
'scopes.scope.storage-buckets.storage-bucket',
storageBucket,
);
await this.router.refresh();
}
/**
* Deletes the storage bucket.
* @param {StorageBucketModel} storageBucket
*/
@action
@loading
@confirm('resources.storage-bucket.questions.delete-storage-bucket.message', {
title: 'resources.storage-bucket.questions.delete-storage-bucket.title',
confirm: 'resources.storage-bucket.actions.delete',
})
@notifyError(({ message }) => message, { catch: true })
@notifySuccess('notifications.delete-success')
async delete(storageBucket) {
await storageBucket.destroyRecord();
}
/**
* Rollback changes on storage buckets.
* @param {StorageBucketModel} storageBucket
*/
@action
cancel(storageBucket) {
const { isNew } = storageBucket;
storageBucket.rollbackAttributes();
if (isNew) this.router.transitionTo('scopes.scope.storage-buckets');
}
/**
* Updates credentil type
* @param {object} storageBucket
* @param {string} credentialType
*/
@action
changeCredentialType(storageBucket, credentialType) {
storageBucket.credentialType = credentialType;
}
/**
* Changes the plugin type.
* @param {*} pluginType
*/
@action
async changePluginType(pluginType) {
await this.router.replaceWith({
queryParams: { compositeType: pluginType },
});
}
}
@@ -0,0 +1,13 @@
import Controller, { inject as controller } from '@ember/controller';
import { inject as service } from '@ember/service';
export default class ScopesScopeStorageBucketsNewController extends Controller {
@controller('scopes/scope/storage-buckets/index')
storageBuckets;
// =services
@service router;
// =attributes
queryParams = ['compositeType'];
}
@@ -0,0 +1,6 @@
import Controller, { inject as controller } from '@ember/controller';
export default class ScopesScopeStorageBucketsStorageBucketIndexController extends Controller {
@controller('scopes/scope/storage-buckets/index')
storageBuckets;
}
@@ -0,0 +1,6 @@
import Controller, { inject as controller } from '@ember/controller';
export default class ScopesScopeTargetsTargetEnableSessionRecordingCreateStorageBucketController extends Controller {
@controller('scopes/scope/storage-buckets/index')
storageBuckets;
}
@@ -5,10 +5,6 @@
import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';
import { action } from '@ember/object';
import { loading } from 'ember-loading';
import { confirm } from 'core/decorators/confirm';
import { notifySuccess, notifyError } from 'core/decorators/notify';
export default class ScopesScopeStorageBucketsRoute extends Route {
// =services
@@ -18,8 +14,6 @@ export default class ScopesScopeStorageBucketsRoute extends Route {
@service can;
@service router;
// =attributes
// =methods
/**
@@ -44,59 +38,4 @@ export default class ScopesScopeStorageBucketsRoute extends Route {
return this.store.query('storage-bucket', { scope_id, recursive: true });
}
}
// =actions
/**
* Handle save
* @param {StorageBucketModel} storageBucket
*/
@action
@loading
@notifyError(({ message }) => message)
@notifySuccess('notifications.save-success')
async save(storageBucket) {
await storageBucket.save();
await this.router.transitionTo(
'scopes.scope.storage-buckets.storage-bucket',
storageBucket,
);
this.refresh();
}
/**
* Rollback changes on storage buckets.
* @param {StorageBucketModel} storageBucket
*/
@action
cancel(storageBucket) {
const { isNew } = storageBucket;
storageBucket.rollbackAttributes();
if (isNew) this.router.transitionTo('scopes.scope.storage-buckets');
}
/**
* Deletes the storage bucket.
* @param {StorageBucketModel} storageBucket
*/
@action
@loading
@confirm('resources.storage-bucket.questions.delete-storage-bucket.message', {
title: 'resources.storage-bucket.questions.delete-storage-bucket.title',
confirm: 'resources.storage-bucket.actions.delete',
})
@notifyError(({ message }) => message, { catch: true })
@notifySuccess('notifications.delete-success')
async delete(storageBucket) {
await storageBucket.destroyRecord();
}
/**
* Updates type of credential
* @param {string} credentialType
*/
@action
changeType(storageBucket, credentialType) {
storageBucket.credentialType = credentialType;
}
}
@@ -17,6 +17,13 @@ export default class ScopesScopeStorageBucketsNewRoute extends Route {
@service can;
@service router;
// =attributes
queryParams = {
compositeType: {
refreshModel: true,
},
};
// =methods
/**
@@ -39,8 +46,7 @@ export default class ScopesScopeStorageBucketsNewRoute extends Route {
* creating another, but reuse name/description/other fields if available.
* @return {StorageBucket}
*/
model() {
const scopeModel = this.store.peekRecord('scope', 'global');
model({ compositeType = TYPE_STORAGE_BUCKET_PLUGIN_AWS_S3 }) {
let name,
description,
scope,
@@ -48,6 +54,7 @@ export default class ScopesScopeStorageBucketsNewRoute extends Route {
bucket_prefix,
region,
worker_filter;
if (this.currentModel?.isNew) {
({
name,
@@ -60,9 +67,10 @@ export default class ScopesScopeStorageBucketsNewRoute extends Route {
} = this.currentModel);
this.currentModel.rollbackAttributes();
}
const record = this.store.createRecord('storage-bucket', {
type: TYPE_STORAGE_BUCKET_PLUGIN,
compositeType: TYPE_STORAGE_BUCKET_PLUGIN_AWS_S3,
compositeType,
name,
description,
scope,
@@ -71,7 +79,6 @@ export default class ScopesScopeStorageBucketsNewRoute extends Route {
region,
worker_filter,
});
record.scopeModel = scopeModel;
return record;
}
@@ -69,6 +69,12 @@
@text={{t 'resources.storage-bucket.titles.amazon_s3'}}
@icon='aws-color'
/>
{{else if B.data.isMinIO}}
<Hds::Badge
@text={{t 'resources.storage-bucket.titles.minio'}}
@icon='cloud-upload'
/>
{{else}}
{{B.data.plugin.name}}
{{/if}}
@@ -113,7 +119,7 @@
<dd.Interactive
@text={{t 'resources.storage-bucket.actions.delete'}}
@color='critical'
{{on 'click' (route-action 'delete' B.data)}}
{{on 'click' (fn this.delete B.data)}}
/>
{{/if}}
</Hds::Dropdown>
@@ -24,10 +24,14 @@
<page.body>
<Form::StorageBucket
@model={{@model}}
@submit={{route-action 'save' @model}}
@cancel={{route-action 'cancel' @model}}
@submit={{fn this.storageBuckets.save @model}}
@cancel={{fn this.storageBuckets.cancel @model}}
@scopes={{this.scopes}}
@changeType={{route-action 'changeType' @model}}
@changeCredentialType={{fn
this.storageBuckets.changeCredentialType
@model
}}
@changePluginType={{this.storageBuckets.changePluginType}}
/>
</page.body>
@@ -27,10 +27,14 @@
<page.body>
<Form::StorageBucket
@model={{@model}}
@submit={{route-action 'save' @model}}
@cancel={{route-action 'cancel' @model}}
@submit={{fn this.storageBuckets.save @model}}
@cancel={{fn this.storageBuckets.cancel @model}}
@scopes={{this.scopes}}
@changeType={{route-action 'changeType' @model}}
@changeCredentialType={{fn
this.storageBuckets.changeCredentialType
@model
}}
@changePluginType={{this.storageBuckets.changePluginType}}
/>
</page.body>
</Rose::Layout::Page>
@@ -27,6 +27,11 @@
@submit={{route-action 'save' @model}}
@cancel={{route-action 'cancel' @model}}
@scopes={{this.scopes}}
@changeCredentialType={{fn
this.storageBuckets.changeCredentialType
@model
}}
@changePluginType={{this.storageBuckets.changePluginType}}
/>
</page.body>
@@ -32,6 +32,10 @@ module('Acceptance | storage-buckets | create', function (hooks) {
const ACCESS_KEY_SELECTOR = '[name="access_key_id"]';
const SECRET_KEY_SELECTOR = '[name="secret_access_key"]';
const SCOPE_SELECTOR = '[name=scope]';
const CREDENTIAL_TYPE_GROUP_SELECTOR = '[name=credential_type]';
const MINIO_PLUGIN_TYPE_SELECTOR = '[value=minio]';
const ENDPOINT_URL_SELECTOR = '[name=endpoint_url]';
const ENDPOINT_URL_TEXT = 'http://www.hashicorp.com';
const instances = {
scopes: {
@@ -63,13 +67,13 @@ module('Acceptance | storage-buckets | create', function (hooks) {
authenticateSession({});
});
test('users can create a new storage bucket with global scope', async function (assert) {
test('users can create a new storage bucket aws plugin type with global scope', async function (assert) {
const storageBucketCount = getStorageBucketCount();
await visit(urls.storageBuckets);
await click(`[href="${urls.newStorageBucket}"]`);
await fillIn(NAME_FIELD_SELECTOR, NAME_FIELD_TEXT);
await click('[value="global"]');
await select(SCOPE_SELECTOR, 'global');
assert.dom(BUCKET_NAME_FIELD_SELECTOR).isNotDisabled();
assert.dom(BUCKET_PREFIX_FIELD_SELECTOR).isNotDisabled();
@@ -86,7 +90,7 @@ module('Acceptance | storage-buckets | create', function (hooks) {
assert.strictEqual(getStorageBucketCount(), storageBucketCount + 1);
});
test('users can create a new storage bucket with org scope', async function (assert) {
test('users can create a new storage bucket aws plugin type with org scope', async function (assert) {
const storageBucketCount = getStorageBucketCount();
await visit(urls.storageBuckets);
@@ -110,13 +114,17 @@ module('Acceptance | storage-buckets | create', function (hooks) {
assert.strictEqual(getStorageBucketCount(), storageBucketCount + 1);
});
test('users can create a new storage bucket with dynamic credentials', async function (assert) {
test('users can create a new storage bucket aws plugin type with dynamic credentials', async function (assert) {
const storageBucketCount = getStorageBucketCount();
await visit(urls.storageBuckets);
await click(`[href="${urls.newStorageBucket}"]`);
await fillIn(NAME_FIELD_SELECTOR, NAME_FIELD_TEXT);
assert.dom('.hds-form-radio-card').exists({ count: 2 });
// There are 2 credential types
assert
.dom(`${CREDENTIAL_TYPE_GROUP_SELECTOR} .hds-form-radio-card`)
.exists({ count: 2 });
await click(DYNAMIC_CREDENTIAL_SELECTOR);
await fillIn(ROLE_ARN_SELECTOR, 'test-arn-id');
@@ -132,13 +140,15 @@ module('Acceptance | storage-buckets | create', function (hooks) {
assert.strictEqual(getStorageBucketCount(), storageBucketCount + 1);
});
test('users can create a new storage bucket with static credentials', async function (assert) {
test('users can create a new storage bucket aws plugin type with static credentials', async function (assert) {
const storageBucketCount = getStorageBucketCount();
await visit(urls.storageBuckets);
await click(`[href="${urls.newStorageBucket}"]`);
await fillIn(NAME_FIELD_SELECTOR, NAME_FIELD_TEXT);
assert.dom('.hds-form-radio-card').exists({ count: 2 });
assert
.dom(`${CREDENTIAL_TYPE_GROUP_SELECTOR} .hds-form-radio-card`)
.exists({ count: 2 });
await click(STATIC_CREDENTIAL_SELECTOR);
await fillIn(ACCESS_KEY_SELECTOR, 'access_key_id');
@@ -156,6 +166,40 @@ module('Acceptance | storage-buckets | create', function (hooks) {
assert.strictEqual(getStorageBucketCount(), storageBucketCount + 1);
});
test('users can create a new storage bucket minio plugin type', async function (assert) {
const storageBucketCount = getStorageBucketCount();
// Navigate to new storage bucket
await visit(urls.storageBuckets);
await click(`[href="${urls.newStorageBucket}"]`);
// Fill the form
await fillIn(NAME_FIELD_SELECTOR, NAME_FIELD_TEXT);
await click(MINIO_PLUGIN_TYPE_SELECTOR);
await fillIn(ENDPOINT_URL_SELECTOR, ENDPOINT_URL_TEXT);
await fillIn(BUCKET_NAME_FIELD_SELECTOR, 'Test SB');
await fillIn(ACCESS_KEY_SELECTOR, 'access_key_id');
await fillIn(SECRET_KEY_SELECTOR, 'secret_access_key');
await click(SAVE_BTN_SELECTOR);
// Retrieve recently created SB
const storageBucket = await this.server.schema.storageBuckets.findBy({
name: NAME_FIELD_TEXT,
});
// Assertions
assert.strictEqual(storageBucket.name, NAME_FIELD_TEXT);
assert.strictEqual(
storageBucket.attributes.endpoint_url,
ENDPOINT_URL_TEXT,
);
assert.strictEqual(storageBucket.attributes.role_arn, null);
assert.strictEqual(storageBucket.plugin.name, 'minio');
assert.strictEqual(storageBucket.type, 'plugin');
assert.strictEqual(getStorageBucketCount(), storageBucketCount + 1);
});
test('user can cancel new storage bucket creation', async function (assert) {
const storageBucketCount = getStorageBucketCount();
await visit(urls.storageBuckets);
@@ -0,0 +1,17 @@
import { module, test } from 'qunit';
import { setupTest } from 'admin/tests/helpers';
module(
'Unit | Controller | scopes/scope/storage-buckets/index',
function (hooks) {
setupTest(hooks);
// TODO: Replace this with your real tests.
test('it exists', function (assert) {
let controller = this.owner.lookup(
'controller:scopes/scope/storage-buckets/index',
);
assert.ok(controller);
});
},
);
@@ -0,0 +1,17 @@
import { module, test } from 'qunit';
import { setupTest } from 'admin/tests/helpers';
module(
'Unit | Controller | scopes/scope/storage-buckets/new',
function (hooks) {
setupTest(hooks);
// TODO: Replace this with your real tests.
test('it exists', function (assert) {
let controller = this.owner.lookup(
'controller:scopes/scope/storage-buckets/new',
);
assert.ok(controller);
});
},
);
@@ -0,0 +1,17 @@
import { module, test } from 'qunit';
import { setupTest } from 'admin/tests/helpers';
module(
'Unit | Controller | scopes/scope/storage-buckets/storage-bucket/index',
function (hooks) {
setupTest(hooks);
// TODO: Replace this with your real tests.
test('it exists', function (assert) {
let controller = this.owner.lookup(
'controller:scopes/scope/storage-buckets/storage-bucket/index',
);
assert.ok(controller);
});
},
);
@@ -0,0 +1,17 @@
import { module, test } from 'qunit';
import { setupTest } from 'admin/tests/helpers';
module(
'Unit | Controller | scopes/scope/targets/target/enable-session-recording/create-storage-bucket',
function (hooks) {
setupTest(hooks);
// TODO: Replace this with your real tests.
test('it exists', function (assert) {
let controller = this.owner.lookup(
'controller:scopes/scope/targets/target/enable-session-recording/create-storage-bucket',
);
assert.ok(controller);
});
},
);