]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
cephadm: Modify the structure of the default container images 60412/head
authorShweta Bhosale <Shweta.Bhosale1@ibm.com>
Mon, 21 Oct 2024 05:12:24 +0000 (10:42 +0530)
committerShweta Bhosale <Shweta.Bhosale1@ibm.com>
Fri, 22 Nov 2024 05:00:00 +0000 (10:30 +0530)
Fixes: https://tracker.ceph.com/issues/68605?next_issue_id=68599
Signed-off-by: Shweta Bhosale <Shweta.Bhosale1@ibm.com>
14 files changed:
doc/cephadm/services/mgmt-gateway.rst
doc/cephadm/services/monitoring.rst
doc/man/8/cephadm.rst
src/cephadm/cephadmlib/container_types.py
src/cephadm/cephadmlib/daemons/ingress.py
src/cephadm/cephadmlib/daemons/mgmt_gateway.py
src/cephadm/cephadmlib/daemons/monitoring.py
src/cephadm/cephadmlib/daemons/nvmeof.py
src/cephadm/cephadmlib/daemons/oauth2_proxy.py
src/cephadm/cephadmlib/daemons/smb.py
src/cephadm/cephadmlib/daemons/snmp.py
src/cephadm/cephadmlib/daemons/tracing.py
src/pybind/mgr/cephadm/module.py
src/python-common/ceph/cephadm/images.py

index 2b88d55952e9627136e3f0d4aa852a526e3832fe..55c024817aedd483bc8b98f80fd04ecaecf44a39 100644 (file)
@@ -183,7 +183,7 @@ The `mgmt-gateway` service internally makes use of nginx reverse proxy. The foll
 
 ::
 
-    DEFAULT_NGINX_IMAGE = 'quay.io/ceph/nginx:1.26.1'
+    mgr/cephadm/container_image_nginx = 'quay.io/ceph/nginx:sclorg-nginx-126'
 
 Admins can specify the image to be used by changing the `container_image_nginx` cephadm module option. If there were already
 running daemon(s) you must redeploy the daemon(s) in order to have them actually use the new image.
index 0e2c62105fac656969f95d45c0bab6cb50258177..ef987fd7bd32ffb476f1fe6e6243d531d1fff491 100644 (file)
@@ -173,24 +173,22 @@ the [ceph-users] mailing list in April of 2024. The thread can be viewed here:
 ``var/lib/ceph/{FSID}/cephadm.{DIGEST}``, where ``{DIGEST}`` is an alphanumeric
 string representing the currently-running version of Ceph.
 
-To see the default container images, run a command of the following form:
+To see the default container images, run below command:
 
 .. prompt:: bash #
 
-   grep -E "DEFAULT*IMAGE" /var/lib/ceph/{FSID}/cephadm.{DIGEST}
+   cephadm list-images
 
-::
-
-   DEFAULT_PROMETHEUS_IMAGE = 'quay.io/prometheus/prometheus:v2.51.0'
-   DEFAULT_LOKI_IMAGE = 'docker.io/grafana/loki:2.9.5'    
-   DEFAULT_PROMTAIL_IMAGE = 'docker.io/grafana/promtail:2.9.5'    
-   DEFAULT_NODE_EXPORTER_IMAGE = 'quay.io/prometheus/node-exporter:v1.7.0'    
-   DEFAULT_ALERT_MANAGER_IMAGE = 'quay.io/prometheus/alertmanager:v0.27.0'   
-   DEFAULT_GRAFANA_IMAGE = 'quay.io/ceph/grafana:10.4.0'
 
 Default monitoring images are specified in
-``/src/cephadm/cephadmlib/constants.py`` and in
-``/src/pybind/mgr/cephadm/module.py``.
+``/src/python-common/ceph/cephadm/images.py``.
+
+
+.. autoclass:: ceph.cephadm.images.DefaultImages
+   :members:
+   :undoc-members:
+   :exclude-members: desc, image_ref, key
+
 
 Using custom images
 ~~~~~~~~~~~~~~~~~~~
index 0847066b66daa666b376fe780a3398465019f5ed..b2cad6cb5059f87e5f73c9d1ea7498da0accfadc 100644 (file)
@@ -13,7 +13,7 @@ Synopsis
 |               [--log-dir LOG_DIR] [--logrotate-dir LOGROTATE_DIR]
 |               [--unit-dir UNIT_DIR] [--verbose] [--timeout TIMEOUT]
 |               [--retry RETRY] [--no-container-init]
-|               {version,pull,inspect-image,ls,list-networks,adopt,rm-daemon,rm-cluster,run,shell,enter,ceph-volume,unit,logs,bootstrap,deploy,check-host,prepare-host,add-repo,rm-repo,install}
+|               {version,pull,inspect-image,ls,list-networks,adopt,rm-daemon,rm-cluster,run,shell,enter,ceph-volume,unit,logs,bootstrap,deploy,check-host,prepare-host,add-repo,rm-repo,install,list-images}
 |               ...
 
 
@@ -104,6 +104,8 @@ Synopsis
 |                                [--registry-password REGISTRY_PASSWORD]
 |                                [--registry-json REGISTRY_JSON] [--fsid FSID]
 
+| **cephadm** **list-images**
+
 
 
 Description
@@ -527,6 +529,12 @@ Arguments:
 * [--name NAME, -n NAME]  daemon name (type.id)
 
 
+list-images
+-----------
+
+List the default container images for all services in ini format. The output can be modified with custom images and passed to --config flag during bootstrap.
+
+
 Availability
 ============
 
index f1e829cbdf7ba5683482f04a93af412ececca7d9..52a68888e78a249416933cfa67a1f524980d04d2 100644 (file)
@@ -9,7 +9,7 @@ from typing import Dict, List, Optional, Any, Union, Tuple, Iterable, cast
 
 from .call_wrappers import call, call_throws, CallVerbosity
 from .constants import DEFAULT_TIMEOUT
-import ceph.cephadm.images as default_images
+from ceph.cephadm.images import DefaultImages
 from .container_engines import Docker, Podman
 from .context import CephadmContext
 from .daemon_identity import DaemonIdentity, DaemonSubIdentity
@@ -665,14 +665,8 @@ def enable_shared_namespaces(
 
 def get_mgr_images() -> dict:
     """Return dict of default mgr images"""
-    mgr_prefix = 'mgr/cephadm/container_image_'
-    mgr_images = {}
-    images = vars(default_images)
-    for key, value in images.items():
-        if key.startswith('DEFAULT_') and key.endswith('_IMAGE'):
-            # flake8 and black disagree about spaces around ":" hence the noqa comment
-            suffix = key[
-                len('DEFAULT_') : -len('_IMAGE')  # noqa: E203
-            ].lower()
-            mgr_images[mgr_prefix + suffix] = value
+    mgr_prefix = 'mgr/cephadm/'
+    mgr_images = {
+        f'{mgr_prefix}{image.key}': image.image_ref for image in DefaultImages
+    }
     return mgr_images
index c88e39ac02576ca4fdb9a1b7ecf9a8752b44c188..645654b59c83afb1362f5841e9c4f4e40b9ce81a 100644 (file)
@@ -2,10 +2,7 @@ import os
 
 from typing import Dict, List, Optional, Tuple, Union
 
-from ceph.cephadm.images import (
-    DEFAULT_HAPROXY_IMAGE,
-    DEFAULT_KEEPALIVED_IMAGE,
-)
+from ceph.cephadm.images import DefaultImages
 from ..constants import (
     DATA_DIR_MODE,
 )
@@ -27,7 +24,7 @@ class HAproxy(ContainerDaemonForm):
 
     daemon_type = 'haproxy'
     required_files = ['haproxy.cfg']
-    default_image = DEFAULT_HAPROXY_IMAGE
+    default_image = DefaultImages.HAPROXY.image_ref
 
     @classmethod
     def for_daemon_type(cls, daemon_type: str) -> bool:
@@ -155,7 +152,7 @@ class Keepalived(ContainerDaemonForm):
 
     daemon_type = 'keepalived'
     required_files = ['keepalived.conf']
-    default_image = DEFAULT_KEEPALIVED_IMAGE
+    default_image = DefaultImages.KEEPALIVED.image_ref
 
     @classmethod
     def for_daemon_type(cls, daemon_type: str) -> bool:
index 85f7249590973c158eaaada3f6ba2361394aa7e2..2be18809aa383558406d05a86b363324c36ab102 100644 (file)
@@ -11,7 +11,7 @@ from ..context_getters import fetch_configs
 from ..daemon_form import register as register_daemon_form
 from ..daemon_identity import DaemonIdentity
 from ..deployment_utils import to_deployment_container
-from ceph.cephadm.images import DEFAULT_NGINX_IMAGE
+from ceph.cephadm.images import DefaultImages
 from ..data_utils import dict_get, is_fsid
 from ..file_utils import populate_files, makedirs, recursive_chown
 from ..exceptions import Error
@@ -32,7 +32,7 @@ class MgmtGateway(ContainerDaemonForm):
         'nginx_internal.key',
     ]
 
-    default_image = DEFAULT_NGINX_IMAGE
+    default_image = DefaultImages.NGINX.image_ref
 
     @classmethod
     def for_daemon_type(cls, daemon_type: str) -> bool:
@@ -44,7 +44,7 @@ class MgmtGateway(ContainerDaemonForm):
         fsid: str,
         daemon_id: str,
         config_json: Dict,
-        image: str = DEFAULT_NGINX_IMAGE,
+        image: str = DefaultImages.NGINX.image_ref,
     ):
         self.ctx = ctx
         self.fsid = fsid
index 710093f0f4674a5ed8f2ff8d8efc1d2c31606732..9a9402632b0a67c42adc2434c132de05d95a0561 100644 (file)
@@ -3,14 +3,7 @@ import os
 from typing import Dict, List, Tuple
 
 from ..call_wrappers import call, CallVerbosity
-from ceph.cephadm.images import (
-    DEFAULT_ALERTMANAGER_IMAGE,
-    DEFAULT_GRAFANA_IMAGE,
-    DEFAULT_LOKI_IMAGE,
-    DEFAULT_NODE_EXPORTER_IMAGE,
-    DEFAULT_PROMETHEUS_IMAGE,
-    DEFAULT_PROMTAIL_IMAGE,
-)
+from ceph.cephadm.images import DefaultImages
 from ..constants import (
     UID_NOBODY,
     GID_NOGROUP,
@@ -43,7 +36,7 @@ class Monitoring(ContainerDaemonForm):
 
     components = {
         'prometheus': {
-            'image': DEFAULT_PROMETHEUS_IMAGE,
+            'image': DefaultImages.PROMETHEUS.image_ref,
             'cpus': '2',
             'memory': '4GB',
             'args': [
@@ -55,7 +48,7 @@ class Monitoring(ContainerDaemonForm):
             ],
         },
         'loki': {
-            'image': DEFAULT_LOKI_IMAGE,
+            'image': DefaultImages.LOKI.image_ref,
             'cpus': '1',
             'memory': '1GB',
             'args': [
@@ -64,7 +57,7 @@ class Monitoring(ContainerDaemonForm):
             'config-json-files': ['loki.yml'],
         },
         'promtail': {
-            'image': DEFAULT_PROMTAIL_IMAGE,
+            'image': DefaultImages.PROMTAIL.image_ref,
             'cpus': '1',
             'memory': '1GB',
             'args': [
@@ -75,13 +68,13 @@ class Monitoring(ContainerDaemonForm):
             ],
         },
         'node-exporter': {
-            'image': DEFAULT_NODE_EXPORTER_IMAGE,
+            'image': DefaultImages.NODE_EXPORTER.image_ref,
             'cpus': '1',
             'memory': '1GB',
             'args': ['--no-collector.timex'],
         },
         'grafana': {
-            'image': DEFAULT_GRAFANA_IMAGE,
+            'image': DefaultImages.GRAFANA.image_ref,
             'cpus': '2',
             'memory': '4GB',
             'args': [],
@@ -93,7 +86,7 @@ class Monitoring(ContainerDaemonForm):
             ],
         },
         'alertmanager': {
-            'image': DEFAULT_ALERTMANAGER_IMAGE,
+            'image': DefaultImages.ALERTMANAGER.image_ref,
             'cpus': '2',
             'memory': '2GB',
             'args': [
index d916c7e639172b6442532a236160be85a8bd4263..06e60a49d8e4f905782c6a8a5e9efcd59095fa42 100644 (file)
@@ -8,7 +8,7 @@ from ..container_types import CephContainer
 from ..context_getters import fetch_configs, get_config_and_keyring
 from ..daemon_form import register as register_daemon_form
 from ..daemon_identity import DaemonIdentity
-from ceph.cephadm.images import DEFAULT_NVMEOF_IMAGE
+from ceph.cephadm.images import DefaultImages
 from ..context import CephadmContext
 from ..data_utils import dict_get, is_fsid
 from ..deployment_utils import to_deployment_container
@@ -26,7 +26,7 @@ class CephNvmeof(ContainerDaemonForm):
 
     daemon_type = 'nvmeof'
     required_files = ['ceph-nvmeof.conf']
-    default_image = DEFAULT_NVMEOF_IMAGE
+    default_image = DefaultImages.NVMEOF.image_ref
 
     @classmethod
     def for_daemon_type(cls, daemon_type: str) -> bool:
@@ -38,7 +38,7 @@ class CephNvmeof(ContainerDaemonForm):
         fsid: str,
         daemon_id: Union[int, str],
         config_json: Dict,
-        image: str = DEFAULT_NVMEOF_IMAGE,
+        image: str = DefaultImages.NVMEOF.image_ref,
     ) -> None:
         self.ctx = ctx
         self.fsid = fsid
index 14202111c14ec6257354b2562515df25a16f49c1..c4f4ec5562fa2ca83f3c1fa63ab41f364dffa132 100644 (file)
@@ -11,7 +11,7 @@ from ..context_getters import fetch_configs
 from ..daemon_form import register as register_daemon_form
 from ..daemon_identity import DaemonIdentity
 from ..deployment_utils import to_deployment_container
-from ceph.cephadm.images import DEFAULT_OAUTH2_PROXY_IMAGE
+from ceph.cephadm.images import DefaultImages
 from ..constants import UID_NOBODY, GID_NOGROUP
 from ..data_utils import dict_get, is_fsid
 from ..file_utils import populate_files, makedirs, recursive_chown
@@ -25,7 +25,7 @@ logger = logging.getLogger()
 class OAuth2Proxy(ContainerDaemonForm):
     """Define the configs for the jaeger tracing containers"""
 
-    default_image = DEFAULT_OAUTH2_PROXY_IMAGE
+    default_image = DefaultImages.OAUTH2_PROXY.image_ref
     daemon_type = 'oauth2-proxy'
     required_files = [
         'oauth2-proxy.conf',
@@ -43,7 +43,7 @@ class OAuth2Proxy(ContainerDaemonForm):
         fsid: str,
         daemon_id: str,
         config_json: Dict,
-        image: str = DEFAULT_OAUTH2_PROXY_IMAGE,
+        image: str = DefaultImages.OAUTH2_PROXY.image_ref,
     ):
         self.ctx = ctx
         self.fsid = fsid
index 33d43cbe6cea4a9327265258d4253aa952ca02d5..0efde19881285f78768674df4523dc17a145f5a1 100644 (file)
@@ -14,7 +14,7 @@ from .. import data_utils
 from .. import deployment_utils
 from .. import file_utils
 from ..call_wrappers import call, CallVerbosity
-from ceph.cephadm.images import DEFAULT_SAMBA_IMAGE
+from ceph.cephadm.images import DefaultImages
 from ..container_daemon_form import ContainerDaemonForm, daemon_to_container
 from ..container_engines import Podman
 from ..container_types import (
@@ -368,7 +368,7 @@ class SMB(ContainerDaemonForm):
 
     daemon_type = 'smb'
     daemon_base = '/usr/sbin/smbd'
-    default_image = DEFAULT_SAMBA_IMAGE
+    default_image = DefaultImages.SAMBA.image_ref
 
     @classmethod
     def for_daemon_type(cls, daemon_type: str) -> bool:
index ab84a302f2c9d40739d187105f5c631086d37ca4..0557a2ef97235d50f9080576f6c72748a3633b95 100644 (file)
@@ -5,7 +5,7 @@ from typing import Any, Dict, List, Optional, Tuple, Union
 from urllib.error import HTTPError, URLError
 from urllib.request import urlopen
 
-from ceph.cephadm.images import DEFAULT_SNMP_GATEWAY_IMAGE
+from ceph.cephadm.images import DefaultImages
 from ..container_daemon_form import ContainerDaemonForm, daemon_to_container
 from ..container_types import CephContainer
 from ..context import CephadmContext
@@ -24,7 +24,7 @@ class SNMPGateway(ContainerDaemonForm):
 
     daemon_type = 'snmp-gateway'
     SUPPORTED_VERSIONS = ['V2c', 'V3']
-    default_image = DEFAULT_SNMP_GATEWAY_IMAGE
+    default_image = DefaultImages.SNMP_GATEWAY.image_ref
     DEFAULT_PORT = 9464
     env_filename = 'snmp-gateway.conf'
 
index 4cf7433945567e69b2507b764a853ef0655e0c54..44548a61d1418d20cca096ae5a6fcdf0d9e798c9 100644 (file)
@@ -2,12 +2,7 @@ import logging
 
 from typing import Any, Dict, List, Tuple
 
-from ceph.cephadm.images import (
-    DEFAULT_ELASTICSEARCH_IMAGE,
-    DEFAULT_JAEGER_AGENT_IMAGE,
-    DEFAULT_JAEGER_COLLECTOR_IMAGE,
-    DEFAULT_JAEGER_QUERY_IMAGE,
-)
+from ceph.cephadm.images import DefaultImages
 from ..container_daemon_form import ContainerDaemonForm, daemon_to_container
 from ..container_types import CephContainer
 from ..context import CephadmContext
@@ -27,17 +22,17 @@ class Tracing(ContainerDaemonForm):
 
     components: Dict[str, Dict[str, Any]] = {
         'elasticsearch': {
-            'image': DEFAULT_ELASTICSEARCH_IMAGE,
+            'image': DefaultImages.ELASTICSEARCH.image_ref,
             'envs': ['discovery.type=single-node'],
         },
         'jaeger-agent': {
-            'image': DEFAULT_JAEGER_AGENT_IMAGE,
+            'image': DefaultImages.JAEGER_AGENT.image_ref,
         },
         'jaeger-collector': {
-            'image': DEFAULT_JAEGER_COLLECTOR_IMAGE,
+            'image': DefaultImages.JAEGER_COLLECTOR.image_ref,
         },
         'jaeger-query': {
-            'image': DEFAULT_JAEGER_QUERY_IMAGE,
+            'image': DefaultImages.JAEGER_QUERY.image_ref,
         },
     }  # type: ignore
 
index e851f1ee3fcc65fbf5cb86e63050f28e7ae98ab5..bf14f8d1715bddb49dde258b540eac4ea5d954a1 100644 (file)
@@ -30,7 +30,7 @@ import multiprocessing.pool
 import subprocess
 from prettytable import PrettyTable
 
-import ceph.cephadm.images as default_images
+from ceph.cephadm.images import DefaultImages
 from ceph.deployment import inventory
 from ceph.deployment.drive_group import DriveGroupSpec
 from ceph.deployment.service_spec import \
@@ -217,96 +217,6 @@ class CephadmOrchestrator(orchestrator.Orchestrator, MgrModule,
             desc='Container image name, without the tag',
             runtime=True,
         ),
-        Option(
-            'container_image_prometheus',
-            default=default_images.DEFAULT_PROMETHEUS_IMAGE,
-            desc='Prometheus container image',
-        ),
-        Option(
-            'container_image_nvmeof',
-            default=default_images.DEFAULT_NVMEOF_IMAGE,
-            desc='Nvme-of container image',
-        ),
-        Option(
-            'container_image_grafana',
-            default=default_images.DEFAULT_GRAFANA_IMAGE,
-            desc='Prometheus container image',
-        ),
-        Option(
-            'container_image_alertmanager',
-            default=default_images.DEFAULT_ALERTMANAGER_IMAGE,
-            desc='Prometheus container image',
-        ),
-        Option(
-            'container_image_node_exporter',
-            default=default_images.DEFAULT_NODE_EXPORTER_IMAGE,
-            desc='Prometheus container image',
-        ),
-        Option(
-            'container_image_loki',
-            default=default_images.DEFAULT_LOKI_IMAGE,
-            desc='Loki container image',
-        ),
-        Option(
-            'container_image_promtail',
-            default=default_images.DEFAULT_PROMTAIL_IMAGE,
-            desc='Promtail container image',
-        ),
-        Option(
-            'container_image_haproxy',
-            default=default_images.DEFAULT_HAPROXY_IMAGE,
-            desc='HAproxy container image',
-        ),
-        Option(
-            'container_image_keepalived',
-            default=default_images.DEFAULT_KEEPALIVED_IMAGE,
-            desc='Keepalived container image',
-        ),
-        Option(
-            'container_image_snmp_gateway',
-            default=default_images.DEFAULT_SNMP_GATEWAY_IMAGE,
-            desc='SNMP Gateway container image',
-        ),
-        Option(
-            'container_image_nginx',
-            default=default_images.DEFAULT_NGINX_IMAGE,
-            desc='Nginx container image',
-        ),
-        Option(
-            'container_image_oauth2_proxy',
-            default=default_images.DEFAULT_OAUTH2_PROXY_IMAGE,
-            desc='oauth2-proxy container image',
-        ),
-        Option(
-            'container_image_elasticsearch',
-            default=default_images.DEFAULT_ELASTICSEARCH_IMAGE,
-            desc='elasticsearch container image',
-        ),
-        Option(
-            'container_image_jaeger_agent',
-            default=default_images.DEFAULT_JAEGER_AGENT_IMAGE,
-            desc='Jaeger agent container image',
-        ),
-        Option(
-            'container_image_jaeger_collector',
-            default=default_images.DEFAULT_JAEGER_COLLECTOR_IMAGE,
-            desc='Jaeger collector container image',
-        ),
-        Option(
-            'container_image_jaeger_query',
-            default=default_images.DEFAULT_JAEGER_QUERY_IMAGE,
-            desc='Jaeger query container image',
-        ),
-        Option(
-            'container_image_samba',
-            default=default_images.DEFAULT_SAMBA_IMAGE,
-            desc='Samba/SMB container image',
-        ),
-        Option(
-            'container_image_samba_metrics',
-            default=default_images.DEFAULT_SAMBA_METRICS_IMAGE,
-            desc='Samba/SMB metrics exporter container image',
-        ),
         Option(
             'warn_on_stray_hosts',
             type='bool',
@@ -543,6 +453,8 @@ class CephadmOrchestrator(orchestrator.Orchestrator, MgrModule,
             desc="Default address for RedFish API (oob management)."
         ),
     ]
+    for image in DefaultImages:
+        MODULE_OPTIONS.append(Option(image.key, default=image.image_ref, desc=image.desc))
 
     def __init__(self, *args: Any, **kwargs: Any):
         super(CephadmOrchestrator, self).__init__(*args, **kwargs)
index 2399cdb6dc926ec5b146f5a5bb25f32a7107d0f5..313741c90cb0d424c4f14dc03e0323bcef49fbed 100644 (file)
@@ -1,19 +1,57 @@
 # Default container images -----------------------------------------------------
-DEFAULT_PROMETHEUS_IMAGE = 'quay.io/prometheus/prometheus:v2.51.0'
-DEFAULT_NODE_EXPORTER_IMAGE = 'quay.io/prometheus/node-exporter:v1.7.0'
-DEFAULT_NVMEOF_IMAGE = 'quay.io/ceph/nvmeof:1.3.3'
-DEFAULT_LOKI_IMAGE = 'quay.io/ceph/loki:3.0.0'
-DEFAULT_PROMTAIL_IMAGE = 'quay.io/ceph/promtail:3.0.0'
-DEFAULT_ALERTMANAGER_IMAGE = 'quay.io/prometheus/alertmanager:v0.27.0'
-DEFAULT_GRAFANA_IMAGE = 'quay.io/ceph/grafana:10.4.8'
-DEFAULT_HAPROXY_IMAGE = 'quay.io/ceph/haproxy:2.3'
-DEFAULT_KEEPALIVED_IMAGE = 'quay.io/ceph/keepalived:2.2.4'
-DEFAULT_SNMP_GATEWAY_IMAGE = 'quay.io/ceph/snmp-notifier:v1.2.1'
-DEFAULT_ELASTICSEARCH_IMAGE = 'quay.io/omrizeneva/elasticsearch:6.8.23'
-DEFAULT_JAEGER_COLLECTOR_IMAGE = 'quay.io/jaegertracing/jaeger-collector:1.29'
-DEFAULT_JAEGER_AGENT_IMAGE = 'quay.io/jaegertracing/jaeger-agent:1.29'
-DEFAULT_NGINX_IMAGE = 'quay.io/ceph/nginx:sclorg-nginx-126'
-DEFAULT_OAUTH2_PROXY_IMAGE = 'quay.io/oauth2-proxy/oauth2-proxy:v7.6.0'
-DEFAULT_JAEGER_QUERY_IMAGE = 'quay.io/jaegertracing/jaeger-query:1.29'
-DEFAULT_SAMBA_IMAGE = 'quay.io/samba.org/samba-server:devbuilds-centos-amd64'
-DEFAULT_SAMBA_METRICS_IMAGE = 'quay.io/samba.org/samba-metrics:latest'
+
+from typing import NamedTuple
+from enum import Enum
+
+
+class ContainerImage(NamedTuple):
+    image_ref: str  # reference to default container image
+    key: str  # image key
+    desc: str  # description of image
+
+    def __repr__(self) -> str:
+        return self.image_ref
+
+
+def _create_image(image_ref: str, key: str) -> ContainerImage:
+    _img_prefix = 'container_image_'
+    description = key.replace('_', ' ').capitalize()
+    return ContainerImage(
+        image_ref,
+        f'{_img_prefix}{key}',
+        f'{description} container image'
+    )
+
+
+class DefaultImages(Enum):
+    PROMETHEUS = _create_image('quay.io/prometheus/prometheus:v2.51.0', 'prometheus')
+    LOKI = _create_image('docker.io/grafana/loki:3.0.0', 'loki')
+    PROMTAIL = _create_image('docker.io/grafana/promtail:3.0.0', 'promtail')
+    NODE_EXPORTER = _create_image('quay.io/prometheus/node-exporter:v1.7.0', 'node_exporter')
+    ALERTMANAGER = _create_image('quay.io/prometheus/alertmanager:v0.27.0', 'alertmanager')
+    GRAFANA = _create_image('quay.io/ceph/grafana:10.4.8', 'grafana')
+    HAPROXY = _create_image('quay.io/ceph/haproxy:2.3', 'haproxy')
+    KEEPALIVED = _create_image('quay.io/ceph/keepalived:2.2.4', 'keepalived')
+    NVMEOF = _create_image('quay.io/ceph/nvmeof:1.2.17', 'nvmeof')
+    SNMP_GATEWAY = _create_image('docker.io/maxwo/snmp-notifier:v1.2.1', 'snmp_gateway')
+    ELASTICSEARCH = _create_image('quay.io/omrizeneva/elasticsearch:6.8.23', 'elasticsearch')
+    JAEGER_COLLECTOR = _create_image('quay.io/jaegertracing/jaeger-collector:1.29',
+                                     'jaeger_collector')
+    JAEGER_AGENT = _create_image('quay.io/jaegertracing/jaeger-agent:1.29', 'jaeger_agent')
+    JAEGER_QUERY = _create_image('quay.io/jaegertracing/jaeger-query:1.29', 'jaeger_query')
+    SAMBA = _create_image('quay.io/samba.org/samba-server:devbuilds-centos-amd64', 'samba')
+    SAMBA_METRICS = _create_image('quay.io/samba.org/samba-metrics:latest', 'samba_metrics')
+    NGINX = _create_image('quay.io/ceph/nginx:sclorg-nginx-126', 'nginx')
+    OAUTH2_PROXY = _create_image('quay.io/oauth2-proxy/oauth2-proxy:v7.6.0', 'oauth2_proxy')
+
+    @property
+    def image_ref(self) -> str:
+        return self.value.image_ref
+
+    @property
+    def key(self) -> str:
+        return self.value.key
+
+    @property
+    def desc(self) -> str:
+        return self.value.desc