)
from cephadmlib.host_facts import HostFacts, list_networks
from cephadmlib.ssh import authorize_ssh_key, check_ssh_connectivity
+from cephadmlib.daemon_form import (
+ DaemonForm,
+ register as register_daemon_form,
+)
FuncT = TypeVar('FuncT', bound=Callable)
##################################
-class Ceph(object):
+@register_daemon_form
+class Ceph(DaemonForm):
daemons = ('mon', 'mgr', 'osd', 'mds', 'rgw', 'rbd-mirror',
'crash', 'cephfs-mirror', 'ceph-exporter')
gateways = ('iscsi', 'nfs', 'nvmeof')
+ @classmethod
+ def for_daemon_type(cls, daemon_type: str) -> bool:
+ # TODO: figure out a way to un-special-case osd
+ return daemon_type in cls.daemons and daemon_type != 'osd'
+
+ def __init__(self, ident: DaemonIdentity) -> None:
+ self._identity = ident
+
+ @classmethod
+ def create(cls, ctx: CephadmContext, ident: DaemonIdentity) -> 'Ceph':
+ return cls(ident)
+
+ @property
+ def identity(self) -> DaemonIdentity:
+ return self._identity
+
##################################
-class OSD(object):
+@register_daemon_form
+class OSD(Ceph):
+ @classmethod
+ def for_daemon_type(cls, daemon_type: str) -> bool:
+ # TODO: figure out a way to un-special-case osd
+ return daemon_type == 'osd'
+
@staticmethod
def get_sysctl_settings() -> List[str]:
return [
##################################
-class SNMPGateway:
+@register_daemon_form
+class SNMPGateway(DaemonForm):
"""Defines an SNMP gateway between Prometheus and SNMP monitoring Frameworks"""
daemon_type = 'snmp-gateway'
SUPPORTED_VERSIONS = ['V2c', 'V3']
DEFAULT_PORT = 9464
env_filename = 'snmp-gateway.conf'
+ @classmethod
+ def for_daemon_type(cls, daemon_type: str) -> bool:
+ return cls.daemon_type == daemon_type
+
def __init__(self,
ctx: CephadmContext,
fsid: str,
assert cfgs # assert some config data was found
return cls(ctx, fsid, daemon_id, cfgs, ctx.image)
+ @classmethod
+ def create(cls, ctx: CephadmContext, ident: DaemonIdentity) -> 'SNMPGateway':
+ return cls.init(ctx, ident.fsid, ident.daemon_id)
+
+ @property
+ def identity(self) -> DaemonIdentity:
+ return DaemonIdentity(self.fsid, self.daemon_type, self.daemon_id)
+
@staticmethod
def get_version(ctx: CephadmContext, fsid: str, daemon_id: str) -> Optional[str]:
"""Return the version of the notifier from it's http endpoint"""
##################################
-class Monitoring(object):
+@register_daemon_form
+class Monitoring(DaemonForm):
"""Define the configs for the monitoring containers"""
port_map = {
},
} # type: ignore
+ @classmethod
+ def for_daemon_type(cls, daemon_type: str) -> bool:
+ return daemon_type in cls.components
+
@staticmethod
def get_version(ctx, container_id, daemon_type):
# type: (CephadmContext, str, str) -> str
version = out.split(' ')[2]
return version
+ def __init__(self, ident: DaemonIdentity) -> None:
+ self._identity = ident
+
+ @classmethod
+ def create(cls, ctx: CephadmContext, ident: DaemonIdentity) -> 'Monitoring':
+ return cls(ident)
+
+ @property
+ def identity(self) -> DaemonIdentity:
+ return self._identity
+
##################################
-class NFSGanesha(object):
+@register_daemon_form
+class NFSGanesha(DaemonForm):
"""Defines a NFS-Ganesha container"""
daemon_type = 'nfs'
'nfs': 2049,
}
+ @classmethod
+ def for_daemon_type(cls, daemon_type: str) -> bool:
+ return cls.daemon_type == daemon_type
+
def __init__(self,
ctx,
fsid,
# type: (CephadmContext, str, Union[int, str]) -> NFSGanesha
return cls(ctx, fsid, daemon_id, fetch_configs(ctx), ctx.image)
+ @classmethod
+ def create(cls, ctx: CephadmContext, ident: DaemonIdentity) -> 'NFSGanesha':
+ return cls.init(ctx, ident.fsid, ident.daemon_id)
+
+ @property
+ def identity(self) -> DaemonIdentity:
+ return DaemonIdentity(self.fsid, self.daemon_type, self.daemon_id)
+
def get_container_mounts(self, data_dir):
# type: (str) -> Dict[str, str]
mounts = dict()
##################################
-class CephIscsi(object):
+@register_daemon_form
+class CephIscsi(DaemonForm):
"""Defines a Ceph-Iscsi container"""
daemon_type = 'iscsi'
required_files = ['iscsi-gateway.cfg']
+ @classmethod
+ def for_daemon_type(cls, daemon_type: str) -> bool:
+ return cls.daemon_type == daemon_type
+
def __init__(self,
ctx,
fsid,
return cls(ctx, fsid, daemon_id,
fetch_configs(ctx), ctx.image)
+ @classmethod
+ def create(cls, ctx: CephadmContext, ident: DaemonIdentity) -> 'CephIscsi':
+ return cls.init(ctx, ident.fsid, ident.daemon_id)
+
+ @property
+ def identity(self) -> DaemonIdentity:
+ return DaemonIdentity(self.fsid, self.daemon_type, self.daemon_id)
+
@staticmethod
def get_container_mounts(data_dir, log_dir):
# type: (str, str) -> Dict[str, str]
##################################
-class CephNvmeof(object):
+@register_daemon_form
+class CephNvmeof(DaemonForm):
"""Defines a Ceph-Nvmeof container"""
daemon_type = 'nvmeof'
required_files = ['ceph-nvmeof.conf']
default_image = DEFAULT_NVMEOF_IMAGE
+ @classmethod
+ def for_daemon_type(cls, daemon_type: str) -> bool:
+ return cls.daemon_type == daemon_type
+
def __init__(self,
ctx,
fsid,
return cls(ctx, fsid, daemon_id,
fetch_configs(ctx), ctx.image)
+ @classmethod
+ def create(cls, ctx: CephadmContext, ident: DaemonIdentity) -> 'CephNvmeof':
+ return cls.init(ctx, ident.fsid, ident.daemon_id)
+
+ @property
+ def identity(self) -> DaemonIdentity:
+ return DaemonIdentity(self.fsid, self.daemon_type, self.daemon_id)
+
@staticmethod
def get_container_mounts(data_dir: str) -> Dict[str, str]:
mounts = dict()
##################################
-class CephExporter(object):
+@register_daemon_form
+class CephExporter(DaemonForm):
"""Defines a Ceph exporter container"""
daemon_type = 'ceph-exporter'
'ceph-exporter': DEFAULT_PORT,
}
+ @classmethod
+ def for_daemon_type(cls, daemon_type: str) -> bool:
+ return cls.daemon_type == daemon_type
+
def __init__(self,
ctx: CephadmContext,
fsid: str, daemon_id: Union[int, str],
return cls(ctx, fsid, daemon_id,
fetch_configs(ctx), ctx.image)
+ @classmethod
+ def create(cls, ctx: CephadmContext, ident: DaemonIdentity) -> 'CephExporter':
+ return cls.init(ctx, ident.fsid, ident.daemon_id)
+
+ @property
+ def identity(self) -> DaemonIdentity:
+ return DaemonIdentity(self.fsid, self.daemon_type, self.daemon_id)
+
@staticmethod
def get_container_mounts() -> Dict[str, str]:
mounts = dict()
##################################
-class HAproxy(object):
+@register_daemon_form
+class HAproxy(DaemonForm):
"""Defines an HAproxy container"""
daemon_type = 'haproxy'
required_files = ['haproxy.cfg']
default_image = DEFAULT_HAPROXY_IMAGE
+ @classmethod
+ def for_daemon_type(cls, daemon_type: str) -> bool:
+ return cls.daemon_type == daemon_type
+
def __init__(self,
ctx: CephadmContext,
fsid: str, daemon_id: Union[int, str],
return cls(ctx, fsid, daemon_id, fetch_configs(ctx),
ctx.image)
+ @classmethod
+ def create(cls, ctx: CephadmContext, ident: DaemonIdentity) -> 'HAproxy':
+ return cls.init(ctx, ident.fsid, ident.daemon_id)
+
+ @property
+ def identity(self) -> DaemonIdentity:
+ return DaemonIdentity(self.fsid, self.daemon_type, self.daemon_id)
+
def create_daemon_dirs(self, data_dir: str, uid: int, gid: int) -> None:
"""Create files under the container data dir"""
if not os.path.isdir(data_dir):
##################################
-class Keepalived(object):
+@register_daemon_form
+class Keepalived(DaemonForm):
"""Defines an Keepalived container"""
daemon_type = 'keepalived'
required_files = ['keepalived.conf']
default_image = DEFAULT_KEEPALIVED_IMAGE
+ @classmethod
+ def for_daemon_type(cls, daemon_type: str) -> bool:
+ return cls.daemon_type == daemon_type
+
def __init__(self,
ctx: CephadmContext,
fsid: str, daemon_id: Union[int, str],
return cls(ctx, fsid, daemon_id,
fetch_configs(ctx), ctx.image)
+ @classmethod
+ def create(cls, ctx: CephadmContext, ident: DaemonIdentity) -> 'Keepalived':
+ return cls.init(ctx, ident.fsid, ident.daemon_id)
+
+ @property
+ def identity(self) -> DaemonIdentity:
+ return DaemonIdentity(self.fsid, self.daemon_type, self.daemon_id)
+
def create_daemon_dirs(self, data_dir: str, uid: int, gid: int) -> None:
"""Create files under the container data dir"""
if not os.path.isdir(data_dir):
##################################
-class Tracing(object):
+@register_daemon_form
+class Tracing(DaemonForm):
"""Define the configs for the jaeger tracing containers"""
components: Dict[str, Dict[str, Any]] = {
},
} # type: ignore
+ @classmethod
+ def for_daemon_type(cls, daemon_type: str) -> bool:
+ return daemon_type in cls.components
+
@staticmethod
def set_configuration(config: Dict[str, str], daemon_type: str) -> None:
if daemon_type in ['jaeger-collector', 'jaeger-query']:
'--processor.jaeger-compact.server-host-port=6799'
]
+ def __init__(self, ident: DaemonIdentity) -> None:
+ self._identity = ident
+
+ @classmethod
+ def create(cls, ctx: CephadmContext, ident: DaemonIdentity) -> 'Tracing':
+ return cls(ident)
+
+ @property
+ def identity(self) -> DaemonIdentity:
+ return self._identity
+
##################################
-class CustomContainer(object):
+@register_daemon_form
+class CustomContainer(DaemonForm):
"""Defines a custom container"""
daemon_type = 'container'
+ @classmethod
+ def for_daemon_type(cls, daemon_type: str) -> bool:
+ return cls.daemon_type == daemon_type
+
def __init__(self,
fsid: str, daemon_id: Union[int, str],
config_json: Dict, image: str) -> None:
return cls(fsid, daemon_id,
fetch_configs(ctx), ctx.image)
+ @classmethod
+ def create(cls, ctx: CephadmContext, ident: DaemonIdentity) -> 'CustomContainer':
+ return cls.init(ctx, ident.fsid, ident.daemon_id)
+
+ @property
+ def identity(self) -> DaemonIdentity:
+ return DaemonIdentity(self.fsid, self.daemon_type, self.daemon_id)
+
def create_daemon_dirs(self, data_dir: str, uid: int, gid: int) -> None:
"""
Create dirs/files below the container data directory.