debian-mirror-gitlab/app/assets/javascripts/clusters_list/components/install_agent_modal.vue

429 lines
12 KiB
Vue
Raw Normal View History

2021-11-18 22:05:49 +05:30
<script>
import {
GlAlert,
GlButton,
GlFormGroup,
GlFormInputGroup,
GlLink,
GlModal,
GlSprintf,
} from '@gitlab/ui';
import { helpPagePath } from '~/helpers/help_page_helper';
2022-01-26 12:08:38 +05:30
import ModalCopyButton from '~/vue_shared/components/modal_copy_button.vue';
2021-11-18 22:05:49 +05:30
import CodeBlock from '~/vue_shared/components/code_block.vue';
2022-01-26 12:08:38 +05:30
import Tracking from '~/tracking';
2021-11-18 22:05:49 +05:30
import { generateAgentRegistrationCommand } from '../clusters_util';
2022-01-26 12:08:38 +05:30
import {
INSTALL_AGENT_MODAL_ID,
I18N_AGENT_MODAL,
KAS_DISABLED_ERROR,
EVENT_LABEL_MODAL,
EVENT_ACTIONS_OPEN,
EVENT_ACTIONS_SELECT,
EVENT_ACTIONS_CLICK,
MODAL_TYPE_EMPTY,
MODAL_TYPE_REGISTER,
} from '../constants';
import { addAgentToStore, addAgentConfigToStore } from '../graphql/cache_update';
2021-11-18 22:05:49 +05:30
import createAgent from '../graphql/mutations/create_agent.mutation.graphql';
import createAgentToken from '../graphql/mutations/create_agent_token.mutation.graphql';
2021-12-11 22:18:48 +05:30
import getAgentsQuery from '../graphql/queries/get_agents.query.graphql';
2022-01-26 12:08:38 +05:30
import agentConfigurations from '../graphql/queries/agent_configurations.query.graphql';
2021-11-18 22:05:49 +05:30
import AvailableAgentsDropdown from './available_agents_dropdown.vue';
2022-01-26 12:08:38 +05:30
const trackingMixin = Tracking.mixin({ label: EVENT_LABEL_MODAL });
2021-11-18 22:05:49 +05:30
export default {
modalId: INSTALL_AGENT_MODAL_ID,
2022-01-26 12:08:38 +05:30
EVENT_ACTIONS_OPEN,
EVENT_ACTIONS_CLICK,
EVENT_LABEL_MODAL,
basicInstallPath: helpPagePath('user/clusters/agent/install/index', {
anchor: 'install-the-agent-into-the-cluster',
}),
advancedInstallPath: helpPagePath('user/clusters/agent/install/index', {
anchor: 'advanced-installation',
}),
enableKasPath: helpPagePath('administration/clusters/kas'),
installAgentPath: helpPagePath('user/clusters/agent/install/index'),
registerAgentPath: helpPagePath('user/clusters/agent/install/index', {
anchor: 'register-an-agent-with-gitlab',
}),
2021-11-18 22:05:49 +05:30
components: {
AvailableAgentsDropdown,
CodeBlock,
GlAlert,
GlButton,
GlFormGroup,
GlFormInputGroup,
GlLink,
GlModal,
GlSprintf,
2022-01-26 12:08:38 +05:30
ModalCopyButton,
2021-11-18 22:05:49 +05:30
},
2022-01-26 12:08:38 +05:30
mixins: [trackingMixin],
inject: ['projectPath', 'kasAddress', 'emptyStateImage'],
2021-12-11 22:18:48 +05:30
props: {
defaultBranchName: {
default: '.noBranch',
required: false,
type: String,
},
maxAgents: {
required: true,
type: Number,
},
},
2022-01-26 12:08:38 +05:30
apollo: {
agents: {
query: agentConfigurations,
variables() {
return {
projectPath: this.projectPath,
};
},
update(data) {
this.populateAvailableAgents(data);
},
error(error) {
this.kasDisabled = error?.message?.indexOf(KAS_DISABLED_ERROR) >= 0;
},
},
},
2021-11-18 22:05:49 +05:30
data() {
return {
registering: false,
agentName: null,
agentToken: null,
error: null,
2021-12-11 22:18:48 +05:30
clusterAgent: null,
2022-01-26 12:08:38 +05:30
availableAgents: [],
kasDisabled: false,
2021-11-18 22:05:49 +05:30
};
},
computed: {
registered() {
return Boolean(this.agentToken);
},
nextButtonDisabled() {
return !this.registering && this.agentName !== null;
},
canCancel() {
2022-01-26 12:08:38 +05:30
return !this.registered && !this.registering && this.isAgentRegistrationModal;
2021-11-18 22:05:49 +05:30
},
2022-04-04 11:22:00 +05:30
canRegister() {
return !this.registered && this.isAgentRegistrationModal;
},
2021-11-18 22:05:49 +05:30
agentRegistrationCommand() {
return generateAgentRegistrationCommand(this.agentToken, this.kasAddress);
},
2021-12-11 22:18:48 +05:30
getAgentsQueryVariables() {
return {
defaultBranchName: this.defaultBranchName,
first: this.maxAgents,
last: null,
projectPath: this.projectPath,
};
2021-11-18 22:05:49 +05:30
},
2022-01-26 12:08:38 +05:30
i18n() {
return I18N_AGENT_MODAL[this.modalType];
},
repositoryPath() {
return `/${this.projectPath}`;
},
modalType() {
return !this.availableAgents?.length && !this.registered
? MODAL_TYPE_EMPTY
: MODAL_TYPE_REGISTER;
},
modalSize() {
return this.isEmptyStateModal ? 'sm' : 'md';
},
isEmptyStateModal() {
return this.modalType === MODAL_TYPE_EMPTY;
},
isAgentRegistrationModal() {
return this.modalType === MODAL_TYPE_REGISTER;
},
2022-04-04 11:22:00 +05:30
isKasEnabledInEmptyStateModal() {
return this.isEmptyStateModal && !this.kasDisabled;
},
2021-11-18 22:05:49 +05:30
},
methods: {
setAgentName(name) {
this.agentName = name;
2022-01-26 12:08:38 +05:30
this.track(EVENT_ACTIONS_SELECT);
2021-11-18 22:05:49 +05:30
},
2021-12-11 22:18:48 +05:30
closeModal() {
2021-11-18 22:05:49 +05:30
this.$refs.modal.hide();
},
resetModal() {
2021-12-11 22:18:48 +05:30
this.registering = false;
2021-11-18 22:05:49 +05:30
this.agentName = null;
this.agentToken = null;
2022-01-26 12:08:38 +05:30
this.clusterAgent = null;
2021-11-18 22:05:49 +05:30
this.error = null;
},
2022-01-26 12:08:38 +05:30
populateAvailableAgents(data) {
const installedAgents = data?.project?.clusterAgents?.nodes.map((agent) => agent.name) ?? [];
const configuredAgents =
data?.project?.agentConfigurations?.nodes.map((config) => config.agentName) ?? [];
this.availableAgents = configuredAgents.filter((agent) => !installedAgents.includes(agent));
},
2021-11-18 22:05:49 +05:30
createAgentMutation() {
return this.$apollo
.mutate({
mutation: createAgent,
variables: {
input: {
name: this.agentName,
projectPath: this.projectPath,
},
},
2021-12-11 22:18:48 +05:30
update: (store, { data: { createClusterAgent } }) => {
addAgentToStore(
store,
createClusterAgent,
getAgentsQuery,
this.getAgentsQueryVariables,
);
},
2021-11-18 22:05:49 +05:30
})
2022-01-26 12:08:38 +05:30
.then(({ data: { createClusterAgent } }) => {
return createClusterAgent;
});
2021-11-18 22:05:49 +05:30
},
createAgentTokenMutation(agendId) {
return this.$apollo
.mutate({
mutation: createAgentToken,
variables: {
input: {
clusterAgentId: agendId,
name: this.agentName,
},
},
2022-01-26 12:08:38 +05:30
update: (store, { data: { clusterAgentTokenCreate } }) => {
addAgentConfigToStore(
store,
clusterAgentTokenCreate,
this.clusterAgent,
agentConfigurations,
{
projectPath: this.projectPath,
},
);
},
2021-11-18 22:05:49 +05:30
})
.then(({ data: { clusterAgentTokenCreate } }) => clusterAgentTokenCreate);
},
async registerAgent() {
this.registering = true;
this.error = null;
try {
const { errors: agentErrors, clusterAgent } = await this.createAgentMutation();
if (agentErrors?.length > 0) {
throw new Error(agentErrors[0]);
}
2021-12-11 22:18:48 +05:30
this.clusterAgent = clusterAgent;
2021-11-18 22:05:49 +05:30
const { errors: tokenErrors, secret } = await this.createAgentTokenMutation(
clusterAgent.id,
);
if (tokenErrors?.length > 0) {
throw new Error(tokenErrors[0]);
}
this.agentToken = secret;
} catch (error) {
if (error) {
this.error = error.message;
} else {
2022-01-26 12:08:38 +05:30
this.error = this.i18n.unknownError;
2021-11-18 22:05:49 +05:30
}
} finally {
this.registering = false;
}
},
},
};
</script>
<template>
<gl-modal
ref="modal"
:modal-id="$options.modalId"
2022-01-26 12:08:38 +05:30
:title="i18n.modalTitle"
:size="modalSize"
2021-11-18 22:05:49 +05:30
static
lazy
@hidden="resetModal"
2022-01-26 12:08:38 +05:30
@show="track($options.EVENT_ACTIONS_OPEN, { property: modalType })"
2021-11-18 22:05:49 +05:30
>
2022-01-26 12:08:38 +05:30
<template v-if="isAgentRegistrationModal">
<template v-if="!registered">
<p>
<strong>{{ i18n.selectAgentTitle }}</strong>
</p>
2021-11-18 22:05:49 +05:30
2022-01-26 12:08:38 +05:30
<p class="gl-mb-0">{{ i18n.selectAgentBody }}</p>
<p>
<gl-link :href="$options.registerAgentPath"> {{ i18n.learnMoreLink }}</gl-link>
</p>
2021-11-18 22:05:49 +05:30
2022-01-26 12:08:38 +05:30
<form>
<gl-form-group label-for="agent-name">
<available-agents-dropdown
class="gl-w-70p"
:is-registering="registering"
:available-agents="availableAgents"
@agentSelected="setAgentName"
/>
</gl-form-group>
</form>
2021-11-18 22:05:49 +05:30
2022-01-26 12:08:38 +05:30
<p v-if="error">
<gl-alert :title="i18n.registrationErrorTitle" variant="danger" :dismissible="false">
{{ error }}
</gl-alert>
</p>
</template>
2021-11-18 22:05:49 +05:30
2022-01-26 12:08:38 +05:30
<template v-else>
<p>
<strong>{{ i18n.tokenTitle }}</strong>
</p>
2021-11-18 22:05:49 +05:30
2022-01-26 12:08:38 +05:30
<p>
<gl-sprintf :message="i18n.tokenBody">
<template #link="{ content }">
<gl-link :href="$options.basicInstallPath" target="_blank"> {{ content }}</gl-link>
</template>
</gl-sprintf>
</p>
2021-11-18 22:05:49 +05:30
2022-01-26 12:08:38 +05:30
<p>
<gl-alert :title="i18n.tokenSingleUseWarningTitle" variant="warning" :dismissible="false">
{{ i18n.tokenSingleUseWarningBody }}
</gl-alert>
</p>
2021-11-18 22:05:49 +05:30
2022-01-26 12:08:38 +05:30
<p>
<gl-form-input-group readonly :value="agentToken" :select-on-click="true">
<template #append>
<modal-copy-button
:text="agentToken"
:title="i18n.copyToken"
:modal-id="$options.modalId"
/>
</template>
</gl-form-input-group>
</p>
2021-11-18 22:05:49 +05:30
2022-01-26 12:08:38 +05:30
<p>
<strong>{{ i18n.basicInstallTitle }}</strong>
</p>
2021-11-18 22:05:49 +05:30
2022-01-26 12:08:38 +05:30
<p>
{{ i18n.basicInstallBody }}
</p>
2021-11-18 22:05:49 +05:30
2022-01-26 12:08:38 +05:30
<p>
<code-block :code="agentRegistrationCommand" />
</p>
<p>
<strong>{{ i18n.advancedInstallTitle }}</strong>
</p>
<p>
<gl-sprintf :message="i18n.advancedInstallBody">
<template #link="{ content }">
<gl-link :href="$options.advancedInstallPath" target="_blank"> {{ content }}</gl-link>
</template>
</gl-sprintf>
</p>
</template>
</template>
<template v-else>
<div class="gl-text-center gl-mb-5">
<img :alt="i18n.altText" :src="emptyStateImage" height="100" />
</div>
2021-11-18 22:05:49 +05:30
2022-04-04 11:22:00 +05:30
<p v-if="kasDisabled">
<gl-sprintf :message="i18n.enableKasText">
2022-01-26 12:08:38 +05:30
<template #link="{ content }">
2022-04-04 11:22:00 +05:30
<gl-link :href="$options.enableKasPath">{{ content }}</gl-link>
2022-01-26 12:08:38 +05:30
</template>
</gl-sprintf>
2021-11-18 22:05:49 +05:30
</p>
2022-04-04 11:22:00 +05:30
<p v-else>
<gl-sprintf :message="i18n.modalBody">
2021-11-18 22:05:49 +05:30
<template #link="{ content }">
2022-04-04 11:22:00 +05:30
<gl-link :href="$options.installAgentPath">{{ content }}</gl-link>
2021-11-18 22:05:49 +05:30
</template>
</gl-sprintf>
</p>
</template>
<template #modal-footer>
2022-01-26 12:08:38 +05:30
<gl-button
v-if="registered"
variant="confirm"
category="primary"
:data-track-action="$options.EVENT_ACTIONS_CLICK"
:data-track-label="$options.EVENT_LABEL_MODAL"
data-track-property="close"
@click="closeModal"
>{{ i18n.close }}
2021-11-18 22:05:49 +05:30
</gl-button>
<gl-button
2022-04-04 11:22:00 +05:30
v-if="canCancel"
:data-track-action="$options.EVENT_ACTIONS_CLICK"
:data-track-label="$options.EVENT_LABEL_MODAL"
data-track-property="cancel"
@click="closeModal"
>{{ i18n.cancel }}
</gl-button>
<gl-button
v-if="canRegister"
2021-11-18 22:05:49 +05:30
:disabled="!nextButtonDisabled"
variant="confirm"
category="primary"
2022-01-26 12:08:38 +05:30
:data-track-action="$options.EVENT_ACTIONS_CLICK"
:data-track-label="$options.EVENT_LABEL_MODAL"
data-track-property="register"
2021-11-18 22:05:49 +05:30
@click="registerAgent"
2022-01-26 12:08:38 +05:30
>{{ i18n.registerAgentButton }}
</gl-button>
<gl-button
2022-04-04 11:22:00 +05:30
v-if="isEmptyStateModal"
2022-01-26 12:08:38 +05:30
:data-track-action="$options.EVENT_ACTIONS_CLICK"
:data-track-label="$options.EVENT_LABEL_MODAL"
2022-04-04 11:22:00 +05:30
data-track-property="done"
2022-01-26 12:08:38 +05:30
@click="closeModal"
2022-04-04 11:22:00 +05:30
>{{ i18n.done }}
2022-01-26 12:08:38 +05:30
</gl-button>
<gl-button
2022-04-04 11:22:00 +05:30
v-if="isKasEnabledInEmptyStateModal"
2022-01-26 12:08:38 +05:30
:href="repositoryPath"
variant="confirm"
category="primary"
2022-04-04 11:22:00 +05:30
data-testid="agent-primary-button"
>{{ i18n.primaryButton }}
2021-11-18 22:05:49 +05:30
</gl-button>
</template>
</gl-modal>
</template>