Merge branch '58269-separate-update-patch' into 'master'
Do not display Update app button when saving Knative domain name Closes #58269 See merge request gitlab-org/gitlab-ce!28904
This commit is contained in:
commit
a9589cdf28
10 changed files with 413 additions and 235 deletions
|
@ -353,8 +353,10 @@ export default class Clusters {
|
||||||
|
|
||||||
saveKnativeDomain(data) {
|
saveKnativeDomain(data) {
|
||||||
const appId = data.id;
|
const appId = data.id;
|
||||||
this.store.updateAppProperty(appId, 'status', APPLICATION_STATUS.UPDATING);
|
this.store.updateApplication(appId);
|
||||||
this.service.updateApplication(appId, data.params);
|
this.service.updateApplication(appId, data.params).catch(() => {
|
||||||
|
this.store.notifyUpdateFailure(appId);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
setKnativeHostname(data) {
|
setKnativeHostname(data) {
|
||||||
|
|
|
@ -89,6 +89,10 @@ export default {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: false,
|
required: false,
|
||||||
},
|
},
|
||||||
|
updateable: {
|
||||||
|
type: Boolean,
|
||||||
|
default: true,
|
||||||
|
},
|
||||||
updateSuccessful: {
|
updateSuccessful: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: false,
|
required: false,
|
||||||
|
@ -326,36 +330,38 @@ export default {
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div
|
<div v-if="updateable">
|
||||||
v-if="shouldShowUpgradeDetails"
|
<div
|
||||||
class="form-text text-muted label p-0 js-cluster-application-upgrade-details"
|
v-if="shouldShowUpgradeDetails"
|
||||||
>
|
class="form-text text-muted label p-0 js-cluster-application-upgrade-details"
|
||||||
{{ versionLabel }}
|
|
||||||
<span v-if="updateSuccessful">to</span>
|
|
||||||
|
|
||||||
<gl-link
|
|
||||||
v-if="updateSuccessful"
|
|
||||||
:href="chartRepo"
|
|
||||||
target="_blank"
|
|
||||||
class="js-cluster-application-upgrade-version"
|
|
||||||
>chart v{{ version }}</gl-link
|
|
||||||
>
|
>
|
||||||
</div>
|
{{ versionLabel }}
|
||||||
|
<span v-if="updateSuccessful">to</span>
|
||||||
|
|
||||||
<div
|
<gl-link
|
||||||
v-if="updateFailed && !isUpgrading"
|
v-if="updateSuccessful"
|
||||||
class="bs-callout bs-callout-danger cluster-application-banner mt-2 mb-0 js-cluster-application-upgrade-failure-message"
|
:href="chartRepo"
|
||||||
>
|
target="_blank"
|
||||||
{{ upgradeFailureDescription }}
|
class="js-cluster-application-upgrade-version"
|
||||||
|
>chart v{{ version }}</gl-link
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
v-if="updateFailed && !isUpgrading"
|
||||||
|
class="bs-callout bs-callout-danger cluster-application-banner mt-2 mb-0 js-cluster-application-upgrade-failure-message"
|
||||||
|
>
|
||||||
|
{{ upgradeFailureDescription }}
|
||||||
|
</div>
|
||||||
|
<loading-button
|
||||||
|
v-if="upgradeAvailable || updateFailed || isUpgrading"
|
||||||
|
class="btn btn-primary js-cluster-application-upgrade-button mt-2"
|
||||||
|
:loading="isUpgrading"
|
||||||
|
:disabled="isUpgrading"
|
||||||
|
:label="upgradeButtonLabel"
|
||||||
|
@click="upgradeClicked"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<loading-button
|
|
||||||
v-if="upgradeAvailable || updateFailed || isUpgrading"
|
|
||||||
class="btn btn-primary js-cluster-application-upgrade-button mt-2"
|
|
||||||
:loading="isUpgrading"
|
|
||||||
:disabled="isUpgrading"
|
|
||||||
:label="upgradeButtonLabel"
|
|
||||||
@click="upgradeClicked"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
:class="{ 'section-25': showManageButton, 'section-15': !showManageButton }"
|
:class="{ 'section-25': showManageButton, 'section-15': !showManageButton }"
|
||||||
|
|
|
@ -15,6 +15,7 @@ import prometheusLogo from 'images/cluster_app_logos/prometheus.png';
|
||||||
import { s__, sprintf } from '../../locale';
|
import { s__, sprintf } from '../../locale';
|
||||||
import applicationRow from './application_row.vue';
|
import applicationRow from './application_row.vue';
|
||||||
import clipboardButton from '../../vue_shared/components/clipboard_button.vue';
|
import clipboardButton from '../../vue_shared/components/clipboard_button.vue';
|
||||||
|
import KnativeDomainEditor from './knative_domain_editor.vue';
|
||||||
import { CLUSTER_TYPE, APPLICATION_STATUS, INGRESS } from '../constants';
|
import { CLUSTER_TYPE, APPLICATION_STATUS, INGRESS } from '../constants';
|
||||||
import LoadingButton from '~/vue_shared/components/loading_button.vue';
|
import LoadingButton from '~/vue_shared/components/loading_button.vue';
|
||||||
import eventHub from '~/clusters/event_hub';
|
import eventHub from '~/clusters/event_hub';
|
||||||
|
@ -25,6 +26,7 @@ export default {
|
||||||
clipboardButton,
|
clipboardButton,
|
||||||
LoadingButton,
|
LoadingButton,
|
||||||
GlLoadingIcon,
|
GlLoadingIcon,
|
||||||
|
KnativeDomainEditor,
|
||||||
},
|
},
|
||||||
props: {
|
props: {
|
||||||
type: {
|
type: {
|
||||||
|
@ -154,64 +156,21 @@ export default {
|
||||||
knative() {
|
knative() {
|
||||||
return this.applications.knative;
|
return this.applications.knative;
|
||||||
},
|
},
|
||||||
knativeInstalled() {
|
|
||||||
return (
|
|
||||||
this.knative.status === APPLICATION_STATUS.INSTALLED ||
|
|
||||||
this.knativeUpgrading ||
|
|
||||||
this.knativeUpgradeFailed ||
|
|
||||||
this.knative.status === APPLICATION_STATUS.UPDATED
|
|
||||||
);
|
|
||||||
},
|
|
||||||
knativeUpgrading() {
|
|
||||||
return (
|
|
||||||
this.knative.status === APPLICATION_STATUS.UPDATING ||
|
|
||||||
this.knative.status === APPLICATION_STATUS.SCHEDULED
|
|
||||||
);
|
|
||||||
},
|
|
||||||
knativeUpgradeFailed() {
|
|
||||||
return this.knative.status === APPLICATION_STATUS.UPDATE_ERRORED;
|
|
||||||
},
|
|
||||||
knativeExternalEndpoint() {
|
|
||||||
return this.knative.externalIp || this.knative.externalHostname;
|
|
||||||
},
|
|
||||||
knativeDescription() {
|
|
||||||
return sprintf(
|
|
||||||
_.escape(
|
|
||||||
s__(
|
|
||||||
`ClusterIntegration|Installing Knative may incur additional costs. Learn more about %{pricingLink}.`,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
{
|
|
||||||
pricingLink: `<strong><a href="https://cloud.google.com/compute/pricing#lb"
|
|
||||||
target="_blank" rel="noopener noreferrer">
|
|
||||||
${_.escape(s__('ClusterIntegration|pricing'))}</a></strong>`,
|
|
||||||
},
|
|
||||||
false,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
canUpdateKnativeEndpoint() {
|
|
||||||
return this.knativeExternalEndpoint && !this.knativeUpgradeFailed && !this.knativeUpgrading;
|
|
||||||
},
|
|
||||||
knativeHostname: {
|
|
||||||
get() {
|
|
||||||
return this.knative.hostname;
|
|
||||||
},
|
|
||||||
set(hostname) {
|
|
||||||
eventHub.$emit('setKnativeHostname', {
|
|
||||||
id: 'knative',
|
|
||||||
hostname,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
this.helmInstallIllustration = helmInstallIllustration;
|
this.helmInstallIllustration = helmInstallIllustration;
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
saveKnativeDomain() {
|
saveKnativeDomain(hostname) {
|
||||||
eventHub.$emit('saveKnativeDomain', {
|
eventHub.$emit('saveKnativeDomain', {
|
||||||
id: 'knative',
|
id: 'knative',
|
||||||
params: { hostname: this.knative.hostname },
|
params: { hostname },
|
||||||
|
});
|
||||||
|
},
|
||||||
|
setKnativeHostname(hostname) {
|
||||||
|
eventHub.$emit('setKnativeHostname', {
|
||||||
|
id: 'knative',
|
||||||
|
hostname,
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -318,9 +277,9 @@ export default {
|
||||||
generated endpoint in order to access
|
generated endpoint in order to access
|
||||||
your application after it has been deployed.`)
|
your application after it has been deployed.`)
|
||||||
}}
|
}}
|
||||||
<a :href="ingressDnsHelpPath" target="_blank" rel="noopener noreferrer">{{
|
<a :href="ingressDnsHelpPath" target="_blank" rel="noopener noreferrer">
|
||||||
__('More information')
|
{{ __('More information') }}
|
||||||
}}</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -330,9 +289,9 @@ export default {
|
||||||
the process of being assigned. Please check your Kubernetes
|
the process of being assigned. Please check your Kubernetes
|
||||||
cluster or Quotas on Google Kubernetes Engine if it takes a long time.`)
|
cluster or Quotas on Google Kubernetes Engine if it takes a long time.`)
|
||||||
}}
|
}}
|
||||||
<a :href="ingressDnsHelpPath" target="_blank" rel="noopener noreferrer">{{
|
<a :href="ingressDnsHelpPath" target="_blank" rel="noopener noreferrer">
|
||||||
__('More information')
|
{{ __('More information') }}
|
||||||
}}</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
</template>
|
</template>
|
||||||
<template v-if="!ingressInstalled">
|
<template v-if="!ingressInstalled">
|
||||||
|
@ -361,9 +320,9 @@ export default {
|
||||||
<div slot="description">
|
<div slot="description">
|
||||||
<p v-html="certManagerDescription"></p>
|
<p v-html="certManagerDescription"></p>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="cert-manager-issuer-email">{{
|
<label for="cert-manager-issuer-email">
|
||||||
s__('ClusterIntegration|Issuer Email')
|
{{ s__('ClusterIntegration|Issuer Email') }}
|
||||||
}}</label>
|
</label>
|
||||||
<div class="input-group">
|
<div class="input-group">
|
||||||
<input
|
<input
|
||||||
v-model="applications.cert_manager.email"
|
v-model="applications.cert_manager.email"
|
||||||
|
@ -491,9 +450,9 @@ export default {
|
||||||
s__(`ClusterIntegration|Replace this with your own hostname if you want.
|
s__(`ClusterIntegration|Replace this with your own hostname if you want.
|
||||||
If you do so, point hostname to Ingress IP Address from above.`)
|
If you do so, point hostname to Ingress IP Address from above.`)
|
||||||
}}
|
}}
|
||||||
<a :href="ingressDnsHelpPath" target="_blank" rel="noopener noreferrer">{{
|
<a :href="ingressDnsHelpPath" target="_blank" rel="noopener noreferrer">
|
||||||
__('More information')
|
{{ __('More information') }}
|
||||||
}}</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -514,6 +473,7 @@ export default {
|
||||||
:uninstallable="applications.knative.uninstallable"
|
:uninstallable="applications.knative.uninstallable"
|
||||||
:uninstall-successful="applications.knative.uninstallSuccessful"
|
:uninstall-successful="applications.knative.uninstallSuccessful"
|
||||||
:uninstall-failed="applications.knative.uninstallFailed"
|
:uninstall-failed="applications.knative.uninstallFailed"
|
||||||
|
:updateable="false"
|
||||||
:disabled="!helmInstalled"
|
:disabled="!helmInstalled"
|
||||||
v-bind="applications.knative"
|
v-bind="applications.knative"
|
||||||
title-link="https://github.com/knative/docs"
|
title-link="https://github.com/knative/docs"
|
||||||
|
@ -525,9 +485,9 @@ export default {
|
||||||
s__(`ClusterIntegration|You must have an RBAC-enabled cluster
|
s__(`ClusterIntegration|You must have an RBAC-enabled cluster
|
||||||
to install Knative.`)
|
to install Knative.`)
|
||||||
}}
|
}}
|
||||||
<a :href="helpPath" target="_blank" rel="noopener noreferrer">{{
|
<a :href="helpPath" target="_blank" rel="noopener noreferrer">
|
||||||
__('More information')
|
{{ __('More information') }}
|
||||||
}}</a>
|
</a>
|
||||||
</p>
|
</p>
|
||||||
<br />
|
<br />
|
||||||
</span>
|
</span>
|
||||||
|
@ -540,83 +500,13 @@ export default {
|
||||||
}}
|
}}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="row">
|
<knative-domain-editor
|
||||||
<template v-if="knativeInstalled || (helmInstalled && rbac)">
|
v-if="knative.installed || (helmInstalled && rbac)"
|
||||||
<div
|
:knative="knative"
|
||||||
:class="{ 'col-md-6': knativeInstalled, 'col-12': helmInstalled && rbac }"
|
:ingress-dns-help-path="ingressDnsHelpPath"
|
||||||
class="form-group col-sm-12 mb-0"
|
@save="saveKnativeDomain"
|
||||||
>
|
@set="setKnativeHostname"
|
||||||
<label for="knative-domainname">
|
/>
|
||||||
<strong>{{ s__('ClusterIntegration|Knative Domain Name:') }}</strong>
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
id="knative-domainname"
|
|
||||||
v-model="knativeHostname"
|
|
||||||
type="text"
|
|
||||||
class="form-control js-knative-domainname"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<template v-if="knativeInstalled">
|
|
||||||
<div class="form-group col-sm-12 col-md-6 pl-md-0 mb-0 mt-3 mt-md-0">
|
|
||||||
<label for="knative-endpoint">
|
|
||||||
<strong>{{ s__('ClusterIntegration|Knative Endpoint:') }}</strong>
|
|
||||||
</label>
|
|
||||||
<div v-if="knativeExternalEndpoint" class="input-group">
|
|
||||||
<input
|
|
||||||
id="knative-endpoint"
|
|
||||||
:value="knativeExternalEndpoint"
|
|
||||||
type="text"
|
|
||||||
class="form-control js-knative-endpoint"
|
|
||||||
readonly
|
|
||||||
/>
|
|
||||||
<span class="input-group-append">
|
|
||||||
<clipboard-button
|
|
||||||
:text="knativeExternalEndpoint"
|
|
||||||
:title="s__('ClusterIntegration|Copy Knative Endpoint to clipboard')"
|
|
||||||
class="input-group-text js-knative-endpoint-clipboard-btn"
|
|
||||||
/>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div v-else class="input-group">
|
|
||||||
<input type="text" class="form-control js-endpoint" readonly />
|
|
||||||
<gl-loading-icon
|
|
||||||
class="position-absolute align-self-center ml-2 js-knative-ip-loading-icon"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p class="form-text text-muted col-12">
|
|
||||||
{{
|
|
||||||
s__(
|
|
||||||
`ClusterIntegration|To access your application after deployment, point a wildcard DNS to the Knative Endpoint.`,
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
<a :href="ingressDnsHelpPath" target="_blank" rel="noopener noreferrer">{{
|
|
||||||
__('More information')
|
|
||||||
}}</a>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p
|
|
||||||
v-if="!knativeExternalEndpoint"
|
|
||||||
class="settings-message js-no-knative-endpoint-message mt-2 mr-3 mb-0 ml-3"
|
|
||||||
>
|
|
||||||
{{
|
|
||||||
s__(`ClusterIntegration|The endpoint is in
|
|
||||||
the process of being assigned. Please check your Kubernetes
|
|
||||||
cluster or Quotas on Google Kubernetes Engine if it takes a long time.`)
|
|
||||||
}}
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<button
|
|
||||||
v-if="canUpdateKnativeEndpoint"
|
|
||||||
class="btn btn-success js-knative-save-domain-button mt-3 ml-3"
|
|
||||||
@click="saveKnativeDomain"
|
|
||||||
>
|
|
||||||
{{ s__('ClusterIntegration|Save changes') }}
|
|
||||||
</button>
|
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</application-row>
|
</application-row>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -0,0 +1,150 @@
|
||||||
|
<script>
|
||||||
|
import LoadingButton from '~/vue_shared/components/loading_button.vue';
|
||||||
|
import ClipboardButton from '../../vue_shared/components/clipboard_button.vue';
|
||||||
|
import { GlLoadingIcon } from '@gitlab/ui';
|
||||||
|
import { s__ } from '~/locale';
|
||||||
|
|
||||||
|
import { APPLICATION_STATUS } from '~/clusters/constants';
|
||||||
|
|
||||||
|
const { UPDATING, UNINSTALLING } = APPLICATION_STATUS;
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
LoadingButton,
|
||||||
|
ClipboardButton,
|
||||||
|
GlLoadingIcon,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
knative: {
|
||||||
|
type: Object,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
ingressDnsHelpPath: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
saveButtonDisabled() {
|
||||||
|
return [UNINSTALLING, UPDATING].includes(this.knative.status);
|
||||||
|
},
|
||||||
|
saving() {
|
||||||
|
return [UPDATING].includes(this.knative.status);
|
||||||
|
},
|
||||||
|
saveButtonLabel() {
|
||||||
|
return this.saving ? this.__('Saving') : this.__('Save changes');
|
||||||
|
},
|
||||||
|
knativeInstalled() {
|
||||||
|
return this.knative.installed;
|
||||||
|
},
|
||||||
|
knativeExternalEndpoint() {
|
||||||
|
return this.knative.externalIp || this.knative.externalHostname;
|
||||||
|
},
|
||||||
|
knativeUpdateSuccessful() {
|
||||||
|
return this.knative.updateSuccessful;
|
||||||
|
},
|
||||||
|
knativeHostname: {
|
||||||
|
get() {
|
||||||
|
return this.knative.hostname;
|
||||||
|
},
|
||||||
|
set(hostname) {
|
||||||
|
this.$emit('set', hostname);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
knativeUpdateSuccessful(updateSuccessful) {
|
||||||
|
if (updateSuccessful) {
|
||||||
|
this.$toast.show(s__('ClusterIntegration|Knative domain name was updated successfully.'));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="row">
|
||||||
|
<div
|
||||||
|
v-if="knative.updateFailed"
|
||||||
|
class="bs-callout bs-callout-danger cluster-application-banner col-12 mt-2 mb-2 js-cluster-knative-domain-name-failure-message"
|
||||||
|
>
|
||||||
|
{{ s__('ClusterIntegration|Something went wrong while updating Knative domain name.') }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div
|
||||||
|
:class="{ 'col-md-6': knativeInstalled, 'col-12': !knativeInstalled }"
|
||||||
|
class="form-group col-sm-12 mb-0"
|
||||||
|
>
|
||||||
|
<label for="knative-domainname">
|
||||||
|
<strong>{{ s__('ClusterIntegration|Knative Domain Name:') }}</strong>
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
id="knative-domainname"
|
||||||
|
v-model="knativeHostname"
|
||||||
|
type="text"
|
||||||
|
class="form-control js-knative-domainname"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template v-if="knativeInstalled">
|
||||||
|
<div class="form-group col-sm-12 col-md-6 pl-md-0 mb-0 mt-3 mt-md-0">
|
||||||
|
<label for="knative-endpoint">
|
||||||
|
<strong>{{ s__('ClusterIntegration|Knative Endpoint:') }}</strong>
|
||||||
|
</label>
|
||||||
|
<div v-if="knativeExternalEndpoint" class="input-group">
|
||||||
|
<input
|
||||||
|
id="knative-endpoint"
|
||||||
|
:value="knativeExternalEndpoint"
|
||||||
|
type="text"
|
||||||
|
class="form-control js-knative-endpoint"
|
||||||
|
readonly
|
||||||
|
/>
|
||||||
|
<span class="input-group-append">
|
||||||
|
<clipboard-button
|
||||||
|
:text="knativeExternalEndpoint"
|
||||||
|
:title="s__('ClusterIntegration|Copy Knative Endpoint to clipboard')"
|
||||||
|
class="input-group-text js-knative-endpoint-clipboard-btn"
|
||||||
|
/>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div v-else class="input-group">
|
||||||
|
<input type="text" class="form-control js-endpoint" readonly />
|
||||||
|
<gl-loading-icon
|
||||||
|
class="position-absolute align-self-center ml-2 js-knative-ip-loading-icon"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p class="form-text text-muted col-12">
|
||||||
|
{{
|
||||||
|
s__(
|
||||||
|
`ClusterIntegration|To access your application after deployment, point a wildcard DNS to the Knative Endpoint.`,
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
<a :href="ingressDnsHelpPath" target="_blank" rel="noopener noreferrer">
|
||||||
|
{{ __('More information') }}
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p
|
||||||
|
v-if="!knativeExternalEndpoint"
|
||||||
|
class="settings-message js-no-knative-endpoint-message mt-2 mr-3 mb-0 ml-3"
|
||||||
|
>
|
||||||
|
{{
|
||||||
|
s__(`ClusterIntegration|The endpoint is in
|
||||||
|
the process of being assigned. Please check your Kubernetes
|
||||||
|
cluster or Quotas on Google Kubernetes Engine if it takes a long time.`)
|
||||||
|
}}
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<loading-button
|
||||||
|
class="btn-success js-knative-save-domain-button mt-3 ml-3"
|
||||||
|
:loading="saving"
|
||||||
|
:disabled="saveButtonDisabled"
|
||||||
|
:label="saveButtonLabel"
|
||||||
|
@click="$emit('save', knativeHostname)"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</template>
|
|
@ -77,6 +77,8 @@ export default class ClusterStore {
|
||||||
isEditingHostName: false,
|
isEditingHostName: false,
|
||||||
externalIp: null,
|
externalIp: null,
|
||||||
externalHostname: null,
|
externalHostname: null,
|
||||||
|
updateSuccessful: false,
|
||||||
|
updateFailed: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
5
changelogs/unreleased/58269-separate-update-patch.yml
Normal file
5
changelogs/unreleased/58269-separate-update-patch.yml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Do not display Update app button when saving Knative domain name
|
||||||
|
merge_request: 28904
|
||||||
|
author:
|
||||||
|
type: changed
|
|
@ -2337,9 +2337,6 @@ msgstr ""
|
||||||
msgid "ClusterIntegration|Installing Ingress may incur additional costs. Learn more about %{pricingLink}."
|
msgid "ClusterIntegration|Installing Ingress may incur additional costs. Learn more about %{pricingLink}."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "ClusterIntegration|Installing Knative may incur additional costs. Learn more about %{pricingLink}."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "ClusterIntegration|Instance cluster"
|
msgid "ClusterIntegration|Instance cluster"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -2373,6 +2370,9 @@ msgstr ""
|
||||||
msgid "ClusterIntegration|Knative Endpoint:"
|
msgid "ClusterIntegration|Knative Endpoint:"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "ClusterIntegration|Knative domain name was updated successfully."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "ClusterIntegration|Knative extends Kubernetes to provide a set of middleware components that are essential to build modern, source-centric, and container-based applications that can run anywhere: on premises, in the cloud, or even in a third-party data center."
|
msgid "ClusterIntegration|Knative extends Kubernetes to provide a set of middleware components that are essential to build modern, source-centric, and container-based applications that can run anywhere: on premises, in the cloud, or even in a third-party data center."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -2547,6 +2547,9 @@ msgstr ""
|
||||||
msgid "ClusterIntegration|Something went wrong while uninstalling %{title}"
|
msgid "ClusterIntegration|Something went wrong while uninstalling %{title}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
msgid "ClusterIntegration|Something went wrong while updating Knative domain name."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
msgid "ClusterIntegration|Specifying a domain will allow you to use Auto Review Apps and Auto Deploy stages for %{auto_devops_start}Auto DevOps%{auto_devops_end}. The domain should have a wildcard DNS configured matching the domain."
|
msgid "ClusterIntegration|Specifying a domain will allow you to use Auto Review Apps and Auto Deploy stages for %{auto_devops_start}Auto DevOps%{auto_devops_end}. The domain should have a wildcard DNS configured matching the domain."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import applications from '~/clusters/components/applications.vue';
|
import applications from '~/clusters/components/applications.vue';
|
||||||
import { CLUSTER_TYPE } from '~/clusters/constants';
|
import { CLUSTER_TYPE } from '~/clusters/constants';
|
||||||
import eventHub from '~/clusters/event_hub';
|
|
||||||
import mountComponent from 'helpers/vue_mount_component_helper';
|
import mountComponent from 'helpers/vue_mount_component_helper';
|
||||||
import { APPLICATIONS_MOCK_STATE } from '../services/mock_data';
|
import { APPLICATIONS_MOCK_STATE } from '../services/mock_data';
|
||||||
|
import eventHub from '~/clusters/event_hub';
|
||||||
|
import { shallowMount } from '@vue/test-utils';
|
||||||
|
import KnativeDomainEditor from '~/clusters/components/knative_domain_editor.vue';
|
||||||
|
|
||||||
describe('Applications', () => {
|
describe('Applications', () => {
|
||||||
let vm;
|
let vm;
|
||||||
|
@ -277,73 +279,48 @@ describe('Applications', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Knative application', () => {
|
describe('Knative application', () => {
|
||||||
describe('when installed', () => {
|
const propsData = {
|
||||||
describe('with ip address', () => {
|
applications: {
|
||||||
const props = {
|
...APPLICATIONS_MOCK_STATE,
|
||||||
applications: {
|
knative: {
|
||||||
...APPLICATIONS_MOCK_STATE,
|
title: 'Knative',
|
||||||
knative: {
|
hostname: 'example.com',
|
||||||
title: 'Knative',
|
status: 'installed',
|
||||||
hostname: 'example.com',
|
externalIp: '1.1.1.1',
|
||||||
status: 'installed',
|
installed: true,
|
||||||
externalIp: '1.1.1.1',
|
},
|
||||||
},
|
},
|
||||||
},
|
};
|
||||||
};
|
const newHostname = 'newhostname.com';
|
||||||
it('renders ip address with a clipboard button', () => {
|
let wrapper;
|
||||||
vm = mountComponent(Applications, props);
|
let knativeDomainEditor;
|
||||||
|
|
||||||
expect(vm.$el.querySelector('.js-knative-endpoint').value).toEqual('1.1.1.1');
|
beforeEach(() => {
|
||||||
|
wrapper = shallowMount(Applications, { propsData });
|
||||||
|
jest.spyOn(eventHub, '$emit');
|
||||||
|
|
||||||
expect(
|
knativeDomainEditor = wrapper.find(KnativeDomainEditor);
|
||||||
vm.$el
|
});
|
||||||
.querySelector('.js-knative-endpoint-clipboard-btn')
|
|
||||||
.getAttribute('data-clipboard-text'),
|
|
||||||
).toEqual('1.1.1.1');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('renders domain & allows editing', () => {
|
afterEach(() => {
|
||||||
expect(vm.$el.querySelector('.js-knative-domainname').value).toEqual('example.com');
|
wrapper.destroy();
|
||||||
expect(vm.$el.querySelector('.js-knative-domainname').getAttribute('readonly')).toBe(
|
});
|
||||||
null,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('renders an update/save Knative domain button', () => {
|
it('emits saveKnativeDomain event when knative domain editor emits save event', () => {
|
||||||
expect(vm.$el.querySelector('.js-knative-save-domain-button')).not.toBe(null);
|
knativeDomainEditor.vm.$emit('save', newHostname);
|
||||||
});
|
|
||||||
|
|
||||||
it('emits event when clicking Save changes button', () => {
|
expect(eventHub.$emit).toHaveBeenCalledWith('saveKnativeDomain', {
|
||||||
jest.spyOn(eventHub, '$emit');
|
id: 'knative',
|
||||||
vm = mountComponent(Applications, props);
|
params: { hostname: newHostname },
|
||||||
|
|
||||||
const saveButton = vm.$el.querySelector('.js-knative-save-domain-button');
|
|
||||||
|
|
||||||
saveButton.click();
|
|
||||||
|
|
||||||
expect(eventHub.$emit).toHaveBeenCalledWith('saveKnativeDomain', {
|
|
||||||
id: 'knative',
|
|
||||||
params: { hostname: 'example.com' },
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('without ip address', () => {
|
it('emits setKnativeHostname event when knative domain editor emits change event', () => {
|
||||||
it('renders an input text with a loading icon and an alert text', () => {
|
wrapper.find(KnativeDomainEditor).vm.$emit('set', newHostname);
|
||||||
vm = mountComponent(Applications, {
|
|
||||||
applications: {
|
|
||||||
...APPLICATIONS_MOCK_STATE,
|
|
||||||
knative: {
|
|
||||||
title: 'Knative',
|
|
||||||
hostname: 'example.com',
|
|
||||||
status: 'installed',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
expect(vm.$el.querySelector('.js-knative-ip-loading-icon')).not.toBe(null);
|
expect(eventHub.$emit).toHaveBeenCalledWith('setKnativeHostname', {
|
||||||
expect(vm.$el.querySelector('.js-no-knative-endpoint-message')).not.toBe(null);
|
id: 'knative',
|
||||||
});
|
hostname: newHostname,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
141
spec/frontend/clusters/components/knative_domain_editor_spec.js
Normal file
141
spec/frontend/clusters/components/knative_domain_editor_spec.js
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
import { shallowMount } from '@vue/test-utils';
|
||||||
|
import KnativeDomainEditor from '~/clusters/components/knative_domain_editor.vue';
|
||||||
|
import LoadingButton from '~/vue_shared/components/loading_button.vue';
|
||||||
|
import { APPLICATION_STATUS } from '~/clusters/constants';
|
||||||
|
|
||||||
|
const { UPDATING } = APPLICATION_STATUS;
|
||||||
|
|
||||||
|
describe('KnativeDomainEditor', () => {
|
||||||
|
let wrapper;
|
||||||
|
let knative;
|
||||||
|
|
||||||
|
const createComponent = (props = {}) => {
|
||||||
|
wrapper = shallowMount(KnativeDomainEditor, {
|
||||||
|
propsData: { ...props },
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
knative = {
|
||||||
|
title: 'Knative',
|
||||||
|
hostname: 'example.com',
|
||||||
|
installed: true,
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
wrapper.destroy();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('knative has an assigned IP address', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
knative.externalIp = '1.1.1.1';
|
||||||
|
createComponent({ knative });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders ip address with a clipboard button', () => {
|
||||||
|
expect(wrapper.find('.js-knative-endpoint').exists()).toBe(true);
|
||||||
|
expect(wrapper.find('.js-knative-endpoint').element.value).toEqual(knative.externalIp);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('displays ip address clipboard button', () => {
|
||||||
|
expect(wrapper.find('.js-knative-endpoint-clipboard-btn').attributes('text')).toEqual(
|
||||||
|
knative.externalIp,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders domain & allows editing', () => {
|
||||||
|
const domainNameInput = wrapper.find('.js-knative-domainname');
|
||||||
|
|
||||||
|
expect(domainNameInput.element.value).toEqual(knative.hostname);
|
||||||
|
expect(domainNameInput.attributes('readonly')).toBeFalsy();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders an update/save Knative domain button', () => {
|
||||||
|
expect(wrapper.find('.js-knative-save-domain-button').exists()).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('knative without ip address', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
knative.externalIp = null;
|
||||||
|
createComponent({ knative });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders an input text with a loading icon', () => {
|
||||||
|
expect(wrapper.find('.js-knative-ip-loading-icon').exists()).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders message indicating there is not IP address assigned', () => {
|
||||||
|
expect(wrapper.find('.js-no-knative-endpoint-message').exists()).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('clicking save changes button', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
createComponent({ knative });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('triggers save event and pass current knative hostname', () => {
|
||||||
|
wrapper.find(LoadingButton).vm.$emit('click');
|
||||||
|
expect(wrapper.emitted('save')[0]).toEqual([knative.hostname]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when knative domain name was saved successfully', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
createComponent({ knative });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('displays toast indicating a successful update', () => {
|
||||||
|
wrapper.vm.$toast = { show: jest.fn() };
|
||||||
|
wrapper.setProps({ knative: Object.assign({ updateSuccessful: true }, knative) });
|
||||||
|
|
||||||
|
return wrapper.vm.$nextTick(() => {
|
||||||
|
expect(wrapper.vm.$toast.show).toHaveBeenCalledWith(
|
||||||
|
'Knative domain name was updated successfully.',
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when knative domain name input changes', () => {
|
||||||
|
it('emits "set" event with updated domain name', () => {
|
||||||
|
const newHostname = 'newhostname.com';
|
||||||
|
|
||||||
|
wrapper.setData({ knativeHostname: newHostname });
|
||||||
|
|
||||||
|
expect(wrapper.emitted('set')[0]).toEqual([newHostname]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when updating knative domain name failed', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
createComponent({ knative });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('displays an error banner indicating the operation failure', () => {
|
||||||
|
wrapper.setProps({ knative: { updateFailed: true, ...knative } });
|
||||||
|
|
||||||
|
expect(wrapper.find('.js-cluster-knative-domain-name-failure-message').exists()).toBe(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe(`when knative status is ${UPDATING}`, () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
createComponent({ knative: { status: UPDATING, ...knative } });
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders loading spinner in save button', () => {
|
||||||
|
expect(wrapper.find(LoadingButton).props('loading')).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders disabled save button', () => {
|
||||||
|
expect(wrapper.find(LoadingButton).props('disabled')).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('renders save button with "Saving" label', () => {
|
||||||
|
expect(wrapper.find(LoadingButton).props('label')).toBe('Saving');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -133,6 +133,8 @@ describe('Clusters Store', () => {
|
||||||
uninstallable: false,
|
uninstallable: false,
|
||||||
uninstallSuccessful: false,
|
uninstallSuccessful: false,
|
||||||
uninstallFailed: false,
|
uninstallFailed: false,
|
||||||
|
updateSuccessful: false,
|
||||||
|
updateFailed: false,
|
||||||
},
|
},
|
||||||
cert_manager: {
|
cert_manager: {
|
||||||
title: 'Cert-Manager',
|
title: 'Cert-Manager',
|
||||||
|
|
Loading…
Reference in a new issue