From 6c2a4d9c4729f202d8370d51cbc43c36a3750d4a Mon Sep 17 00:00:00 2001 From: Adam King Date: Tue, 16 Apr 2024 12:22:01 -0400 Subject: [PATCH] python-common: handle "anonymous_access: false" in to_json of Grafana spec This option is dropped during the regular ServiceSpec to_json function, as it is not equipped to handle booleans that default to True. In hindsight, we just shouldn't have added a boolean field that defaults to True, but it's a bit late now to change the attribute, so this implements a workaround. NOTE: if OrderedDict[str, Any] is not encapsulated in quotes, a bunch of mgr modules fail to load on python 3.6 with mgr[py] Traceback (most recent call last): File "/usr/share/ceph/mgr/volumes/__init__.py", line 2, in from .module import Module File "/usr/share/ceph/mgr/volumes/module.py", line 7, in import orchestrator File "/usr/share/ceph/mgr/orchestrator/__init__.py", line 3, in from .module import OrchestratorCli File "/usr/share/ceph/mgr/orchestrator/module.py", line 19, in from ceph.deployment.drive_group import DriveGroupSpec, DeviceSelection, OSDMethod File "/lib/python3.6/site-packages/ceph/deployment/drive_group.py", line 5, in from ceph.deployment.service_spec import ( File "/lib/python3.6/site-packages/ceph/deployment/service_spec.py", line 1986, in class GrafanaSpec(MonitoringSpec): File "/lib/python3.6/site-packages/ceph/deployment/service_spec.py", line 2034, in GrafanaSpec def to_json(self) -> OrderedDict[str, Any]: TypeError: 'type' object is not subscriptable Fixes: https://tracker.ceph.com/issues/65511 Signed-off-by: Adam King (cherry picked from commit 0089536567b2ce8d3215339b264a48de06bfac38) Conflicts: src/python-common/ceph/deployment/service_spec.py --- .../ceph/deployment/service_spec.py | 20 ++++++++++++++++++- .../ceph/tests/test_service_spec.py | 8 ++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/python-common/ceph/deployment/service_spec.py b/src/python-common/ceph/deployment/service_spec.py index 6049d02a4be65..d57b8207f35a3 100644 --- a/src/python-common/ceph/deployment/service_spec.py +++ b/src/python-common/ceph/deployment/service_spec.py @@ -1317,7 +1317,7 @@ class GrafanaSpec(MonitoringSpec): networks: Optional[List[str]] = None, port: Optional[int] = None, initial_admin_password: Optional[str] = None, - anonymous_access: Optional[bool] = True, + anonymous_access: bool = True, extra_container_args: Optional[List[str]] = None, extra_entrypoint_args: Optional[List[str]] = None, custom_configs: Optional[List[CustomConfig]] = None, @@ -1339,6 +1339,24 @@ class GrafanaSpec(MonitoringSpec): 'be inaccessible.') raise SpecValidationError(err_msg) + def to_json(self) -> "OrderedDict[str, Any]": + json_dict = super(GrafanaSpec, self).to_json() + if not self.anonymous_access: + # This field was added as a boolean that defaults + # to True, which makes it get dropped when the user + # sets it to False and it is converted to json. This means + # the in memory version of the spec will have the option set + # correctly, but the persistent version we store in the config-key + # store will always drop this option. It's already been backported to + # some release versions, or we'd probably just rename it to + # no_anonymous_access and default it to False. This block is to + # handle this option specially and in the future, we should avoid + # boolean fields that default to True. + if 'spec' not in json_dict: + json_dict['spec'] = {} + json_dict['spec']['anonymous_access'] = False + return json_dict + yaml.add_representer(GrafanaSpec, ServiceSpec.yaml_representer) diff --git a/src/python-common/ceph/tests/test_service_spec.py b/src/python-common/ceph/tests/test_service_spec.py index 714fcf57200f4..a73469bea8056 100644 --- a/src/python-common/ceph/tests/test_service_spec.py +++ b/src/python-common/ceph/tests/test_service_spec.py @@ -383,6 +383,14 @@ spec: privacy_protocol: AES snmp_destination: 192.168.1.42:162 snmp_version: V3 +--- +service_type: grafana +service_name: grafana +placement: + count: 1 +spec: + anonymous_access: false + initial_admin_password: password """.split('---\n')) def test_yaml(y): data = yaml.safe_load(y) -- 2.39.5