+import { HttpParams } from '@angular/common/http';
import { Component, Input, OnInit, ViewChild } from '@angular/core';
import { AbstractControl, Validators } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
})
export class ServiceFormComponent extends CdForm implements OnInit {
readonly RGW_SVC_ID_PATTERN = /^([^.]+)(\.([^.]+)\.([^.]+))?$/;
+ readonly MDS_SVC_ID_PATTERN = /^[a-zA-Z_.-][a-zA-Z0-9_.-]*$/;
readonly SNMP_DESTINATION_PATTERN = /^[^\:]+:[0-9]/;
readonly SNMP_ENGINE_ID_PATTERN = /^[0-9A-Fa-f]{10,64}/g;
+ readonly INGRESS_SUPPORTED_SERVICE_TYPES = ['rgw', 'nfs'];
@ViewChild(NgbTypeahead, { static: false })
typeahead: NgbTypeahead;
action: string;
resource: string;
serviceTypes: string[] = [];
+ serviceIds: string[] = [];
hosts: any;
labels: string[];
labelClick = new Subject<string>();
pools: Array<object>;
services: Array<CephServiceSpec> = [];
pageURL: string;
+ serviceList: CephServiceSpec[];
constructor(
public actionLabels: ActionLabelsI18n,
service_id: [
null,
[
- CdValidators.requiredIf({
- service_type: 'mds'
- }),
+ CdValidators.composeIf(
+ {
+ service_type: 'mds'
+ },
+ [
+ Validators.required,
+ CdValidators.custom('mdsPattern', (value: string) => {
+ if (_.isEmpty(value)) {
+ return false;
+ }
+ return !this.MDS_SVC_ID_PATTERN.test(value);
+ })
+ ]
+ ),
CdValidators.requiredIf({
service_type: 'nfs'
}),
return !this.RGW_SVC_ID_PATTERN.test(value);
})
]
- )
+ ),
+ CdValidators.custom('uniqueName', (service_id: string) => {
+ return this.serviceIds && this.serviceIds.includes(service_id);
+ })
]
],
placement: ['hosts'],
null,
[
CdValidators.requiredIf({
- service_type: 'iscsi',
- unmanaged: false
+ service_type: 'iscsi'
})
]
],
null,
[
CdValidators.requiredIf({
- service_type: 'ingress',
- unmanaged: false
+ service_type: 'ingress'
})
]
],
null,
[
CdValidators.requiredIf({
- service_type: 'ingress',
- unmanaged: false
+ service_type: 'ingress'
+ })
+ ]
+ ],
+ frontend_port: [
+ null,
+ [
+ CdValidators.number(false),
+ CdValidators.requiredIf({
+ service_type: 'ingress'
+ })
+ ]
+ ],
+ monitor_port: [
+ null,
+ [
+ CdValidators.number(false),
+ CdValidators.requiredIf({
+ service_type: 'ingress'
})
]
],
- frontend_port: [null, [CdValidators.number(false)]],
- monitor_port: [null, [CdValidators.number(false)]],
virtual_interface_networks: [null],
// RGW, Ingress & iSCSI
ssl: [false],
ssl: true
},
[Validators.required, CdValidators.sslCert()]
+ ),
+ CdValidators.composeIf(
+ {
+ service_type: 'ingress',
+ unmanaged: false,
+ ssl: true
+ },
+ [Validators.required, CdValidators.pemCert()]
)
]
],
this.serviceType = params.type;
});
}
+
+ this.cephServiceService
+ .list(new HttpParams({ fromObject: { limit: -1, offset: 0 } }))
+ .observable.subscribe((services: CephServiceSpec[]) => {
+ this.serviceList = services;
+ this.services = services.filter((service: any) =>
+ this.INGRESS_SUPPORTED_SERVICE_TYPES.includes(service.service_type)
+ );
+ });
+
this.cephServiceService.getKnownTypes().subscribe((resp: Array<string>) => {
// Remove service types:
// osd - This is deployed a different way.
this.poolService.getList().subscribe((resp: Array<object>) => {
this.pools = resp;
});
- this.cephServiceService.list().subscribe((services: CephServiceSpec[]) => {
- this.services = services.filter((service: any) => service.service_type === 'rgw');
- });
if (this.editing) {
this.action = this.actionLabels.EDIT;
this.disableForEditing(this.serviceType);
- this.cephServiceService.list(this.serviceName).subscribe((response: CephServiceSpec[]) => {
- const formKeys = ['service_type', 'service_id', 'unmanaged'];
- formKeys.forEach((keys) => {
- this.serviceForm.get(keys).setValue(response[0][keys]);
- });
- if (!response[0]['unmanaged']) {
- const placementKey = Object.keys(response[0]['placement'])[0];
- let placementValue: string;
- ['hosts', 'label'].indexOf(placementKey) >= 0
- ? (placementValue = placementKey)
- : (placementValue = 'hosts');
- this.serviceForm.get('placement').setValue(placementValue);
- this.serviceForm.get('count').setValue(response[0]['placement']['count']);
- if (response[0]?.placement[placementValue]) {
- this.serviceForm.get(placementValue).setValue(response[0]?.placement[placementValue]);
- }
- }
- switch (this.serviceType) {
- case 'iscsi':
- const specKeys = ['pool', 'api_password', 'api_user', 'trusted_ip_list', 'api_port'];
- specKeys.forEach((key) => {
- this.serviceForm.get(key).setValue(response[0].spec[key]);
- });
- this.serviceForm.get('ssl').setValue(response[0].spec?.api_secure);
- if (response[0].spec?.api_secure) {
- this.serviceForm.get('ssl_cert').setValue(response[0].spec?.ssl_cert);
- this.serviceForm.get('ssl_key').setValue(response[0].spec?.ssl_key);
+ this.cephServiceService
+ .list(new HttpParams({ fromObject: { limit: -1, offset: 0 } }), this.serviceName)
+ .observable.subscribe((response: CephServiceSpec[]) => {
+ const formKeys = ['service_type', 'service_id', 'unmanaged'];
+ formKeys.forEach((keys) => {
+ this.serviceForm.get(keys).setValue(response[0][keys]);
+ });
+ if (!response[0]['unmanaged']) {
+ const placementKey = Object.keys(response[0]['placement'])[0];
+ let placementValue: string;
+ ['hosts', 'label'].indexOf(placementKey) >= 0
+ ? (placementValue = placementKey)
+ : (placementValue = 'hosts');
+ this.serviceForm.get('placement').setValue(placementValue);
+ this.serviceForm.get('count').setValue(response[0]['placement']['count']);
+ if (response[0]?.placement[placementValue]) {
+ this.serviceForm.get(placementValue).setValue(response[0]?.placement[placementValue]);
}
- break;
- case 'rgw':
- this.serviceForm.get('rgw_frontend_port').setValue(response[0].spec?.rgw_frontend_port);
- this.serviceForm.get('ssl').setValue(response[0].spec?.ssl);
- if (response[0].spec?.ssl) {
+ }
+ switch (this.serviceType) {
+ case 'iscsi':
+ const specKeys = ['pool', 'api_password', 'api_user', 'trusted_ip_list', 'api_port'];
+ specKeys.forEach((key) => {
+ this.serviceForm.get(key).setValue(response[0].spec[key]);
+ });
+ this.serviceForm.get('ssl').setValue(response[0].spec?.api_secure);
+ if (response[0].spec?.api_secure) {
+ this.serviceForm.get('ssl_cert').setValue(response[0].spec?.ssl_cert);
+ this.serviceForm.get('ssl_key').setValue(response[0].spec?.ssl_key);
+ }
+ break;
+ case 'rgw':
this.serviceForm
- .get('ssl_cert')
- .setValue(response[0].spec?.rgw_frontend_ssl_certificate);
- }
- break;
- case 'ingress':
- const ingressSpecKeys = [
- 'backend_service',
- 'virtual_ip',
- 'frontend_port',
- 'monitor_port',
- 'virtual_interface_networks',
- 'ssl'
- ];
- ingressSpecKeys.forEach((key) => {
- this.serviceForm.get(key).setValue(response[0].spec[key]);
- });
- if (response[0].spec?.ssl) {
- this.serviceForm.get('ssl_cert').setValue(response[0].spec?.ssl_cert);
- this.serviceForm.get('ssl_key').setValue(response[0].spec?.ssl_key);
- }
- break;
- case 'snmp-gateway':
- const snmpCommonSpecKeys = ['snmp_version', 'snmp_destination'];
- snmpCommonSpecKeys.forEach((key) => {
- this.serviceForm.get(key).setValue(response[0].spec[key]);
- });
- if (this.serviceForm.getValue('snmp_version') === 'V3') {
- const snmpV3SpecKeys = [
- 'engine_id',
- 'auth_protocol',
- 'privacy_protocol',
- 'snmp_v3_auth_username',
- 'snmp_v3_auth_password',
- 'snmp_v3_priv_password'
+ .get('rgw_frontend_port')
+ .setValue(response[0].spec?.rgw_frontend_port);
+ this.serviceForm.get('ssl').setValue(response[0].spec?.ssl);
+ if (response[0].spec?.ssl) {
+ this.serviceForm
+ .get('ssl_cert')
+ .setValue(response[0].spec?.rgw_frontend_ssl_certificate);
+ }
+ break;
+ case 'ingress':
+ const ingressSpecKeys = [
+ 'backend_service',
+ 'virtual_ip',
+ 'frontend_port',
+ 'monitor_port',
+ 'virtual_interface_networks',
+ 'ssl'
];
- snmpV3SpecKeys.forEach((key) => {
- if (key !== null) {
- if (
- key === 'snmp_v3_auth_username' ||
- key === 'snmp_v3_auth_password' ||
- key === 'snmp_v3_priv_password'
- ) {
- this.serviceForm.get(key).setValue(response[0].spec['credentials'][key]);
- } else {
- this.serviceForm.get(key).setValue(response[0].spec[key]);
- }
- }
+ ingressSpecKeys.forEach((key) => {
+ this.serviceForm.get(key).setValue(response[0].spec[key]);
});
- } else {
- this.serviceForm
- .get('snmp_community')
- .setValue(response[0].spec['credentials']['snmp_community']);
- }
- break;
- }
- });
+ if (response[0].spec?.ssl) {
+ this.serviceForm.get('ssl_cert').setValue(response[0].spec?.ssl_cert);
+ this.serviceForm.get('ssl_key').setValue(response[0].spec?.ssl_key);
+ }
+ break;
+ case 'snmp-gateway':
+ const snmpCommonSpecKeys = ['snmp_version', 'snmp_destination'];
+ snmpCommonSpecKeys.forEach((key) => {
+ this.serviceForm.get(key).setValue(response[0].spec[key]);
+ });
+ if (this.serviceForm.getValue('snmp_version') === 'V3') {
+ const snmpV3SpecKeys = [
+ 'engine_id',
+ 'auth_protocol',
+ 'privacy_protocol',
+ 'snmp_v3_auth_username',
+ 'snmp_v3_auth_password',
+ 'snmp_v3_priv_password'
+ ];
+ snmpV3SpecKeys.forEach((key) => {
+ if (key !== null) {
+ if (
+ key === 'snmp_v3_auth_username' ||
+ key === 'snmp_v3_auth_password' ||
+ key === 'snmp_v3_priv_password'
+ ) {
+ this.serviceForm.get(key).setValue(response[0].spec['credentials'][key]);
+ } else {
+ this.serviceForm.get(key).setValue(response[0].spec[key]);
+ }
+ }
+ });
+ } else {
+ this.serviceForm
+ .get('snmp_community')
+ .setValue(response[0].spec['credentials']['snmp_community']);
+ }
+ break;
+ }
+ });
}
}
+ getServiceIds(selectedServiceType: string) {
+ this.serviceIds = this.serviceList
+ ?.filter((service) => service['service_type'] === selectedServiceType)
+ .map((service) => service['service_id']);
+ }
+
disableForEditing(serviceType: string) {
const disableForEditKeys = ['service_type', 'service_id'];
disableForEditKeys.forEach((key) => {
serviceName = `${serviceType}.${serviceId}`;
serviceSpec['service_id'] = serviceId;
}
+
+ // These services has some fields to be
+ // filled out even if unmanaged is true
+ switch (serviceType) {
+ case 'ingress':
+ serviceSpec['backend_service'] = values['backend_service'];
+ serviceSpec['service_id'] = values['backend_service'];
+ if (_.isNumber(values['frontend_port']) && values['frontend_port'] > 0) {
+ serviceSpec['frontend_port'] = values['frontend_port'];
+ }
+ if (_.isString(values['virtual_ip']) && !_.isEmpty(values['virtual_ip'])) {
+ serviceSpec['virtual_ip'] = values['virtual_ip'].trim();
+ }
+ if (_.isNumber(values['monitor_port']) && values['monitor_port'] > 0) {
+ serviceSpec['monitor_port'] = values['monitor_port'];
+ }
+ break;
+
+ case 'iscsi':
+ serviceSpec['pool'] = values['pool'];
+ break;
+
+ case 'snmp-gateway':
+ serviceSpec['credentials'] = {};
+ serviceSpec['snmp_version'] = values['snmp_version'];
+ serviceSpec['snmp_destination'] = values['snmp_destination'];
+ if (values['snmp_version'] === 'V3') {
+ serviceSpec['engine_id'] = values['engine_id'];
+ serviceSpec['auth_protocol'] = values['auth_protocol'];
+ serviceSpec['credentials']['snmp_v3_auth_username'] = values['snmp_v3_auth_username'];
+ serviceSpec['credentials']['snmp_v3_auth_password'] = values['snmp_v3_auth_password'];
+ if (values['privacy_protocol'] !== null) {
+ serviceSpec['privacy_protocol'] = values['privacy_protocol'];
+ serviceSpec['credentials']['snmp_v3_priv_password'] = values['snmp_v3_priv_password'];
+ }
+ } else {
+ serviceSpec['credentials']['snmp_community'] = values['snmp_community'];
+ }
+ break;
+ }
+
if (!values['unmanaged']) {
switch (values['placement']) {
case 'hosts':
}
break;
case 'iscsi':
- serviceSpec['pool'] = values['pool'];
if (_.isString(values['trusted_ip_list']) && !_.isEmpty(values['trusted_ip_list'])) {
serviceSpec['trusted_ip_list'] = values['trusted_ip_list'].trim();
}
}
break;
case 'ingress':
- serviceSpec['backend_service'] = values['backend_service'];
- serviceSpec['service_id'] = values['backend_service'];
- if (_.isString(values['virtual_ip']) && !_.isEmpty(values['virtual_ip'])) {
- serviceSpec['virtual_ip'] = values['virtual_ip'].trim();
- }
- if (_.isNumber(values['frontend_port']) && values['frontend_port'] > 0) {
- serviceSpec['frontend_port'] = values['frontend_port'];
- }
- if (_.isNumber(values['monitor_port']) && values['monitor_port'] > 0) {
- serviceSpec['monitor_port'] = values['monitor_port'];
- }
serviceSpec['ssl'] = values['ssl'];
if (values['ssl']) {
serviceSpec['ssl_cert'] = values['ssl_cert']?.trim();
}
serviceSpec['virtual_interface_networks'] = values['virtual_interface_networks'];
break;
- case 'snmp-gateway':
- serviceSpec['credentials'] = {};
- serviceSpec['snmp_version'] = values['snmp_version'];
- serviceSpec['snmp_destination'] = values['snmp_destination'];
- if (values['snmp_version'] === 'V3') {
- serviceSpec['engine_id'] = values['engine_id'];
- serviceSpec['auth_protocol'] = values['auth_protocol'];
- serviceSpec['credentials']['snmp_v3_auth_username'] = values['snmp_v3_auth_username'];
- serviceSpec['credentials']['snmp_v3_auth_password'] = values['snmp_v3_auth_password'];
- if (values['privacy_protocol'] !== null) {
- serviceSpec['privacy_protocol'] = values['privacy_protocol'];
- serviceSpec['credentials']['snmp_v3_priv_password'] = values['snmp_v3_priv_password'];
- }
- } else {
- serviceSpec['credentials']['snmp_community'] = values['snmp_community'];
- }
- break;
}
}
task: new FinishedTask(taskUrl, {
service_name: serviceName
}),
- call: this.cephServiceService.create(serviceSpec)
+ call: this.editing
+ ? this.cephServiceService.update(serviceSpec)
+ : this.cephServiceService.create(serviceSpec)
})
.subscribe({
error() {