| 1531 | ) |
| 1532 | |
| 1533 | def validate(self) -> None: |
| 1534 | super(NFSServiceSpec, self).validate() |
| 1535 | |
| 1536 | if self.virtual_ip and (self.ip_addrs or self.networks): |
| 1537 | raise SpecValidationError("Invalid NFS spec: Cannot set virtual_ip and " |
| 1538 | f"{'ip_addrs' if self.ip_addrs else 'networks'} fields") |
| 1539 | |
| 1540 | # Validate colocation_ports |
| 1541 | self.validate_colocation_ports() |
| 1542 | |
| 1543 | # validate qos dict |
| 1544 | if self.cluster_qos_config: |
| 1545 | qos_enable = self.cluster_qos_config.get('enable_qos', True) |
| 1546 | enable_bw_ctrl = self.cluster_qos_config.get('enable_bw_control', False) |
| 1547 | combined_bw_ctrl = self.cluster_qos_config.get('combined_rw_bw_control', False) |
| 1548 | enable_ops_ctrl = self.cluster_qos_config.get('enable_iops_control', False) |
| 1549 | for key in [qos_enable, enable_bw_ctrl, combined_bw_ctrl, enable_ops_ctrl]: |
| 1550 | if not isinstance(key, bool): |
| 1551 | raise SpecValidationError('Invalid NFS spec: cluster_qos_config is not correct') |
| 1552 | if not qos_enable or not (enable_bw_ctrl or enable_ops_ctrl): |
| 1553 | # this means bandwidth or iops qos won't be enable, we don't need to set qos |
| 1554 | self.cluster_qos_config = None |
| 1555 | return |
| 1556 | |
| 1557 | # Verify qos_type |
| 1558 | qos_type = self.cluster_qos_config.get('qos_type') |
| 1559 | valid_qos_types = ['PerShare', 'PerClient', 'PerShare_PerClient'] |
| 1560 | if not qos_type: |
| 1561 | raise SpecValidationError( |
| 1562 | 'Invalid NFS spec: to set cluster-level QoS, "qos_type" must be provided.' |
| 1563 | ) |
| 1564 | if qos_type not in valid_qos_types: |
| 1565 | raise SpecValidationError( |
| 1566 | f'Invalid NFS spec: "{qos_type}" is not a valid qos_type. ' |
| 1567 | f'Valid types are: {"|".join(valid_qos_types)}.' |
| 1568 | ) |
| 1569 | |
| 1570 | # Verify bandwidth and IOPS types |
| 1571 | for key, value in self.cluster_qos_config.items(): |
| 1572 | if key.endswith('bw') and not isinstance(value, str): |
| 1573 | raise SpecValidationError( |
| 1574 | f"Invalid NFS spec: bandwidth '{key}' should be a string" |
| 1575 | ) |
| 1576 | if key.endswith('iops') and not isinstance(value, int): |
| 1577 | raise SpecValidationError( |
| 1578 | f"Invalid NFS spec: IOPS '{key}' should be an integer") |
| 1579 | |
| 1580 | # TLS certificate validation |
| 1581 | if self.ssl and not self.certificate_source: |
| 1582 | raise SpecValidationError('If SSL is enabled, a certificate source must be provided.') |
| 1583 | if self.certificate_source == CertificateSource.INLINE.value: |
| 1584 | tls_field_names = [ |
| 1585 | 'ssl_cert', |
| 1586 | 'ssl_key', |
| 1587 | 'ssl_ca_cert', |
| 1588 | ] |
| 1589 | tls_fields = [getattr(self, tls_field) for tls_field in tls_field_names] |
| 1590 | if any(tls_fields) and not all(tls_fields): |