diff options
Diffstat (limited to 'app/assets/javascripts/terraform')
4 files changed, 132 insertions, 21 deletions
diff --git a/app/assets/javascripts/terraform/components/empty_state.vue b/app/assets/javascripts/terraform/components/empty_state.vue index d86ba3af2b1..a5a613b7282 100644 --- a/app/assets/javascripts/terraform/components/empty_state.vue +++ b/app/assets/javascripts/terraform/components/empty_state.vue @@ -1,12 +1,12 @@ <script> -import { GlEmptyState, GlIcon, GlLink, GlSprintf } from '@gitlab/ui'; +import { GlEmptyState, GlIcon, GlLink } from '@gitlab/ui'; +import { helpPagePath } from '~/helpers/help_page_helper'; export default { components: { GlEmptyState, GlIcon, GlLink, - GlSprintf, }, props: { image: { @@ -14,6 +14,11 @@ export default { required: true, }, }, + computed: { + docsUrl() { + return helpPagePath('user/infrastructure/terraform_state'); + }, + }, }; </script> @@ -21,23 +26,10 @@ export default { <gl-empty-state :svg-path="image" :title="s__('Terraform|Get started with Terraform')"> <template #description> <p> - <gl-sprintf - :message=" - s__( - 'Terraform|Find out how to use the %{linkStart}GitLab managed Terraform State%{linkEnd}', - ) - " - > - <template #link="{ content }"> - <gl-link - href="https://docs.gitlab.com/ee/user/infrastructure/index.html" - target="_blank" - > - {{ content }} - <gl-icon name="external-link" /> - </gl-link> - </template> - </gl-sprintf> + <gl-link :href="docsUrl" target="_blank" + >{{ s__('Terraform|How to use GitLab-managed Terraform State?') }} + <gl-icon name="external-link" + /></gl-link> </p> </template> </gl-empty-state> diff --git a/app/assets/javascripts/terraform/components/init_command_modal.vue b/app/assets/javascripts/terraform/components/init_command_modal.vue new file mode 100644 index 00000000000..2cb10d4ae23 --- /dev/null +++ b/app/assets/javascripts/terraform/components/init_command_modal.vue @@ -0,0 +1,86 @@ +<script> +import { GlModal, GlSprintf, GlLink } from '@gitlab/ui'; +import { __, s__ } from '~/locale'; +import ModalCopyButton from '~/vue_shared/components/modal_copy_button.vue'; + +export default { + i18n: { + title: s__('Terraform|Terraform init command'), + explanatoryText: s__( + `Terraform|To get access to this terraform state from your local computer, run the following command at the command line. The first line requires a personal access token with API read and write access. %{linkStart}How do I create a personal access token?%{linkEnd}.`, + ), + closeText: __('Close'), + copyToClipboardText: __('Copy'), + }, + components: { + GlModal, + GlSprintf, + GlLink, + ModalCopyButton, + }, + inject: ['accessTokensPath', 'terraformApiUrl', 'username'], + props: { + modalId: { + type: String, + required: true, + }, + stateName: { + type: String, + required: true, + }, + }, + computed: { + closeModalProps() { + return { + text: this.$options.i18n.closeText, + attributes: [], + }; + }, + }, + methods: { + getModalInfoCopyStr() { + return `export GITLAB_ACCESS_TOKEN=<YOUR-ACCESS-TOKEN> +terraform init \\ + -backend-config="address=${this.terraformApiUrl}/${this.stateName}" \\ + -backend-config="lock_address=${this.terraformApiUrl}/${this.stateName}/lock" \\ + -backend-config="unlock_address=${this.terraformApiUrl}/${this.stateName}/lock" \\ + -backend-config="username=${this.username}" \\ + -backend-config="password=$GITLAB_ACCESS_TOKEN" \\ + -backend-config="lock_method=POST" \\ + -backend-config="unlock_method=DELETE" \\ + -backend-config="retry_wait_min=5" + `; + }, + }, +}; +</script> + +<template> + <gl-modal + ref="initCommandModal" + :modal-id="modalId" + :title="$options.i18n.title" + :action-cancel="closeModalProps" + > + <p data-testid="init-command-explanatory-text"> + <gl-sprintf :message="$options.i18n.explanatoryText"> + <template #link="{ content }"> + <gl-link :href="accessTokensPath" target="_blank">{{ content }}</gl-link> + </template> + </gl-sprintf> + </p> + + <div class="gl-display-flex"> + <pre class="gl-bg-gray gl-white-space-pre-wrap" data-testid="terraform-init-command">{{ + getModalInfoCopyStr() + }}</pre> + <modal-copy-button + :title="$options.i18n.copyToClipboardText" + :text="getModalInfoCopyStr()" + :modal-id="$options.modalId" + data-testid="init-command-copy-clipboard" + css-classes="gl-align-self-start gl-ml-2" + /> + </div> + </gl-modal> +</template> diff --git a/app/assets/javascripts/terraform/components/states_table_actions.vue b/app/assets/javascripts/terraform/components/states_table_actions.vue index c4fd97188de..817c421823c 100644 --- a/app/assets/javascripts/terraform/components/states_table_actions.vue +++ b/app/assets/javascripts/terraform/components/states_table_actions.vue @@ -8,12 +8,14 @@ import { GlIcon, GlModal, GlSprintf, + GlModalDirective, } from '@gitlab/ui'; import { s__, sprintf } from '~/locale'; import addDataToState from '../graphql/mutations/add_data_to_state.mutation.graphql'; import lockState from '../graphql/mutations/lock_state.mutation.graphql'; import removeState from '../graphql/mutations/remove_state.mutation.graphql'; import unlockState from '../graphql/mutations/unlock_state.mutation.graphql'; +import InitCommandModal from './init_command_modal.vue'; export default { components: { @@ -25,6 +27,10 @@ export default { GlIcon, GlModal, GlSprintf, + InitCommandModal, + }, + directives: { + GlModalDirective, }, props: { state: { @@ -36,6 +42,7 @@ export default { return { showRemoveModal: false, removeConfirmText: '', + showCommandModal: false, }; }, i18n: { @@ -43,7 +50,7 @@ export default { errorUpdate: s__('Terraform|An error occurred while changing the state file'), lock: s__('Terraform|Lock'), modalBody: s__( - 'Terraform|You are about to remove the State file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, only the state file with all its versions are to be removed. This action is non-revertible.', + 'Terraform|You are about to remove the state file %{name}. This will permanently delete all the State versions and history. The infrastructure provisioned previously will remain intact, and only the state file with all its versions will be removed. This action cannot be undone.', ), modalCancel: s__('Terraform|Cancel'), modalHeader: s__('Terraform|Are you sure you want to remove the Terraform State %{name}?'), @@ -54,6 +61,7 @@ export default { remove: s__('Terraform|Remove state file and versions'), removeSuccessful: s__('Terraform|%{name} successfully removed'), unlock: s__('Terraform|Unlock'), + copyCommand: s__('Terraform|Copy Terraform init command'), }, computed: { cancelModalProps() { @@ -74,6 +82,9 @@ export default { attributes: [{ disabled: this.disableModalSubmit }, { variant: 'danger' }], }; }, + commandModalId() { + return `init-command-modal-${this.state.name}`; + }, }, methods: { hideModal() { @@ -164,6 +175,9 @@ export default { }); }); }, + copyInitCommand() { + this.showCommandModal = true; + }, }, }; </script> @@ -182,6 +196,14 @@ export default { </template> <gl-dropdown-item + v-gl-modal-directive="commandModalId" + data-testid="terraform-state-copy-init-command" + @click="copyInitCommand" + > + {{ $options.i18n.copyCommand }} + </gl-dropdown-item> + + <gl-dropdown-item v-if="state.latestVersion" data-testid="terraform-state-download" :download="`${state.name}.json`" @@ -248,5 +270,11 @@ export default { /> </gl-form-group> </gl-modal> + + <init-command-modal + v-if="showCommandModal" + :modal-id="commandModalId" + :state-name="state.name" + /> </div> </template> diff --git a/app/assets/javascripts/terraform/index.js b/app/assets/javascripts/terraform/index.js index 3f986423836..1b8cab0d51e 100644 --- a/app/assets/javascripts/terraform/index.js +++ b/app/assets/javascripts/terraform/index.js @@ -24,11 +24,16 @@ export default () => { }, }); - const { emptyStateImage, projectPath } = el.dataset; + const { emptyStateImage, projectPath, accessTokensPath, terraformApiUrl, username } = el.dataset; return new Vue({ el, apolloProvider: new VueApollo({ defaultClient }), + provide: { + accessTokensPath, + terraformApiUrl, + username, + }, render(createElement) { return createElement(TerraformList, { props: { |