import yaml
-from ceph.deployment.service_spec import PlacementSpec
+from ceph.deployment.service_spec import (
+ PlacementSpec,
+ SMBClusterPublicIPSpec,
+ SpecValidationError,
+)
from object_format import ErrorResponseBase
from . import resourcelib, validation
return self.to_json()
+# This class is a near 1:1 mirror of the service spec helper class.
+@resourcelib.component()
+class ClusterPublicIPAssignment(_RBase):
+ address: str
+ destination: Union[List[str], str, None] = None
+
+ def to_spec(self) -> SMBClusterPublicIPSpec:
+ return SMBClusterPublicIPSpec(
+ address=self.address,
+ destination=self.destination,
+ )
+
+ def validate(self) -> None:
+ try:
+ self.to_spec().validate()
+ except SpecValidationError as err:
+ raise ValueError(str(err)) from err
+
+
@resourcelib.resource('ceph.smb.cluster')
class Cluster(_RBase):
"""Represents a cluster (instance) that is / should be present."""
placement: Optional[WrappedPlacementSpec] = None
# control if the cluster is really a cluster
clustering: Optional[SMBClustering] = None
+ public_addrs: Optional[List[ClusterPublicIPAssignment]] = None
def validate(self) -> None:
if not self.cluster_id:
# clustering enabled unless we're deploying a single instance "cluster"
return count != 1
+ def service_spec_public_addrs(
+ self,
+ ) -> Optional[List[SMBClusterPublicIPSpec]]:
+ if self.public_addrs is None:
+ return None
+ return [a.to_spec() for a in self.public_addrs]
+
@resourcelib.resource('ceph.smb.join.auth')
class JoinAuth(_RBase):