validation.check_access_name(self.name)
+@resourcelib.component()
+class RGWStorage(_RBase):
+ """Description of where in an RGW bucket a share is located."""
+
+ bucket: str
+ user_id: Optional[str] = None
+ access_key_id: Optional[str] = None
+ secret_access_key: Optional[str] = None
+
+ def validate(self) -> None:
+ if not self.bucket:
+ raise ValueError('bucket requires a value')
+
+ def convert(self, operation: ConversionOp) -> Self:
+ """Convert password fields based on the operation."""
+ return self.__class__(
+ bucket=self.bucket,
+ user_id=self.user_id,
+ access_key_id=(
+ _password_convert(self.access_key_id, operation)
+ if self.access_key_id
+ else None
+ ),
+ secret_access_key=(
+ _password_convert(self.secret_access_key, operation)
+ if self.secret_access_key
+ else None
+ ),
+ )
+
+ @resourcelib.customize
+ def _customize_resource(rc: resourcelib.Resource) -> resourcelib.Resource:
+ rc.user_id.quiet = True
+ rc.access_key_id.quiet = True
+ rc.secret_access_key.quiet = True
+ return rc
+
+
@resourcelib.component()
class HostAccessEntry(_RBase):
access: HostAccess
comment: Optional[str] = None
max_connections: Optional[int] = None
cephfs: Optional[CephFSStorage] = None
+ rgw: Optional[RGWStorage] = None
custom_smb_share_options: Optional[Dict[str, str]] = None
login_control: Optional[List[LoginAccessEntry]] = None
restrict_access: bool = False
validation.check_share_name(self.name)
if self.intent != Intent.PRESENT:
raise ValueError('Share must have present intent')
- # currently only cephfs is supported
- if self.cephfs is None:
- raise ValueError('a cephfs configuration is required')
+ # Ensure exactly one storage backend is specified
+ storage_count = len([b for b in (self.cephfs, self.rgw) if b])
+ if storage_count == 0:
+ raise ValueError(
+ 'a storage configuration is required (cephfs or rgw)'
+ )
+ if storage_count > 1:
+ raise ValueError('only one storage backend can be specified')
if self.max_connections is not None and self.max_connections < 0:
raise ValueError(
'max_connections must be 0 or a non-negative integer'
"""Return the .cephfs storage object or raise ValueError if None."""
return checked(self.cephfs)
+ def convert(self, operation: ConversionOp) -> Self:
+ """Convert password fields in nested storage components."""
+ return self.__class__(
+ cluster_id=self.cluster_id,
+ share_id=self.share_id,
+ intent=self.intent,
+ name=self.name,
+ readonly=self.readonly,
+ browseable=self.browseable,
+ comment=self.comment,
+ max_connections=self.max_connections,
+ cephfs=self.cephfs.convert(operation) if self.cephfs else None,
+ rgw=self.rgw.convert(operation) if self.rgw else None,
+ custom_smb_share_options=self.custom_smb_share_options,
+ login_control=self.login_control,
+ restrict_access=self.restrict_access,
+ hosts_access=self.hosts_access,
+ )
+
@resourcelib.customize
def _customize_resource(rc: resourcelib.Resource) -> resourcelib.Resource:
rc.restrict_access.quiet = True