summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/clusters
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-08-20 18:42:06 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-08-20 18:42:06 +0000
commit6e4e1050d9dba2b7b2523fdd1768823ab85feef4 (patch)
tree78be5963ec075d80116a932011d695dd33910b4e /app/assets/javascripts/clusters
parent1ce776de4ae122aba3f349c02c17cebeaa8ecf07 (diff)
downloadgitlab-ce-6e4e1050d9dba2b7b2523fdd1768823ab85feef4.tar.gz
Add latest changes from gitlab-org/gitlab@13-3-stable-ee
Diffstat (limited to 'app/assets/javascripts/clusters')
-rw-r--r--app/assets/javascripts/clusters/clusters_bundle.js37
-rw-r--r--app/assets/javascripts/clusters/components/application_row.vue22
-rw-r--r--app/assets/javascripts/clusters/components/applications.vue101
-rw-r--r--app/assets/javascripts/clusters/components/crossplane_provider_stack.vue18
-rw-r--r--app/assets/javascripts/clusters/components/fluentd_output_settings.vue22
-rw-r--r--app/assets/javascripts/clusters/components/ingress_modsecurity_settings.vue26
-rw-r--r--app/assets/javascripts/clusters/components/knative_domain_editor.vue26
-rw-r--r--app/assets/javascripts/clusters/components/remove_cluster_confirmation.vue41
-rw-r--r--app/assets/javascripts/clusters/constants.js1
-rw-r--r--app/assets/javascripts/clusters/forms/components/integration_form.vue163
-rw-r--r--app/assets/javascripts/clusters/forms/show/index.js27
-rw-r--r--app/assets/javascripts/clusters/forms/stores/index.js12
-rw-r--r--app/assets/javascripts/clusters/forms/stores/state.js13
-rw-r--r--app/assets/javascripts/clusters/services/application_state_machine.js36
-rw-r--r--app/assets/javascripts/clusters/stores/clusters_store.js8
15 files changed, 397 insertions, 156 deletions
diff --git a/app/assets/javascripts/clusters/clusters_bundle.js b/app/assets/javascripts/clusters/clusters_bundle.js
index 83bdea15e62..92517203972 100644
--- a/app/assets/javascripts/clusters/clusters_bundle.js
+++ b/app/assets/javascripts/clusters/clusters_bundle.js
@@ -4,23 +4,15 @@ import { GlToast } from '@gitlab/ui';
import AccessorUtilities from '~/lib/utils/accessor';
import PersistentUserCallout from '../persistent_user_callout';
import { s__, sprintf } from '../locale';
-import Flash from '../flash';
+import { deprecatedCreateFlash as Flash } from '../flash';
import Poll from '../lib/utils/poll';
import initSettingsPanels from '../settings_panels';
import eventHub from './event_hub';
-import {
- APPLICATION_STATUS,
- INGRESS,
- INGRESS_DOMAIN_SUFFIX,
- CROSSPLANE,
- KNATIVE,
- FLUENTD,
-} from './constants';
+import { APPLICATION_STATUS, CROSSPLANE, KNATIVE, FLUENTD } from './constants';
import ClustersService from './services/clusters_service';
import ClustersStore from './stores/clusters_store';
import Applications from './components/applications.vue';
import RemoveClusterConfirmation from './components/remove_cluster_confirmation.vue';
-import setupToggleButtons from '../toggle_buttons';
import initProjectSelectDropdown from '~/project_select';
import initServerlessSurveyBanner from '~/serverless/survey_banner';
@@ -68,6 +60,7 @@ export default class Clusters {
deployBoardsHelpPath,
cloudRunHelpPath,
clusterId,
+ ciliumHelpPath,
} = document.querySelector('.js-edit-cluster-form').dataset;
this.clusterId = clusterId;
@@ -84,6 +77,7 @@ export default class Clusters {
clustersHelpPath,
deployBoardsHelpPath,
cloudRunHelpPath,
+ ciliumHelpPath,
);
this.store.setManagePrometheusPath(managePrometheusPath);
this.store.updateStatus(clusterStatus);
@@ -119,19 +113,11 @@ export default class Clusters {
this.errorReasonContainer = this.errorContainer.querySelector('.js-error-reason');
this.successApplicationContainer = document.querySelector('.js-cluster-application-notice');
this.tokenField = document.querySelector('.js-cluster-token');
- this.ingressDomainHelpText = document.querySelector('.js-ingress-domain-help-text');
- this.ingressDomainSnippet =
- this.ingressDomainHelpText &&
- this.ingressDomainHelpText.querySelector('.js-ingress-domain-snippet');
initProjectSelectDropdown();
Clusters.initDismissableCallout();
initSettingsPanels();
- const toggleButtonsContainer = document.querySelector('.js-cluster-enable-toggle-area');
- if (toggleButtonsContainer) {
- setupToggleButtons(toggleButtonsContainer);
- }
this.initApplications(clusterType);
this.initEnvironments();
@@ -184,6 +170,7 @@ export default class Clusters {
providerType: this.state.providerType,
preInstalledKnative: this.state.preInstalledKnative,
rbac: this.state.rbac,
+ ciliumHelpPath: this.state.ciliumHelpPath,
},
});
},
@@ -329,13 +316,6 @@ export default class Clusters {
this.checkForNewInstalls(prevApplicationMap, this.store.state.applications);
this.updateContainer(prevStatus, this.store.state.status, this.store.state.statusReason);
- if (this.ingressDomainHelpText) {
- this.toggleIngressDomainHelpText(
- prevApplicationMap[INGRESS],
- this.store.state.applications[INGRESS],
- );
- }
-
if (this.store.state.applications[KNATIVE]?.status === APPLICATION_STATUS.INSTALLED) {
initServerlessSurveyBanner();
}
@@ -507,13 +487,6 @@ export default class Clusters {
});
}
- toggleIngressDomainHelpText({ externalIp }, { externalIp: newExternalIp }) {
- if (externalIp !== newExternalIp) {
- this.ingressDomainHelpText.classList.toggle('hide', !newExternalIp);
- this.ingressDomainSnippet.textContent = `${newExternalIp}${INGRESS_DOMAIN_SUFFIX}`;
- }
- }
-
saveKnativeDomain(data) {
const appId = data.id;
this.store.updateApplication(appId);
diff --git a/app/assets/javascripts/clusters/components/application_row.vue b/app/assets/javascripts/clusters/components/application_row.vue
index ba6de41e025..c86db28515f 100644
--- a/app/assets/javascripts/clusters/components/application_row.vue
+++ b/app/assets/javascripts/clusters/components/application_row.vue
@@ -52,6 +52,11 @@ export default {
required: false,
default: false,
},
+ installable: {
+ type: Boolean,
+ required: false,
+ default: true,
+ },
uninstallable: {
type: Boolean,
required: false,
@@ -141,6 +146,7 @@ export default {
return (
this.status === APPLICATION_STATUS.NOT_INSTALLABLE ||
this.status === APPLICATION_STATUS.INSTALLABLE ||
+ this.status === APPLICATION_STATUS.UNINSTALLED ||
this.isUnknownStatus
);
},
@@ -164,14 +170,20 @@ export default {
return !this.status || this.isInstalling;
},
installButtonDisabled() {
+ // Applications installed through the management project can
+ // only be installed through the CI pipeline. Installation should
+ // be disable in all states.
+ if (!this.installable) return true;
+
// Avoid the potential for the real-time data to say APPLICATION_STATUS.INSTALLABLE but
// we already made a request to install and are just waiting for the real-time
// to sync up.
+ if (this.isInstalling) return true;
+
+ if (!this.isKnownStatus) return false;
+
return (
- ((this.status !== APPLICATION_STATUS.INSTALLABLE &&
- this.status !== APPLICATION_STATUS.ERROR) ||
- this.isInstalling) &&
- this.isKnownStatus
+ this.status !== APPLICATION_STATUS.INSTALLABLE && this.status !== APPLICATION_STATUS.ERROR
);
},
installButtonLabel() {
@@ -335,7 +347,7 @@ export default {
<div>
<slot name="description"></slot>
</div>
- <div v-if="hasError" class="cluster-application-error text-danger prepend-top-10">
+ <div v-if="hasError" class="cluster-application-error text-danger gl-mt-3">
<p class="js-cluster-application-general-error-message gl-mb-0">
{{ generalErrorDescription }}
</p>
diff --git a/app/assets/javascripts/clusters/components/applications.vue b/app/assets/javascripts/clusters/components/applications.vue
index 214906021ad..039237042ea 100644
--- a/app/assets/javascripts/clusters/components/applications.vue
+++ b/app/assets/javascripts/clusters/components/applications.vue
@@ -1,8 +1,6 @@
<script>
-import helmInstallIllustration from '@gitlab/svgs/dist/illustrations/kubernetes-installation.svg';
import { GlLoadingIcon, GlSprintf, GlLink } from '@gitlab/ui';
import gitlabLogo from 'images/cluster_app_logos/gitlab.png';
-import helmLogo from 'images/cluster_app_logos/helm.png';
import jupyterhubLogo from 'images/cluster_app_logos/jupyterhub.png';
import kubernetesLogo from 'images/cluster_app_logos/kubernetes.png';
import certManagerLogo from 'images/cluster_app_logos/cert_manager.png';
@@ -88,18 +86,13 @@ export default {
required: false,
default: false,
},
+ ciliumHelpPath: {
+ type: String,
+ required: false,
+ default: '',
+ },
},
computed: {
- managedAppsLocalTillerEnabled() {
- return Boolean(gon.features?.managedAppsLocalTiller);
- },
- helmInstalled() {
- return (
- this.managedAppsLocalTillerEnabled ||
- this.applications.helm.status === APPLICATION_STATUS.INSTALLED ||
- this.applications.helm.status === APPLICATION_STATUS.UPDATED
- );
- },
ingressId() {
return INGRESS;
},
@@ -157,7 +150,6 @@ export default {
},
logos: {
gitlabLogo,
- helmLogo,
jupyterhubLogo,
kubernetesLogo,
certManagerLogo,
@@ -167,7 +159,6 @@ export default {
elasticStackLogo,
fluentdLogo,
},
- helmInstallIllustration,
};
</script>
@@ -175,46 +166,12 @@ export default {
<section id="cluster-applications">
<p class="gl-mb-0">
{{
- s__(`ClusterIntegration|Choose which applications to install on your Kubernetes cluster.
- Helm Tiller is required to install any of the following applications.`)
+ s__(`ClusterIntegration|Choose which applications to install on your Kubernetes cluster.`)
}}
<gl-link :href="helpPath">{{ __('More information') }}</gl-link>
</p>
- <div class="cluster-application-list prepend-top-10">
- <application-row
- v-if="!managedAppsLocalTillerEnabled"
- id="helm"
- :logo-url="$options.logos.helmLogo"
- :title="applications.helm.title"
- :status="applications.helm.status"
- :status-reason="applications.helm.statusReason"
- :request-status="applications.helm.requestStatus"
- :request-reason="applications.helm.requestReason"
- :installed="applications.helm.installed"
- :install-failed="applications.helm.installFailed"
- :uninstallable="applications.helm.uninstallable"
- :uninstall-successful="applications.helm.uninstallSuccessful"
- :uninstall-failed="applications.helm.uninstallFailed"
- class="rounded-top"
- title-link="https://docs.helm.sh/"
- >
- <template #description>
- {{
- s__(`ClusterIntegration|Helm streamlines installing
- and managing Kubernetes applications.
- Tiller runs inside of your Kubernetes Cluster,
- and manages releases of your charts.`)
- }}
- </template>
- </application-row>
- <div v-show="!helmInstalled" class="cluster-application-warning">
- <div class="svg-container" v-html="$options.helmInstallIllustration"></div>
- {{
- s__(`ClusterIntegration|You must first install Helm Tiller before
- installing the applications below`)
- }}
- </div>
+ <div class="cluster-application-list gl-mt-3">
<application-row
:id="ingressId"
:logo-url="$options.logos.kubernetesLogo"
@@ -232,7 +189,6 @@ export default {
:uninstallable="applications.ingress.uninstallable"
:uninstall-successful="applications.ingress.uninstallSuccessful"
:uninstall-failed="applications.ingress.uninstallFailed"
- :disabled="!helmInstalled"
:updateable="false"
title-link="https://kubernetes.io/docs/concepts/services-networking/ingress/"
>
@@ -335,7 +291,6 @@ export default {
:uninstallable="applications.cert_manager.uninstallable"
:uninstall-successful="applications.cert_manager.uninstallSuccessful"
:uninstall-failed="applications.cert_manager.uninstallFailed"
- :disabled="!helmInstalled"
title-link="https://cert-manager.readthedocs.io/en/latest/#"
>
<template #description>
@@ -393,7 +348,6 @@ export default {
:uninstallable="applications.prometheus.uninstallable"
:uninstall-successful="applications.prometheus.uninstallSuccessful"
:uninstall-failed="applications.prometheus.uninstallFailed"
- :disabled="!helmInstalled"
title-link="https://prometheus.io/docs/introduction/overview/"
>
<template #description>
@@ -433,7 +387,6 @@ export default {
:uninstallable="applications.runner.uninstallable"
:uninstall-successful="applications.runner.uninstallSuccessful"
:uninstall-failed="applications.runner.uninstallFailed"
- :disabled="!helmInstalled"
title-link="https://docs.gitlab.com/runner/"
>
<template #description>
@@ -459,7 +412,6 @@ export default {
:uninstall-successful="applications.crossplane.uninstallSuccessful"
:uninstall-failed="applications.crossplane.uninstallFailed"
:install-application-request-params="{ stack: applications.crossplane.stack }"
- :disabled="!helmInstalled"
title-link="https://crossplane.io"
>
<template #description>
@@ -504,7 +456,6 @@ export default {
:uninstall-successful="applications.jupyter.uninstallSuccessful"
:uninstall-failed="applications.jupyter.uninstallFailed"
:install-application-request-params="{ hostname: applications.jupyter.hostname }"
- :disabled="!helmInstalled"
title-link="https://jupyterhub.readthedocs.io/en/stable/"
>
<template #description>
@@ -570,7 +521,6 @@ export default {
:uninstall-successful="applications.knative.uninstallSuccessful"
:uninstall-failed="applications.knative.uninstallFailed"
:updateable="false"
- :disabled="!helmInstalled"
v-bind="applications.knative"
title-link="https://github.com/knative/docs"
>
@@ -592,7 +542,7 @@ export default {
</p>
<knative-domain-editor
- v-if="(knative.installed || (helmInstalled && rbac)) && !preInstalledKnative"
+ v-if="(knative.installed || rbac) && !preInstalledKnative"
:knative="knative"
:ingress-dns-help-path="ingressDnsHelpPath"
@save="saveKnativeDomain"
@@ -629,7 +579,6 @@ export default {
:uninstallable="applications.elastic_stack.uninstallable"
:uninstall-successful="applications.elastic_stack.uninstallSuccessful"
:uninstall-failed="applications.elastic_stack.uninstallFailed"
- :disabled="!helmInstalled"
title-link="https://gitlab.com/gitlab-org/charts/elastic-stack"
>
<template #description>
@@ -663,7 +612,6 @@ export default {
:uninstallable="applications.fluentd.uninstallable"
:uninstall-successful="applications.fluentd.uninstallSuccessful"
:uninstall-failed="applications.fluentd.uninstallFailed"
- :disabled="!helmInstalled"
:updateable="false"
title-link="https://github.com/helm/charts/tree/master/stable/fluentd"
>
@@ -687,6 +635,39 @@ export default {
/>
</template>
</application-row>
+
+ <div class="gl-mt-7 gl-border-1 gl-border-t-solid gl-border-gray-100">
+ <!-- This empty div serves as a separator. The applications below can be externally installed using a cluster-management project. -->
+ </div>
+
+ <application-row
+ id="cilium"
+ :title="applications.cilium.title"
+ :logo-url="$options.logos.gitlabLogo"
+ :status="applications.cilium.status"
+ :status-reason="applications.cilium.statusReason"
+ :installable="applications.cilium.installable"
+ :uninstallable="applications.cilium.uninstallable"
+ :installed="applications.cilium.installed"
+ :install-failed="applications.cilium.installFailed"
+ :title-link="ciliumHelpPath"
+ >
+ <template #description>
+ <p data-testid="ciliumDescription">
+ <gl-sprintf
+ :message="
+ s__(
+ 'ClusterIntegration|Protect your clusters with GitLab Container Network Policies by enforcing how pods communicate with each other and other network endpoints. %{linkStart}Learn more about configuring Network Policies here.%{linkEnd}',
+ )
+ "
+ >
+ <template #link="{ content }">
+ <gl-link :href="ciliumHelpPath" target="_blank">{{ content }}</gl-link>
+ </template>
+ </gl-sprintf>
+ </p>
+ </template>
+ </application-row>
</div>
</section>
</template>
diff --git a/app/assets/javascripts/clusters/components/crossplane_provider_stack.vue b/app/assets/javascripts/clusters/components/crossplane_provider_stack.vue
index 6b99bb09504..c816fc56d7a 100644
--- a/app/assets/javascripts/clusters/components/crossplane_provider_stack.vue
+++ b/app/assets/javascripts/clusters/components/crossplane_provider_stack.vue
@@ -1,12 +1,12 @@
<script>
-import { GlDropdown, GlDropdownItem, GlIcon } from '@gitlab/ui';
+import { GlDeprecatedDropdown, GlDeprecatedDropdownItem, GlIcon } from '@gitlab/ui';
import { s__ } from '../../locale';
export default {
name: 'CrossplaneProviderStack',
components: {
- GlDropdown,
- GlDropdownItem,
+ GlDeprecatedDropdown,
+ GlDeprecatedDropdownItem,
GlIcon,
},
props: {
@@ -67,17 +67,21 @@ export default {
<label>
{{ s__('ClusterIntegration|Enabled stack') }}
</label>
- <gl-dropdown
+ <gl-deprecated-dropdown
:disabled="crossplane.installed"
:text="dropdownText"
toggle-class="dropdown-menu-toggle gl-field-error-outline"
class="w-100"
:class="{ 'gl-show-field-errors': validationError }"
>
- <gl-dropdown-item v-for="stack in stacks" :key="stack.code" @click="selectStack(stack)">
+ <gl-deprecated-dropdown-item
+ v-for="stack in stacks"
+ :key="stack.code"
+ @click="selectStack(stack)"
+ >
<span class="ml-1">{{ stack.name }}</span>
- </gl-dropdown-item>
- </gl-dropdown>
+ </gl-deprecated-dropdown-item>
+ </gl-deprecated-dropdown>
<span v-if="validationError" class="gl-field-error">{{ validationError }}</span>
<p class="form-text text-muted">
{{ s__(`You must select a stack for configuring your cloud provider. Learn more about`) }}
diff --git a/app/assets/javascripts/clusters/components/fluentd_output_settings.vue b/app/assets/javascripts/clusters/components/fluentd_output_settings.vue
index 20f6210aba8..e6001b11296 100644
--- a/app/assets/javascripts/clusters/components/fluentd_output_settings.vue
+++ b/app/assets/javascripts/clusters/components/fluentd_output_settings.vue
@@ -1,15 +1,15 @@
<script>
-import { __ } from '~/locale';
-import { APPLICATION_STATUS, FLUENTD } from '~/clusters/constants';
import {
GlAlert,
GlDeprecatedButton,
- GlDropdown,
- GlDropdownItem,
+ GlDeprecatedDropdown,
+ GlDeprecatedDropdownItem,
GlFormCheckbox,
} from '@gitlab/ui';
-import eventHub from '~/clusters/event_hub';
import { mapValues } from 'lodash';
+import { __ } from '~/locale';
+import { APPLICATION_STATUS, FLUENTD } from '~/clusters/constants';
+import eventHub from '~/clusters/event_hub';
const { UPDATING, UNINSTALLING, INSTALLING, INSTALLED, UPDATED } = APPLICATION_STATUS;
@@ -17,8 +17,8 @@ export default {
components: {
GlAlert,
GlDeprecatedButton,
- GlDropdown,
- GlDropdownItem,
+ GlDeprecatedDropdown,
+ GlDeprecatedDropdownItem,
GlFormCheckbox,
},
props: {
@@ -203,15 +203,15 @@ export default {
<label for="fluentd-protocol">
<strong>{{ s__('ClusterIntegration|SIEM Protocol') }}</strong>
</label>
- <gl-dropdown :text="protocolName" class="w-100">
- <gl-dropdown-item
+ <gl-deprecated-dropdown :text="protocolName" class="w-100">
+ <gl-deprecated-dropdown-item
v-for="(value, index) in protocols"
:key="index"
@click="selectProtocol(value.toLowerCase())"
>
{{ value }}
- </gl-dropdown-item>
- </gl-dropdown>
+ </gl-deprecated-dropdown-item>
+ </gl-deprecated-dropdown>
</div>
<div class="form-group flex flex-wrap">
<gl-form-checkbox :checked="wafLogEnabled" @input="wafLogChanged">
diff --git a/app/assets/javascripts/clusters/components/ingress_modsecurity_settings.vue b/app/assets/javascripts/clusters/components/ingress_modsecurity_settings.vue
index 87c3225085f..5e8e1a76182 100644
--- a/app/assets/javascripts/clusters/components/ingress_modsecurity_settings.vue
+++ b/app/assets/javascripts/clusters/components/ingress_modsecurity_settings.vue
@@ -1,19 +1,19 @@
<script>
import { escape } from 'lodash';
-import { s__, __ } from '../../locale';
-import { APPLICATION_STATUS, INGRESS, LOGGING_MODE, BLOCKING_MODE } from '~/clusters/constants';
import {
GlAlert,
GlSprintf,
GlLink,
GlToggle,
GlDeprecatedButton,
- GlDropdown,
- GlDropdownItem,
+ GlDeprecatedDropdown,
+ GlDeprecatedDropdownItem,
GlIcon,
} from '@gitlab/ui';
-import eventHub from '~/clusters/event_hub';
import modSecurityLogo from 'images/cluster_app_logos/gitlab.png';
+import { s__, __ } from '../../locale';
+import { APPLICATION_STATUS, INGRESS, LOGGING_MODE, BLOCKING_MODE } from '~/clusters/constants';
+import eventHub from '~/clusters/event_hub';
const { UPDATING, UNINSTALLING, INSTALLING, INSTALLED, UPDATED } = APPLICATION_STATUS;
@@ -26,8 +26,8 @@ export default {
GlLink,
GlToggle,
GlDeprecatedButton,
- GlDropdown,
- GlDropdownItem,
+ GlDeprecatedDropdown,
+ GlDeprecatedDropdownItem,
GlIcon,
},
props: {
@@ -221,11 +221,15 @@ export default {
</strong>
</p>
</div>
- <gl-dropdown :text="modSecurityModeName" :disabled="saveButtonDisabled">
- <gl-dropdown-item v-for="(mode, key) in modes" :key="key" @click="selectMode(key)">
+ <gl-deprecated-dropdown :text="modSecurityModeName" :disabled="saveButtonDisabled">
+ <gl-deprecated-dropdown-item
+ v-for="(mode, key) in modes"
+ :key="key"
+ @click="selectMode(key)"
+ >
{{ mode.name }}
- </gl-dropdown-item>
- </gl-dropdown>
+ </gl-deprecated-dropdown-item>
+ </gl-deprecated-dropdown>
</div>
</div>
<div v-if="showButtons" class="mt-3">
diff --git a/app/assets/javascripts/clusters/components/knative_domain_editor.vue b/app/assets/javascripts/clusters/components/knative_domain_editor.vue
index ac61cd8e242..1236d2a46c9 100644
--- a/app/assets/javascripts/clusters/components/knative_domain_editor.vue
+++ b/app/assets/javascripts/clusters/components/knative_domain_editor.vue
@@ -1,8 +1,8 @@
<script>
import {
- GlDropdown,
- GlDropdownDivider,
- GlDropdownItem,
+ GlDeprecatedDropdown,
+ GlDeprecatedDropdownDivider,
+ GlDeprecatedDropdownItem,
GlLoadingIcon,
GlSearchBoxByType,
GlSprintf,
@@ -20,9 +20,9 @@ export default {
LoadingButton,
ClipboardButton,
GlLoadingIcon,
- GlDropdown,
- GlDropdownDivider,
- GlDropdownItem,
+ GlDeprecatedDropdown,
+ GlDeprecatedDropdownDivider,
+ GlDeprecatedDropdownItem,
GlSearchBoxByType,
GlSprintf,
},
@@ -121,7 +121,7 @@ export default {
<strong>{{ s__('ClusterIntegration|Knative Domain Name:') }}</strong>
</label>
- <gl-dropdown
+ <gl-deprecated-dropdown
v-if="showDomainsDropdown"
:text="domainDropdownText"
toggle-class="dropdown-menu-toggle"
@@ -132,16 +132,16 @@ export default {
:placeholder="s__('ClusterIntegration|Search domains')"
class="m-2"
/>
- <gl-dropdown-item
+ <gl-deprecated-dropdown-item
v-for="domain in filteredDomains"
:key="domain.id"
@click="selectDomain(domain)"
>
<span class="ml-1">{{ domain.domain }}</span>
- </gl-dropdown-item>
+ </gl-deprecated-dropdown-item>
<template v-if="searchQuery">
- <gl-dropdown-divider />
- <gl-dropdown-item key="custom-domain" @click="selectCustomDomain(searchQuery)">
+ <gl-deprecated-dropdown-divider />
+ <gl-deprecated-dropdown-item key="custom-domain" @click="selectCustomDomain(searchQuery)">
<span class="ml-1">
<gl-sprintf :message="s__('ClusterIntegration|Use %{query}')">
<template #query>
@@ -149,9 +149,9 @@ export default {
</template>
</gl-sprintf>
</span>
- </gl-dropdown-item>
+ </gl-deprecated-dropdown-item>
</template>
- </gl-dropdown>
+ </gl-deprecated-dropdown>
<input
v-else
diff --git a/app/assets/javascripts/clusters/components/remove_cluster_confirmation.vue b/app/assets/javascripts/clusters/components/remove_cluster_confirmation.vue
index 45f2dd48961..3e3b102f0aa 100644
--- a/app/assets/javascripts/clusters/components/remove_cluster_confirmation.vue
+++ b/app/assets/javascripts/clusters/components/remove_cluster_confirmation.vue
@@ -1,7 +1,7 @@
<script>
import { escape } from 'lodash';
+import { GlModal, GlButton, GlDeprecatedButton, GlFormInput, GlSprintf } from '@gitlab/ui';
import SplitButton from '~/vue_shared/components/split_button.vue';
-import { GlModal, GlButton, GlDeprecatedButton, GlFormInput } from '@gitlab/ui';
import { s__, sprintf } from '~/locale';
import csrf from '~/lib/utils/csrf';
@@ -30,6 +30,7 @@ export default {
GlButton,
GlDeprecatedButton,
GlFormInput,
+ GlSprintf,
},
props: {
clusterPath: {
@@ -67,18 +68,6 @@ export default {
)
: s__('ClusterIntegration|You are about to remove your cluster integration.');
},
- warningToBeRemoved() {
- return s__(`ClusterIntegration|
- This will permanently delete the following resources:
- <ul>
- <li>All installed applications and related resources</li>
- <li>The <code>gitlab-managed-apps</code> namespace</li>
- <li>Any project namespaces</li>
- <li><code>clusterroles</code></li>
- <li><code>clusterrolebindings</code></li>
- </ul>
- `);
- },
confirmationTextLabel() {
return sprintf(
this.confirmCleanup
@@ -118,7 +107,7 @@ export default {
</script>
<template>
- <div>
+ <div class="gl-display-flex gl-justify-content-end">
<split-button
v-if="canCleanupResources"
:action-items="$options.splitButtonActionItems"
@@ -144,9 +133,29 @@ export default {
>
<template>
<p>{{ warningMessage }}</p>
- <div v-if="confirmCleanup" v-html="warningToBeRemoved"></div>
+ <div v-if="confirmCleanup">
+ {{ s__('ClusterIntegration|This will permanently delete the following resources:') }}
+ <ul>
+ <li>
+ {{ s__('ClusterIntegration|All installed applications and related resources') }}
+ </li>
+ <li>
+ <gl-sprintf :message="s__('ClusterIntegration|The %{gitlabNamespace} namespace')">
+ <template #gitlabNamespace>
+ <!-- eslint-disable-next-line @gitlab/vue-require-i18n-strings -->
+ <code>{{ 'gitlab-managed-apps' }}</code>
+ </template>
+ </gl-sprintf>
+ </li>
+ <li>{{ s__('ClusterIntegration|Any project namespaces') }}</li>
+ <!-- eslint-disable @gitlab/vue-require-i18n-strings -->
+ <li><code>clusterroles</code></li>
+ <li><code>clusterrolebindings</code></li>
+ <!-- eslint-enable @gitlab/vue-require-i18n-strings -->
+ </ul>
+ </div>
<strong v-html="confirmationTextLabel"></strong>
- <form ref="form" :action="clusterPath" method="post" class="append-bottom-20">
+ <form ref="form" :action="clusterPath" method="post" class="gl-mb-5">
<input ref="method" type="hidden" name="_method" value="delete" />
<input :value="csrfToken" type="hidden" name="authenticity_token" />
<input ref="cleanup" type="hidden" name="cleanup" value="true" />
diff --git a/app/assets/javascripts/clusters/constants.js b/app/assets/javascripts/clusters/constants.js
index 60e179c54eb..e2227c61cee 100644
--- a/app/assets/javascripts/clusters/constants.js
+++ b/app/assets/javascripts/clusters/constants.js
@@ -25,6 +25,7 @@ export const APPLICATION_STATUS = {
UNINSTALL_ERRORED: 'uninstall_errored',
ERROR: 'errored',
PRE_INSTALLED: 'pre_installed',
+ UNINSTALLED: 'uninstalled',
};
/*
diff --git a/app/assets/javascripts/clusters/forms/components/integration_form.vue b/app/assets/javascripts/clusters/forms/components/integration_form.vue
new file mode 100644
index 00000000000..53e004b4fc0
--- /dev/null
+++ b/app/assets/javascripts/clusters/forms/components/integration_form.vue
@@ -0,0 +1,163 @@
+<script>
+import {
+ GlFormGroup,
+ GlFormInput,
+ GlToggle,
+ GlTooltipDirective,
+ GlSprintf,
+ GlLink,
+ GlButton,
+} from '@gitlab/ui';
+import { mapState } from 'vuex';
+
+export default {
+ components: {
+ GlFormGroup,
+ GlToggle,
+ GlFormInput,
+ GlSprintf,
+ GlLink,
+ GlButton,
+ },
+ directives: {
+ GlTooltip: GlTooltipDirective,
+ },
+ inject: {
+ autoDevopsHelpPath: {
+ type: String,
+ },
+ externalEndpointHelpPath: {
+ type: String,
+ },
+ },
+ data() {
+ return {
+ toggleEnabled: true,
+ envScope: '*',
+ baseDomainField: '',
+ externalIp: '',
+ };
+ },
+ computed: {
+ ...mapState([
+ 'enabled',
+ 'editable',
+ 'environmentScope',
+ 'baseDomain',
+ 'applicationIngressExternalIp',
+ ]),
+ canSubmit() {
+ return (
+ this.enabled !== this.toggleEnabled ||
+ this.environmentScope !== this.envScope ||
+ this.baseDomain !== this.baseDomainField
+ );
+ },
+ },
+ mounted() {
+ this.toggleEnabled = this.enabled;
+ this.envScope = this.environmentScope;
+ this.baseDomainField = this.baseDomain;
+ this.externalIp = this.applicationIngressExternalIp;
+ },
+};
+</script>
+
+<template>
+ <div class="d-flex gl-flex-direction-column">
+ <gl-form-group>
+ <div class="gl-display-flex gl-align-items-center">
+ <h4 class="gl-pr-3 gl-m-0">{{ s__('ClusterIntegration|GitLab Integration') }}</h4>
+
+ <div class="js-cluster-enable-toggle-area">
+ <gl-toggle
+ id="toggleCluster"
+ v-model="toggleEnabled"
+ v-gl-tooltip:tooltipcontainer
+ name="cluster[enabled]"
+ class="gl-mb-0 js-project-feature-toggle"
+ data-qa-selector="integration_status_toggle"
+ aria-describedby="toggleCluster"
+ :disabled="!editable"
+ :title="
+ s__(
+ 'ClusterIntegration|Enable or disable GitLab\'s connection to your Kubernetes cluster.',
+ )
+ "
+ />
+ </div>
+ </div>
+ </gl-form-group>
+
+ <gl-form-group
+ :label="s__('ClusterIntegration|Environment scope')"
+ label-size="sm"
+ label-for="cluster_environment_scope"
+ :description="
+ s__('ClusterIntegration|Choose which of your environments will use this cluster.')
+ "
+ >
+ <gl-form-input
+ id="cluster_environment_scope"
+ v-model="envScope"
+ name="cluster[environment_scope]"
+ class="col-md-6"
+ type="text"
+ />
+ </gl-form-group>
+
+ <gl-form-group
+ :label="s__('ClusterIntegration|Base domain')"
+ label-size="sm"
+ label-for="cluster_base_domain"
+ >
+ <gl-form-input
+ id="cluster_base_domain"
+ v-model="baseDomainField"
+ name="cluster[base_domain]"
+ data-qa-selector="base_domain_field"
+ class="col-md-6"
+ type="text"
+ />
+ <div class="form-text text-muted inline">
+ <gl-sprintf
+ :message="
+ s__(
+ 'ClusterIntegration|Specifying a domain will allow you to use Auto Review Apps and Auto Deploy stages for %{linkStart}Auto DevOps.%{linkEnd} The domain should have a wildcard DNS configured matching the domain. ',
+ )
+ "
+ >
+ <template #link="{ content }">
+ <gl-link :href="autoDevopsHelpPath" target="_blank">{{ content }}</gl-link>
+ </template>
+ </gl-sprintf>
+ <div v-if="applicationIngressExternalIp" class="js-ingress-domain-help-text inline">
+ {{ s__('ClusterIntegration|Alternatively, ') }}
+ <gl-sprintf :message="s__('ClusterIntegration|%{externalIp}.nip.io')">
+ <template #externalIp>{{ externalIp }}</template>
+ </gl-sprintf>
+ {{ s__('ClusterIntegration|can be used instead of a custom domain. ') }}
+ </div>
+ <gl-sprintf
+ class="inline"
+ :message="s__('ClusterIntegration|%{linkStart}More information%{linkEnd}')"
+ >
+ <template #link="{ content }">
+ <gl-link :href="externalEndpointHelpPath" target="_blank">{{ content }}</gl-link>
+ </template>
+ </gl-sprintf>
+ </div>
+ </gl-form-group>
+ <div v-if="editable" class="form group gl-display-flex gl-justify-content-end">
+ <gl-button
+ category="primary"
+ variant="success"
+ type="submit"
+ :disabled="!canSubmit"
+ :aria-disabled="!canSubmit"
+ data-qa-selector="save_changes_button"
+ >{{ s__('ClusterIntegration|Save changes') }}</gl-button
+ >
+ </div>
+ </div>
+</template>
diff --git a/app/assets/javascripts/clusters/forms/show/index.js b/app/assets/javascripts/clusters/forms/show/index.js
new file mode 100644
index 00000000000..47a3016c777
--- /dev/null
+++ b/app/assets/javascripts/clusters/forms/show/index.js
@@ -0,0 +1,27 @@
+import Vue from 'vue';
+import IntegrationForm from '../components/integration_form.vue';
+import { createStore } from '../stores';
+
+export default () => {
+ const entryPoint = document.querySelector('#js-cluster-integration-form');
+
+ if (!entryPoint) {
+ return;
+ }
+
+ const { autoDevopsHelpPath, externalEndpointHelpPath } = entryPoint.dataset;
+
+ // eslint-disable-next-line no-new
+ new Vue({
+ el: entryPoint,
+ store: createStore(entryPoint.dataset),
+ provide: {
+ autoDevopsHelpPath,
+ externalEndpointHelpPath,
+ },
+
+ render(createElement) {
+ return createElement(IntegrationForm, {});
+ },
+ });
+};
diff --git a/app/assets/javascripts/clusters/forms/stores/index.js b/app/assets/javascripts/clusters/forms/stores/index.js
new file mode 100644
index 00000000000..ae082c07f26
--- /dev/null
+++ b/app/assets/javascripts/clusters/forms/stores/index.js
@@ -0,0 +1,12 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+import state from './state';
+
+Vue.use(Vuex);
+
+export const createStore = initialState =>
+ new Vuex.Store({
+ state: state(initialState),
+ });
+
+export default createStore;
diff --git a/app/assets/javascripts/clusters/forms/stores/state.js b/app/assets/javascripts/clusters/forms/stores/state.js
new file mode 100644
index 00000000000..2a96590b5e7
--- /dev/null
+++ b/app/assets/javascripts/clusters/forms/stores/state.js
@@ -0,0 +1,13 @@
+import { parseBoolean } from '../../../lib/utils/common_utils';
+
+export default (initialState = {}) => {
+ return {
+ enabled: parseBoolean(initialState.enabled),
+ editable: parseBoolean(initialState.editable),
+ environmentScope: initialState.environmentScope,
+ baseDomain: initialState.baseDomain,
+ applicationIngressExternalIp: initialState.applicationIngressExternalIp,
+ autoDevopsHelpPath: initialState.autoDevopsHelpPath,
+ externalEndpointHelpPath: initialState.externalEndpointHelpPath,
+ };
+};
diff --git a/app/assets/javascripts/clusters/services/application_state_machine.js b/app/assets/javascripts/clusters/services/application_state_machine.js
index 6af9b10f12f..683b0e18534 100644
--- a/app/assets/javascripts/clusters/services/application_state_machine.js
+++ b/app/assets/javascripts/clusters/services/application_state_machine.js
@@ -14,6 +14,7 @@ const {
UNINSTALLING,
UNINSTALL_ERRORED,
PRE_INSTALLED,
+ UNINSTALLED,
} = APPLICATION_STATUS;
const applicationStateMachine = {
@@ -67,6 +68,9 @@ const applicationStateMachine = {
[PRE_INSTALLED]: {
target: PRE_INSTALLED,
},
+ [UNINSTALLED]: {
+ target: UNINSTALLED,
+ },
},
},
[NOT_INSTALLABLE]: {
@@ -87,9 +91,17 @@ const applicationStateMachine = {
[NOT_INSTALLABLE]: {
target: NOT_INSTALLABLE,
},
- // This is possible in artificial environments for E2E testing
[INSTALLED]: {
target: INSTALLED,
+ effects: {
+ installFailed: false,
+ },
+ },
+ [UNINSTALLED]: {
+ target: UNINSTALLED,
+ effects: {
+ installFailed: false,
+ },
},
},
},
@@ -125,6 +137,15 @@ const applicationStateMachine = {
uninstallSuccessful: false,
},
},
+ [UNINSTALLED]: {
+ target: UNINSTALLED,
+ },
+ [ERROR]: {
+ target: INSTALLABLE,
+ effects: {
+ installFailed: true,
+ },
+ },
},
},
[PRE_INSTALLED]: {
@@ -180,6 +201,19 @@ const applicationStateMachine = {
},
},
},
+ [UNINSTALLED]: {
+ on: {
+ [INSTALLED]: {
+ target: INSTALLED,
+ },
+ [ERROR]: {
+ target: INSTALLABLE,
+ effects: {
+ installFailed: true,
+ },
+ },
+ },
+ },
};
/**
diff --git a/app/assets/javascripts/clusters/stores/clusters_store.js b/app/assets/javascripts/clusters/stores/clusters_store.js
index 9d354e66661..53868b7c02d 100644
--- a/app/assets/javascripts/clusters/stores/clusters_store.js
+++ b/app/assets/javascripts/clusters/stores/clusters_store.js
@@ -23,6 +23,7 @@ const applicationInitialState = {
status: null,
statusReason: null,
requestReason: null,
+ installable: true,
installed: false,
installFailed: false,
uninstallable: false,
@@ -114,6 +115,11 @@ export default class ClusterStore {
ciliumLogEnabled: null,
isEditingSettings: false,
},
+ cilium: {
+ ...applicationInitialState,
+ title: s__('ClusterIntegration|GitLab Container Network Policies'),
+ installable: false,
+ },
},
environments: [],
fetchingEnvironments: false,
@@ -129,6 +135,7 @@ export default class ClusterStore {
clustersHelpPath,
deployBoardsHelpPath,
cloudRunHelpPath,
+ ciliumHelpPath,
) {
this.state.helpPath = helpPath;
this.state.ingressHelpPath = ingressHelpPath;
@@ -138,6 +145,7 @@ export default class ClusterStore {
this.state.clustersHelpPath = clustersHelpPath;
this.state.deployBoardsHelpPath = deployBoardsHelpPath;
this.state.cloudRunHelpPath = cloudRunHelpPath;
+ this.state.ciliumHelpPath = ciliumHelpPath;
}
setManagePrometheusPath(managePrometheusPath) {