From 60d2982d61acf9f806c5f97bf04753f97fb1e442 Mon Sep 17 00:00:00 2001 From: Adam Dyess Date: Mon, 14 Apr 2025 21:41:40 -0500 Subject: [PATCH 1/2] Support sharing the proxy-config via o7s-interface relation Signed-off-by: Adam Dyess --- docs/provides.md | 15 ++++++++++ .../interface_openstack_integration/model.py | 3 +- .../requires.py | 14 +++++++++- provides.py | 28 ++++++++++++++++--- requires.py | 9 ++++++ 5 files changed, 63 insertions(+), 6 deletions(-) diff --git a/docs/provides.md b/docs/provides.md index ee17ac6..620108f 100644 --- a/docs/provides.md +++ b/docs/provides.md @@ -106,3 +106,18 @@ IntegrationRequest.set_block_storage_config(bs_version, trust_device_path, Set the block storage config for this request. +

get_proxy_config

+ +```python +IntegrationRequest.get_proxy_config() -> Dict[str, str] +``` + +Retrieve the proxy_config previously set by the provider side of the charm. + +

set_proxy_config

+ +```python +IntegrationRequest.set_proxy_config() -> Dict[str, str] +``` + +Share the proxy_config for openstack endpoints from the provider side of the relation. diff --git a/ops/ops/interface_openstack_integration/model.py b/ops/ops/interface_openstack_integration/model.py index 4036566..e0c513a 100644 --- a/ops/ops/interface_openstack_integration/model.py +++ b/ops/ops/interface_openstack_integration/model.py @@ -10,7 +10,7 @@ import configparser import contextlib import io -from typing import Optional +from typing import Dict, Optional from pydantic import BaseModel, Json, SecretStr, validator @@ -40,6 +40,7 @@ class Data(BaseModel): lb_method: Json[Optional[str]] project_id: Json[Optional[str]] = None project_domain_id: Json[Optional[str]] = None + proxy_config: Json[Optional[Dict[str, str]]] = None manage_security_groups: Json[Optional[bool]] subnet_id: Json[Optional[str]] trust_device_path: Json[Optional[bool]] diff --git a/ops/ops/interface_openstack_integration/requires.py b/ops/ops/interface_openstack_integration/requires.py index a211574..2d10b08 100644 --- a/ops/ops/interface_openstack_integration/requires.py +++ b/ops/ops/interface_openstack_integration/requires.py @@ -7,7 +7,7 @@ """ import base64 import logging -from typing import Optional +from typing import Dict, Optional from backports.cached_property import cached_property from ops.charm import CharmBase, RelationBrokenEvent @@ -108,3 +108,15 @@ def endpoint_tls_ca(self) -> Optional[bytes]: if data.endpoint_tls_ca: return data.endpoint_tls_ca.encode() return None + + @property + def proxy_config(self) -> Dict[str, str]: + """Return proxy_config from integrator relation.""" + if self.is_ready and (data := self._data): + config = data.proxy_config + else: + config = {} + + if not config or not isinstance(config, dict): + return {} + return {k: (v or "") for k, v in config.items()} diff --git a/provides.py b/provides.py index dd4f9d4..4e64d49 100644 --- a/provides.py +++ b/provides.py @@ -12,6 +12,7 @@ """ from operator import attrgetter +from typing import Dict from charms.reactive import Endpoint from charms.reactive import when @@ -109,7 +110,7 @@ def set_credentials(self, """ Set the credentials for this request. """ - self._unit.relation.to_publish.update({ + self._to_publish.update({ 'auth_url': auth_url, 'region': region, 'username': username, @@ -137,7 +138,7 @@ def set_lbaas_config(self, """ Set the load-balancer-as-a-service config for this request. """ - self._unit.relation.to_publish.update({ + self._to_publish.update({ 'subnet_id': subnet_id, 'floating_network_id': floating_network_id, 'lb_method': lb_method, @@ -154,15 +155,34 @@ def set_block_storage_config(self, """ Set the block storage config for this request. """ - self._unit.relation.to_publish.update({ + self._to_publish.update({ 'bs_version': bs_version, 'trust_device_path': trust_device_path, 'ignore_volume_az': ignore_volume_az, }) + def get_proxy_config(self) -> Dict[str, str]: + """ + Get the proxy config for this request. + + if `proxy_config` is not set, return an empty dict. + """ + data = self._to_publish.get('proxy_config') + if not data or not isinstance(data, dict): + return {} + return {k: (v or "") for k, v in data.items()} + + def set_proxy_config(self, proxy_config: Dict[str, str]): + """ + Set the proxy config for this request. + """ + self._to_publish.update({ + 'proxy_config': proxy_config, + }) + @property def has_credentials(self): """ Whether or not credentials have been set via `set_credentials`. """ - return 'credentials' in self._unit.relation.to_publish + return 'credentials' in self._to_publish diff --git a/requires.py b/requires.py index c08d4e2..9de96aa 100644 --- a/requires.py +++ b/requires.py @@ -22,6 +22,7 @@ charm once handled. """ +from typing import Dict from charms.reactive import Endpoint from charms.reactive import when, when_not @@ -311,3 +312,11 @@ def lb_enabled(self): """ # be careful to ensure a None value is returned as True, for backward compatibility return self._received['lb_enabled'] is not False + + @property + def proxy_config(self) -> Dict[str, str]: + """Return proxy_config from integrator relation.""" + data = self._received.get('proxy_config') + if not data or not isinstance(data, dict): + return {} + return {k: (v or "") for k, v in data.items()} From 045be965a0c47b36a5431745c4f15d76aec79ca4 Mon Sep 17 00:00:00 2001 From: Adam Dyess Date: Wed, 16 Apr 2025 10:35:02 -0500 Subject: [PATCH 2/2] Address review comments --- docs/provides.md | 7 ++++--- docs/requires.md | 10 ++++++++++ ops/ops/interface_openstack_integration/requires.py | 8 ++------ provides.py | 5 +++-- 4 files changed, 19 insertions(+), 11 deletions(-) diff --git a/docs/provides.md b/docs/provides.md index 620108f..7864d40 100644 --- a/docs/provides.md +++ b/docs/provides.md @@ -106,13 +106,14 @@ IntegrationRequest.set_block_storage_config(bs_version, trust_device_path, Set the block storage config for this request. -

get_proxy_config

+

proxy_config

```python -IntegrationRequest.get_proxy_config() -> Dict[str, str] +@property +IntegrationRequest.proxy_config() -> Dict[str, str] ``` -Retrieve the proxy_config previously set by the provider side of the charm. +Retrieve the `proxy_config` currently set by the provider side of the charm.

set_proxy_config

diff --git a/docs/requires.md b/docs/requires.md index 510e292..72c49b6 100644 --- a/docs/requires.md +++ b/docs/requires.md @@ -158,3 +158,13 @@ The username. Optional version number for the APIs or None. + +

proxy_config

+ +```python +@property +OpenStackIntegrationRequires.proxy_config() -> Dict[str, str] +``` + +Optional `proxy_config` used to indicate to the application proxy details +necessary to reach the openstack endpoints. diff --git a/ops/ops/interface_openstack_integration/requires.py b/ops/ops/interface_openstack_integration/requires.py index 2d10b08..5f9a02f 100644 --- a/ops/ops/interface_openstack_integration/requires.py +++ b/ops/ops/interface_openstack_integration/requires.py @@ -112,11 +112,7 @@ def endpoint_tls_ca(self) -> Optional[bytes]: @property def proxy_config(self) -> Dict[str, str]: """Return proxy_config from integrator relation.""" + config = None if self.is_ready and (data := self._data): config = data.proxy_config - else: - config = {} - - if not config or not isinstance(config, dict): - return {} - return {k: (v or "") for k, v in config.items()} + return config or {} diff --git a/provides.py b/provides.py index 4e64d49..c36a781 100644 --- a/provides.py +++ b/provides.py @@ -161,9 +161,10 @@ def set_block_storage_config(self, 'ignore_volume_az': ignore_volume_az, }) - def get_proxy_config(self) -> Dict[str, str]: + @property + def proxy_config(self) -> Dict[str, str]: """ - Get the proxy config for this request. + Get the proxy config answered on this request. if `proxy_config` is not set, return an empty dict. """