blob: 7dcb4dd91074ad6a763943dcde6a48aa91728751 [file] [log] [blame]
Yoshie Muranaka37393812020-03-24 15:25:24 -07001<template>
Yoshie Muranaka3111b6f2020-04-21 19:48:38 -07002 <b-container fluid="xl">
Yoshie Muranaka37393812020-03-24 15:25:24 -07003 <page-title />
4 <b-row>
Yoshie Muranaka3111b6f2020-04-21 19:48:38 -07005 <b-col xl="11">
Yoshie Muranakae45f54b2020-03-26 15:23:34 -07006 <!-- Expired certificates banner -->
7 <alert :show="expiredCertificateTypes.length > 0" variant="danger">
8 <template v-if="expiredCertificateTypes.length > 1">
9 {{ $t('pageSslCertificates.alert.certificatesExpiredMessage') }}
10 </template>
11 <template v-else>
12 {{
13 $t('pageSslCertificates.alert.certificateExpiredMessage', {
14 certificate: expiredCertificateTypes[0]
15 })
16 }}
17 </template>
18 </alert>
19 <!-- Expiring certificates banner -->
20 <alert :show="expiringCertificateTypes.length > 0" variant="warning">
21 <template v-if="expiringCertificateTypes.length > 1">
22 {{ $t('pageSslCertificates.alert.certificatesExpiringMessage') }}
23 </template>
24 <template v-else>
25 {{
26 $t('pageSslCertificates.alert.certificateExpiringMessage', {
27 certificate: expiringCertificateTypes[0]
28 })
29 }}
30 </template>
31 </alert>
32 </b-col>
33 </b-row>
34 <b-row>
Yoshie Muranaka3111b6f2020-04-21 19:48:38 -070035 <b-col xl="11" class="text-right">
Yoshie Muranaka532a4b02020-03-27 11:00:50 -070036 <b-button v-b-modal.generate-csr variant="link">
37 <icon-add />
38 {{ $t('pageSslCertificates.generateCsr') }}
39 </b-button>
Yoshie Muranaka37393812020-03-24 15:25:24 -070040 <b-button
41 variant="primary"
42 :disabled="certificatesForUpload.length === 0"
43 @click="initModalUploadCertificate(null)"
44 >
45 <icon-add />
46 {{ $t('pageSslCertificates.addNewCertificate') }}
47 </b-button>
48 </b-col>
49 </b-row>
50 <b-row>
Yoshie Muranaka3111b6f2020-04-21 19:48:38 -070051 <b-col xl="11">
Yoshie Muranaka37393812020-03-24 15:25:24 -070052 <b-table :fields="fields" :items="tableItems">
53 <template v-slot:cell(validFrom)="{ value }">
54 {{ value | formatDate }}
55 </template>
56
57 <template v-slot:cell(validUntil)="{ value }">
Yoshie Muranakae45f54b2020-03-26 15:23:34 -070058 <status-icon
59 v-if="getDaysUntilExpired(value) < 31"
60 :status="getIconStatus(value)"
61 />
Yoshie Muranaka37393812020-03-24 15:25:24 -070062 {{ value | formatDate }}
63 </template>
64
65 <template v-slot:cell(actions)="{ value, item }">
66 <table-row-action
67 v-for="(action, index) in value"
68 :key="index"
69 :value="action.value"
70 :title="action.title"
71 :enabled="action.enabled"
72 @click:tableAction="onTableRowAction($event, item)"
73 >
74 <template v-slot:icon>
75 <icon-replace v-if="action.value === 'replace'" />
76 <icon-trashcan v-if="action.value === 'delete'" />
77 </template>
78 </table-row-action>
79 </template>
80 </b-table>
81 </b-col>
82 </b-row>
83
84 <!-- Modals -->
85 <modal-upload-certificate :certificate="modalCertificate" @ok="onModalOk" />
Yoshie Muranaka532a4b02020-03-27 11:00:50 -070086 <modal-generate-csr />
Yoshie Muranaka37393812020-03-24 15:25:24 -070087 </b-container>
88</template>
89
90<script>
91import IconAdd from '@carbon/icons-vue/es/add--alt/20';
92import IconReplace from '@carbon/icons-vue/es/renew/20';
93import IconTrashcan from '@carbon/icons-vue/es/trash-can/20';
94
Yoshie Muranaka532a4b02020-03-27 11:00:50 -070095import ModalGenerateCsr from './ModalGenerateCsr';
Yoshie Muranaka37393812020-03-24 15:25:24 -070096import ModalUploadCertificate from './ModalUploadCertificate';
97import PageTitle from '../../../components/Global/PageTitle';
98import TableRowAction from '../../../components/Global/TableRowAction';
Yoshie Muranakae45f54b2020-03-26 15:23:34 -070099import StatusIcon from '../../../components/Global/StatusIcon';
100import Alert from '../../../components/Global/Alert';
Yoshie Muranaka37393812020-03-24 15:25:24 -0700101
102import BVToastMixin from '../../../components/Mixins/BVToastMixin';
Yoshie Muranakae5be9ba2020-04-30 10:13:40 -0700103import LoadingBarMixin from '@/components/Mixins/LoadingBarMixin';
Yoshie Muranaka37393812020-03-24 15:25:24 -0700104
105export default {
106 name: 'SslCertificates',
107 components: {
Yoshie Muranakae45f54b2020-03-26 15:23:34 -0700108 Alert,
Yoshie Muranaka37393812020-03-24 15:25:24 -0700109 IconAdd,
110 IconReplace,
111 IconTrashcan,
Yoshie Muranaka532a4b02020-03-27 11:00:50 -0700112 ModalGenerateCsr,
Yoshie Muranaka37393812020-03-24 15:25:24 -0700113 ModalUploadCertificate,
114 PageTitle,
Yoshie Muranakae45f54b2020-03-26 15:23:34 -0700115 StatusIcon,
Yoshie Muranaka37393812020-03-24 15:25:24 -0700116 TableRowAction
117 },
Yoshie Muranakae5be9ba2020-04-30 10:13:40 -0700118 mixins: [BVToastMixin, LoadingBarMixin],
Yoshie Muranaka37393812020-03-24 15:25:24 -0700119 data() {
120 return {
121 modalCertificate: null,
122 fields: [
123 {
124 key: 'certificate',
125 label: this.$t('pageSslCertificates.table.certificate')
126 },
127 {
128 key: 'issuedBy',
129 label: this.$t('pageSslCertificates.table.issuedBy')
130 },
131 {
132 key: 'issuedTo',
133 label: this.$t('pageSslCertificates.table.issuedTo')
134 },
135 {
136 key: 'validFrom',
137 label: this.$t('pageSslCertificates.table.validFrom')
138 },
139 {
140 key: 'validUntil',
141 label: this.$t('pageSslCertificates.table.validUntil')
142 },
143 {
144 key: 'actions',
145 label: '',
146 tdClass: 'text-right'
147 }
148 ]
149 };
150 },
151 computed: {
152 certificates() {
153 return this.$store.getters['sslCertificates/allCertificates'];
154 },
155 tableItems() {
156 return this.certificates.map(certificate => {
157 return {
158 ...certificate,
159 actions: [
160 {
161 value: 'replace',
162 title: this.$t('pageSslCertificates.replaceCertificate')
163 },
164 {
165 value: 'delete',
166 title: this.$t('pageSslCertificates.deleteCertificate'),
167 enabled:
168 certificate.type === 'TrustStore Certificate' ? true : false
169 }
170 ]
171 };
172 });
173 },
174 certificatesForUpload() {
175 return this.$store.getters['sslCertificates/availableUploadTypes'];
Yoshie Muranakae45f54b2020-03-26 15:23:34 -0700176 },
177 bmcTime() {
178 return this.$store.getters['global/bmcTime'];
179 },
180 expiredCertificateTypes() {
181 return this.certificates.reduce((acc, val) => {
182 const daysUntilExpired = this.getDaysUntilExpired(val.validUntil);
183 if (daysUntilExpired < 1) {
184 acc.push(val.certificate);
185 }
186 return acc;
187 }, []);
188 },
189 expiringCertificateTypes() {
190 return this.certificates.reduce((acc, val) => {
191 const daysUntilExpired = this.getDaysUntilExpired(val.validUntil);
192 if (daysUntilExpired < 31 && daysUntilExpired > 0) {
193 acc.push(val.certificate);
194 }
195 return acc;
196 }, []);
Yoshie Muranaka37393812020-03-24 15:25:24 -0700197 }
198 },
Yoshie Muranakae5be9ba2020-04-30 10:13:40 -0700199 async created() {
200 this.startLoader();
201 await this.$store.dispatch('global/getBmcTime');
202 this.$store
203 .dispatch('sslCertificates/getCertificates')
204 .finally(() => this.endLoader());
205 },
206 beforeRouteLeave(to, from, next) {
207 this.hideLoader();
208 next();
Yoshie Muranaka37393812020-03-24 15:25:24 -0700209 },
210 methods: {
211 onTableRowAction(event, rowItem) {
212 switch (event) {
213 case 'replace':
214 this.initModalUploadCertificate(rowItem);
215 break;
216 case 'delete':
217 this.initModalDeleteCertificate(rowItem);
218 break;
219 default:
220 break;
221 }
222 },
223 initModalUploadCertificate(certificate = null) {
224 this.modalCertificate = certificate;
225 this.$bvModal.show('upload-certificate');
226 },
227 initModalDeleteCertificate(certificate) {
228 this.$bvModal
229 .msgBoxConfirm(
230 this.$t('pageSslCertificates.modal.deleteConfirmMessage', {
231 issuedBy: certificate.issuedBy,
232 certificate: certificate.certificate
233 }),
234 {
235 title: this.$t('pageSslCertificates.deleteCertificate'),
236 okTitle: this.$t('global.action.delete')
237 }
238 )
239 .then(deleteConfirmed => {
240 if (deleteConfirmed) this.deleteCertificate(certificate);
241 });
242 },
243 onModalOk({ addNew, file, type, location }) {
244 if (addNew) {
245 // Upload a new certificate
246 this.addNewCertificate(file, type);
247 } else {
248 // Replace an existing certificate
249 this.replaceCertificate(file, type, location);
250 }
251 },
252 addNewCertificate(file, type) {
Yoshie Muranakae5be9ba2020-04-30 10:13:40 -0700253 this.startLoader();
Yoshie Muranaka37393812020-03-24 15:25:24 -0700254 this.$store
255 .dispatch('sslCertificates/addNewCertificate', { file, type })
256 .then(success => this.successToast(success))
Yoshie Muranakae5be9ba2020-04-30 10:13:40 -0700257 .catch(({ message }) => this.errorToast(message))
258 .finally(() => this.endLoader());
Yoshie Muranaka37393812020-03-24 15:25:24 -0700259 },
260 replaceCertificate(file, type, location) {
Yoshie Muranakae5be9ba2020-04-30 10:13:40 -0700261 this.startLoader();
Yoshie Muranaka37393812020-03-24 15:25:24 -0700262 const reader = new FileReader();
263 reader.readAsBinaryString(file);
264 reader.onloadend = event => {
265 const certificateString = event.target.result;
266 this.$store
267 .dispatch('sslCertificates/replaceCertificate', {
268 certificateString,
269 type,
270 location
271 })
272 .then(success => this.successToast(success))
Yoshie Muranakae5be9ba2020-04-30 10:13:40 -0700273 .catch(({ message }) => this.errorToast(message))
274 .finally(() => this.endLoader());
Yoshie Muranaka37393812020-03-24 15:25:24 -0700275 };
276 },
277 deleteCertificate({ type, location }) {
Yoshie Muranakae5be9ba2020-04-30 10:13:40 -0700278 this.startLoader();
Yoshie Muranaka37393812020-03-24 15:25:24 -0700279 this.$store
280 .dispatch('sslCertificates/deleteCertificate', {
281 type,
282 location
283 })
284 .then(success => this.successToast(success))
Yoshie Muranakae5be9ba2020-04-30 10:13:40 -0700285 .catch(({ message }) => this.errorToast(message))
286 .finally(() => this.endLoader());
Yoshie Muranakae45f54b2020-03-26 15:23:34 -0700287 },
288 getDaysUntilExpired(date) {
289 if (this.bmcTime) {
290 const validUntilMs = date.getTime();
291 const currentBmcTimeMs = this.bmcTime.getTime();
292 const oneDayInMs = 24 * 60 * 60 * 1000;
293 return Math.round((validUntilMs - currentBmcTimeMs) / oneDayInMs);
294 }
Yoshie Muranakae5be9ba2020-04-30 10:13:40 -0700295 return new Date();
Yoshie Muranakae45f54b2020-03-26 15:23:34 -0700296 },
297 getIconStatus(date) {
298 const daysUntilExpired = this.getDaysUntilExpired(date);
299 if (daysUntilExpired < 1) {
300 return 'danger';
301 } else if (daysUntilExpired < 31) {
302 return 'warning';
303 }
Yoshie Muranaka37393812020-03-24 15:25:24 -0700304 }
305 }
306};
307</script>