Commit f0b27f9b authored by Filipa Lacerda's avatar Filipa Lacerda

Adds support to render the IP address in the application ingress row

Updates components to use a slot to allow to reuse the clipboard button
Adds tests
parent 9fc393c2
...@@ -36,10 +36,6 @@ ...@@ -36,10 +36,6 @@
type: String, type: String,
required: false, required: false,
}, },
description: {
type: String,
required: true,
},
status: { status: {
type: String, type: String,
required: false, required: false,
...@@ -148,11 +144,14 @@ ...@@ -148,11 +144,14 @@
class="table-section section-wrap" class="table-section section-wrap"
role="gridcell" role="gridcell"
> >
<div v-html="description"></div> <slot name="description"></slot>
</div> </div>
<div <div
class="table-section table-button-footer section-align-top" class="table-section table-button-footer section-align-top"
:class="{ 'section-20': showManageButton, 'section-15': !showManageButton }" :class="{
'section-20': showManageButton,
'section-15': !showManageButton,
}"
role="gridcell" role="gridcell"
> >
<div <div
......
...@@ -2,10 +2,15 @@ ...@@ -2,10 +2,15 @@
import _ from 'underscore'; import _ from 'underscore';
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 {
APPLICATION_INSTALLED,
} from '../constants';
export default { export default {
components: { components: {
applicationRow, applicationRow,
clipboardButton,
}, },
props: { props: {
applications: { applications: {
...@@ -43,19 +48,10 @@ ...@@ -43,19 +48,10 @@
false, false,
); );
}, },
helmTillerDescription() { ingressInstalled() {
return _.escape(s__( return this.applications.ingress.status === APPLICATION_INSTALLED;
`ClusterIntegration|Helm streamlines installing and managing Kubernetes applications.
Tiller runs inside of your Kubernetes Cluster, and manages
releases of your charts.`,
));
}, },
ingressDescription() { ingressDescription() {
const descriptionParagraph = _.escape(s__(
`ClusterIntegration|Ingress gives you a way to route requests to services based on the
request host or path, centralizing a number of services into a single entrypoint.`,
));
const extraCostParagraph = sprintf( const extraCostParagraph = sprintf(
_.escape(s__( _.escape(s__(
`ClusterIntegration|%{boldNotice} This will add some extra resources `ClusterIntegration|%{boldNotice} This will add some extra resources
...@@ -83,9 +79,6 @@ ...@@ -83,9 +79,6 @@
); );
return ` return `
<p>
${descriptionParagraph}
</p>
<p> <p>
${extraCostParagraph} ${extraCostParagraph}
</p> </p>
...@@ -136,33 +129,123 @@ ...@@ -136,33 +129,123 @@
id="helm" id="helm"
:title="applications.helm.title" :title="applications.helm.title"
title-link="https://docs.helm.sh/" title-link="https://docs.helm.sh/"
:description="helmTillerDescription"
:status="applications.helm.status" :status="applications.helm.status"
:status-reason="applications.helm.statusReason" :status-reason="applications.helm.statusReason"
:request-status="applications.helm.requestStatus" :request-status="applications.helm.requestStatus"
:request-reason="applications.helm.requestReason" :request-reason="applications.helm.requestReason"
/> >
<div slot="description">
{{ s__(
`ClusterIntegration|Helm streamlines installing and managing Kubernetes applications.
Tiller runs inside of your Kubernetes Cluster, and manages releases of your charts.`,
) }}
</div>
</application-row>
<application-row <application-row
id="ingress" id="ingress"
:title="applications.ingress.title" :title="applications.ingress.title"
title-link="https://kubernetes.io/docs/concepts/services-networking/ingress/" title-link="https://kubernetes.io/docs/concepts/services-networking/ingress/"
:description="ingressDescription"
:status="applications.ingress.status" :status="applications.ingress.status"
:status-reason="applications.ingress.statusReason" :status-reason="applications.ingress.statusReason"
:request-status="applications.ingress.requestStatus" :request-status="applications.ingress.requestStatus"
:request-reason="applications.ingress.requestReason" :request-reason="applications.ingress.requestReason"
>
<div slot="description">
<p>
{{ s__(
`ClusterIntegration|Ingress gives you a way to route
requests to services based on the request host or path,
centralizing a number of services into a single entrypoint.`,
) }}
</p>
<template v-if="ingressInstalled">
<div class="form-group">
<label for="ipAddress">
{{ s__("ClusterIntegration| Ingress IP Address") }}
</label>
<div
v-if="applications.ingress.external_ip"
class="input-group"
>
<input
type="text"
id="ipAddress"
class="form-control js-select-on-focus"
:placeholder="applications.ingress.external_ip"
readonly
/>
<span class="input-group-btn">
<clipboard-button
:text="applications.ingress.external_ip"
:title="s__('ClusterIntegration|Copy Ingress IP Address')"
css-class="btn btn-default js-clipboard-btn"
/>
</span>
</div>
<input
v-else
type="text"
id="ipAddress"
class="form-control"
readonly
placeholder="?"
/> />
</div>
<p
v-if="!applications.ingress.external_ip"
class="settings-message js-no-ip-message"
>
{{ s__(`ClusterIntegration|The IP address is in process
to be assigned, please check your Kubernetes
cluster or Quotas on GKE if it takes a long time.`) }}
<a
href="TODO"
target="_blank"
rel="noopener noreferrer"
>
{{ __("More information") }}
</a>
</p>
<p>
{{ s__(`ClusterIntegration|Point a wildcard DNS to this
generated IP address in order to access
your application after it has been deployed.`) }}
<a
href="TODO"
target="_blank"
rel="noopener noreferrer"
>
{{ __("More information") }}
</a>
</p>
</template>
<template
v-else
v-html="ingressDescription"
>
</template>
</div>
</application-row>
<application-row <application-row
id="prometheus" id="prometheus"
:title="applications.prometheus.title" :title="applications.prometheus.title"
title-link="https://prometheus.io/docs/introduction/overview/" title-link="https://prometheus.io/docs/introduction/overview/"
:manage-link="managePrometheusPath" :manage-link="managePrometheusPath"
:description="prometheusDescription"
:status="applications.prometheus.status" :status="applications.prometheus.status"
:status-reason="applications.prometheus.statusReason" :status-reason="applications.prometheus.statusReason"
:request-status="applications.prometheus.requestStatus" :request-status="applications.prometheus.requestStatus"
:request-reason="applications.prometheus.requestReason" :request-reason="applications.prometheus.requestReason"
/> >
<div
slot="description"
v-html="prometheusDescription"
>
</div>
</application-row>
<!-- <!--
NOTE: Don't forget to update `clusters.scss` NOTE: Don't forget to update `clusters.scss`
min-height for this block and uncomment `application_spec` tests min-height for this block and uncomment `application_spec` tests
......
...@@ -28,6 +28,11 @@ ...@@ -28,6 +28,11 @@
required: false, required: false,
default: false, default: false,
}, },
cssClass: {
type: String,
required: false,
default: 'btn btn-default btn-transparent btn-clipboard',
},
}, },
}; };
</script> </script>
...@@ -35,7 +40,7 @@ ...@@ -35,7 +40,7 @@
<template> <template>
<button <button
type="button" type="button"
class="btn btn-transparent btn-clipboard" :class="cssClass"
:title="title" :title="title"
:data-clipboard-text="text" :data-clipboard-text="text"
v-tooltip v-tooltip
......
---
title: Display ingress IP address in the Kubernetes page
merge_request:
author:
type: fixed
...@@ -44,4 +44,74 @@ describe('Applications', () => { ...@@ -44,4 +44,74 @@ describe('Applications', () => {
}); });
/* */ /* */
}); });
describe('Ingress application', () => {
describe('when installed', () => {
describe('with ip address', () => {
it('renders ip address with a clipboard button', () => {
vm = mountComponent(Applications, {
applications: {
ingress: {
title: 'Ingress',
status: 'installed',
external_ip: '0.0.0.0',
},
helm: { title: 'Helm Tiller' },
runner: { title: 'GitLab Runner' },
prometheus: { title: 'Prometheus' },
},
});
expect(
vm.$el.querySelector('#ipAddress').getAttribute('placeholder'),
).toEqual('0.0.0.0');
expect(
vm.$el.querySelector('.js-clipboard-btn').getAttribute('data-clipboard-text'),
).toEqual('0.0.0.0');
});
});
describe('without ip address', () => {
it('renders an input text with a question mark and an alert text', () => {
vm = mountComponent(Applications, {
applications: {
ingress: {
title: 'Ingress',
status: 'installed',
},
helm: { title: 'Helm Tiller' },
runner: { title: 'GitLab Runner' },
prometheus: { title: 'Prometheus' },
},
});
expect(
vm.$el.querySelector('#ipAddress').getAttribute('placeholder'),
).toEqual('?');
expect(
vm.$el.querySelector('.js-no-ip-message').textContent.replace(/\n(\s)+/g, ' ').trim(),
).toEqual(
'The IP address is in process to be assigned, please check your Kubernetes cluster or Quotas on GKE if it takes a long time. More information',
);
});
});
});
describe('before installing', () => {
it('does not render the IP address', () => {
vm = mountComponent(Applications, {
applications: {
helm: { title: 'Helm Tiller' },
ingress: { title: 'Ingress' },
runner: { title: 'GitLab Runner' },
prometheus: { title: 'Prometheus' },
},
});
expect(vm.$el.textContent).not.toContain('Ingress IP Address');
expect(vm.$el.querySelector('#ipAddress')).toBe(null);
});
});
});
}); });
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment