diff --git a/lib/charms/vault_k8s/v0/vault_kv.py b/lib/charms/vault_k8s/v0/vault_kv.py index 7bfab139..3a9c2ad9 100644 --- a/lib/charms/vault_k8s/v0/vault_kv.py +++ b/lib/charms/vault_k8s/v0/vault_kv.py @@ -54,8 +54,9 @@ def _on_install(self, event: InstallEvent): def _on_connected(self, event: vault_kv.VaultKvConnectedEvent): relation = self.model.get_relation(event.relation_name, event.relation_id) - egress_subnet = str(self.model.get_binding(relation).network.interfaces[0].subnet) - self.interface.request_credentials(relation, egress_subnet, self.get_nonce()) + egress_subnets = [str(subnet) for subnet in self.model.get_binding(relation).network.egress_subnets][0].subnet] + egress_subnets.append(str(self.model.get_binding(relation).network.interfaces[0].subnet)) + self.interface.request_credentials(relation, egress_subnets, self.get_nonce()) def _on_ready(self, event: vault_kv.VaultKvReadyEvent): relation = self.model.get_relation(event.relation_name, event.relation_id) @@ -94,9 +95,10 @@ def _on_update_status(self, event): # Update status might not be the best place binding = self.model.get_binding("vault-kv") if binding is not None: - egress_subnet = str(binding.network.interfaces[0].subnet) + egress_subnets = [str(subnet) for subnet in self.model.get_binding(relation).network.egress_subnets][0].subnet] + egress_subnets.append(str(self.model.get_binding(relation).network.interfaces[0].subnet)) relation = self.model.get_relation(relation_name="vault-kv") - self.interface.request_credentials(relation, egress_subnet, self.get_nonce()) + self.interface.request_credentials(relation, egress_subnets, self.get_nonce()) def get_nonce(self): secret = self.model.get_secret(label=NONCE_SECRET_LABEL) @@ -133,7 +135,7 @@ def get_nonce(self): # Increment this PATCH version before using `charmcraft publish-lib` or reset # to 0 if you are raising the major API version -LIBPATCH = 9 +LIBPATCH = 10 PYDEPS = ["pydantic", "pytest-interface-tester"] @@ -164,7 +166,7 @@ class VaultKvProviderSchema(BaseModel): ca_certificate: str = Field( description="The CA certificate to use when validating the Vault server's certificate." ) - egress_subnet: str = Field(description="The CIDR allowed by the role.") + egress_subnet: str = Field(description="The CIDRs allowed by the role separated by commas.") credentials: Json[Mapping[str, str]] = Field( description=( "Mapping of unit name and credentials for that unit." @@ -184,7 +186,9 @@ class AppVaultKvRequirerSchema(BaseModel): class UnitVaultKvRequirerSchema(BaseModel): """Unit schema of the requirer side of the vault-kv interface.""" - egress_subnet: str = Field(description="Egress subnet to use, in CIDR notation.") + egress_subnet: str = Field( + description="Egress subnets to use separated by commas, in CIDR notation." + ) nonce: str = Field( description="Uniquely identifying value for this unit. `secrets.token_hex(16)` is recommended." ) @@ -211,10 +215,21 @@ class KVRequest: app_name: str unit_name: str mount_suffix: str - egress_subnet: str + egress_subnets: List[str] nonce: str +def get_egress_subnets_list_from_relation_data(relation_databag: Mapping[str, str]) -> List[str]: + """Return the egress_subnet as a list. + + This function converts the string with values separated by commas to a list. + + Args: + relation_databag: the relation databag of the unit or the app. + """ + return [subnet.strip() for subnet in relation_databag.get("egress_subnet", "").split(",")] + + def is_requirer_data_valid(app_data: Mapping[str, str], unit_data: Mapping[str, str]) -> bool: """Return whether the requirer data is valid.""" try: @@ -238,6 +253,12 @@ def is_provider_data_valid(data: Mapping[str, str]) -> bool: return False +class VaultKvGoneAwayEvent(ops.EventBase): + """VaultKvGoneAwayEvent Event.""" + + pass + + class NewVaultKvClientAttachedEvent(ops.EventBase): """New vault kv client attached event.""" @@ -248,7 +269,7 @@ def __init__( app_name: str, unit_name: str, mount_suffix: str, - egress_subnet: str, + egress_subnets: List[str], nonce: str, ): super().__init__(handle) @@ -256,7 +277,7 @@ def __init__( self.app_name = app_name self.unit_name = unit_name self.mount_suffix = mount_suffix - self.egress_subnet = egress_subnet + self.egress_subnets = egress_subnets self.nonce = nonce def snapshot(self) -> dict: @@ -266,7 +287,7 @@ def snapshot(self) -> dict: "app_name": self.app_name, "unit_name": self.unit_name, "mount_suffix": self.mount_suffix, - "egress_subnet": self.egress_subnet, + "egress_subnets": self.egress_subnets, "nonce": self.nonce, } @@ -277,7 +298,7 @@ def restore(self, snapshot: Dict[str, Any]): self.app_name = snapshot["app_name"] self.unit_name = snapshot["unit_name"] self.mount_suffix = snapshot["mount_suffix"] - self.egress_subnet = snapshot["egress_subnet"] + self.egress_subnets = snapshot["egress_subnets"] self.nonce = snapshot["nonce"] @@ -285,6 +306,7 @@ class VaultKvProviderEvents(ops.ObjectEvents): """List of events that the Vault Kv provider charm can leverage.""" new_vault_kv_client_attached = ops.EventSource(NewVaultKvClientAttachedEvent) + gone_away = ops.EventSource(VaultKvGoneAwayEvent) class VaultKvProvides(ops.Object): @@ -304,6 +326,10 @@ def __init__( self.charm.on[relation_name].relation_changed, self._on_relation_changed, ) + self.framework.observe( + self.charm.on[relation_name].relation_broken, + self._on_vault_kv_relation_broken, + ) def _on_relation_changed(self, event: ops.RelationChangedEvent): """Handle client changed relation. @@ -324,10 +350,16 @@ def _on_relation_changed(self, event: ops.RelationChangedEvent): app_name=event.app.name, unit_name=unit.name, mount_suffix=event.relation.data[event.app]["mount_suffix"], - egress_subnet=event.relation.data[unit]["egress_subnet"], + egress_subnets=get_egress_subnets_list_from_relation_data( + event.relation.data[unit] + ), nonce=event.relation.data[unit]["nonce"], ) + def _on_vault_kv_relation_broken(self, event: ops.RelationBrokenEvent): + """Handle relation broken.""" + self.on.gone_away.emit() + def set_vault_url(self, relation: ops.Relation, vault_url: str): """Set the vault_url on the relation.""" if not self.charm.unit.is_leader(): @@ -354,11 +386,11 @@ def set_mount(self, relation: ops.Relation, mount: str): relation.data[self.charm.app]["mount"] = mount - def set_egress_subnet(self, relation: ops.Relation, egress_subnet: str): - """Set the egress_subnet on the relation.""" + def set_egress_subnets(self, relation: ops.Relation, egress_subnets: List[str]): + """Set the egress_subnets on the relation.""" if not self.charm.unit.is_leader(): return - relation.data[self.charm.app]["egress_subnet"] = egress_subnet + relation.data[self.charm.app]["egress_subnet"] = ",".join(egress_subnets) def set_unit_credentials( self, @@ -439,7 +471,7 @@ def get_kv_requests(self, relation_id: Optional[int] = None) -> List[KVRequest]: app_name=relation.app.name, unit_name=unit.name, mount_suffix=app_data["mount_suffix"], - egress_subnet=unit_data["egress_subnet"], + egress_subnets=get_egress_subnets_list_from_relation_data(unit_data), nonce=unit_data["nonce"], ) ) @@ -508,12 +540,6 @@ def restore(self, snapshot: Dict[str, Any]): self.relation_name = snapshot["relation_name"] -class VaultKvGoneAwayEvent(ops.EventBase): - """VaultKvGoneAwayEvent Event.""" - - pass - - class VaultKvRequireEvents(ops.ObjectEvents): """List of events that the Vault Kv requirer charm can leverage.""" @@ -558,9 +584,9 @@ def _set_unit_nonce(self, relation: ops.Relation, nonce: str): """Set the nonce on the relation.""" relation.data[self.charm.unit]["nonce"] = nonce - def _set_unit_egress_subnet(self, relation: ops.Relation, egress_subnet: str): - """Set the egress_subnet on the relation.""" - relation.data[self.charm.unit]["egress_subnet"] = egress_subnet + def _set_unit_egress_subnets(self, relation: ops.Relation, egress_subnets: List[str]): + """Set the egress_subnets on the relation.""" + relation.data[self.charm.unit]["egress_subnet"] = ",".join(egress_subnets) def _handle_relation(self, event: ops.EventBase): """Run when a new unit joins the relation or when the address of the unit changes. @@ -597,16 +623,20 @@ def _on_vault_kv_relation_broken(self, event: ops.RelationBrokenEvent): """Handle relation broken.""" self.on.gone_away.emit() - def request_credentials(self, relation: ops.Relation, egress_subnet: str, nonce: str) -> None: + def request_credentials( + self, relation: ops.Relation, egress_subnet: Union[List[str], str], nonce: str + ) -> None: """Request credentials from the vault-kv relation. Generated secret ids are tied to the unit egress_subnet, so if the egress_subnet changes a new secret id must be generated. - A change in egress_subnet can happen when the pod is rescheduled to a different + A change in egress_subnets can happen when the pod is rescheduled to a different node by the underlying substrate without a change from Juju. """ - self._set_unit_egress_subnet(relation, egress_subnet) + if isinstance(egress_subnet, str): + egress_subnet = [egress_subnet] + self._set_unit_egress_subnets(relation, egress_subnet) self._set_unit_nonce(relation, nonce) def get_vault_url(self, relation: ops.Relation) -> Optional[str]: diff --git a/src/charm.py b/src/charm.py index 256bb864..ccf936de 100755 --- a/src/charm.py +++ b/src/charm.py @@ -462,7 +462,7 @@ def _on_new_vault_kv_client_attached(self, event: NewVaultKvClientAttachedEvent) app_name=event.app_name, unit_name=event.unit_name, mount_suffix=event.mount_suffix, - egress_subnet=event.egress_subnet, + egress_subnets=event.egress_subnets, nonce=event.nonce, ) @@ -607,7 +607,7 @@ def _sync_vault_kv(self) -> None: app_name=kv_request.app_name, unit_name=kv_request.unit_name, mount_suffix=kv_request.mount_suffix, - egress_subnet=kv_request.egress_subnet, + egress_subnets=kv_request.egress_subnets, nonce=kv_request.nonce, ) @@ -617,7 +617,7 @@ def _generate_kv_for_requirer( app_name: str, unit_name: str, mount_suffix: str, - egress_subnet: str, + egress_subnets: List[str], nonce: str, ): if not self.unit.is_leader(): @@ -633,8 +633,8 @@ def _generate_kv_for_requirer( return mount = f"charm-{app_name}-{mount_suffix}" vault.enable_secrets_engine(SecretsBackend.KV_V2, mount) - self._ensure_unit_credentials(vault, relation, unit_name, mount, nonce, egress_subnet) - self._set_kv_relation_data(relation, mount, ca_certificate, egress_subnet) + self._ensure_unit_credentials(vault, relation, unit_name, mount, nonce, egress_subnets) + self._set_kv_relation_data(relation, mount, ca_certificate, egress_subnets) self._remove_stale_nonce(relation=relation, nonce=nonce) def _get_pki_ca_certificate(self) -> Optional[str]: @@ -934,7 +934,7 @@ def _set_kv_relation_data( relation: Relation, mount: str, ca_certificate: str, - egress_subnet: str, + egress_subnets: List[str], ) -> None: """Set relation data for vault-kv. @@ -942,12 +942,12 @@ def _set_kv_relation_data( relation: Relation mount: mount name ca_certificate: CA certificate - egress_subnet: egress subnet + egress_subnets: egress subnet """ self.vault_kv.set_mount(relation, mount) vault_url = self._get_relation_api_address(relation) self.vault_kv.set_ca_certificate(relation, ca_certificate) - self.vault_kv.set_egress_subnet(relation, egress_subnet) + self.vault_kv.set_egress_subnets(relation, egress_subnets) if vault_url is not None: self.vault_kv.set_vault_url(relation, vault_url) @@ -958,7 +958,7 @@ def _ensure_unit_credentials( unit_name: str, mount: str, nonce: str, - egress_subnet: str, + egress_subnets: List[str], ): """Ensure a unit has credentials to access the vault-kv mount.""" policy_name = role_name = mount + "-" + unit_name.replace("/", "-") @@ -966,7 +966,7 @@ def _ensure_unit_credentials( role_id = vault.configure_approle( role_name, policies=[policy_name], - cidrs=[egress_subnet], + cidrs=egress_subnets, token_ttl="1h", token_max_ttl="1h", ) @@ -975,7 +975,7 @@ def _ensure_unit_credentials( relation, role_id, role_name, - egress_subnet, + egress_subnets, ) self.vault_kv.set_unit_credentials(relation, nonce, secret) @@ -985,7 +985,7 @@ def _create_or_update_kv_secret( relation: Relation, role_id: str, role_name: str, - egress_subnet: str, + egress_subnets: List[str], ) -> Secret: """Create or update a KV secret for a unit. @@ -996,11 +996,11 @@ def _create_or_update_kv_secret( secret_id = self._get_vault_kv_secret_in_peer_relation(label) if secret_id is None: return self._create_kv_secret( - vault, relation, role_id, role_name, egress_subnet, label + vault, relation, role_id, role_name, egress_subnets, label ) else: return self._update_kv_secret( - vault, relation, role_name, egress_subnet, label, secret_id + vault, relation, role_name, egress_subnets, label, secret_id ) def _create_kv_secret( @@ -1009,11 +1009,11 @@ def _create_kv_secret( relation: Relation, role_id: str, role_name: str, - egress_subnet: str, + egress_subnets: List[str], label: str, ) -> Secret: """Create a vault kv secret, store its id in the peer relation and return it.""" - role_secret_id = vault.generate_role_secret_id(role_name, [egress_subnet]) + role_secret_id = vault.generate_role_secret_id(role_name, egress_subnets) secret = self.app.add_secret( {"role-id": role_id, "role-secret-id": role_secret_id}, label=label, @@ -1029,7 +1029,7 @@ def _update_kv_secret( vault: Vault, relation: Relation, role_name: str, - egress_subnet: str, + egress_subnets: List[str], label: str, secret_id: str, ) -> Secret: @@ -1039,9 +1039,9 @@ def _update_kv_secret( credentials = secret.get_content(refresh=True) role_secret_id_data = vault.read_role_secret(role_name, credentials["role-secret-id"]) # if unit subnet is already in cidr_list, skip - if egress_subnet in role_secret_id_data["cidr_list"]: + if sorted(egress_subnets) == sorted(role_secret_id_data["cidr_list"]): return secret - credentials["role-secret-id"] = vault.generate_role_secret_id(role_name, [egress_subnet]) + credentials["role-secret-id"] = vault.generate_role_secret_id(role_name, egress_subnets) secret.set_content(credentials) return secret diff --git a/tests/integration/vault_kv_requirer_operator/src/charm.py b/tests/integration/vault_kv_requirer_operator/src/charm.py index 4d770ea6..23b89d60 100755 --- a/tests/integration/vault_kv_requirer_operator/src/charm.py +++ b/tests/integration/vault_kv_requirer_operator/src/charm.py @@ -60,8 +60,9 @@ def _on_kv_connected(self, event: VaultKvConnectedEvent): if not binding: logger.error("Binding not found") return - egress_subnet = str(binding.network.interfaces[0].subnet) - self.vault_kv.request_credentials(relation, egress_subnet, self.get_nonce()) + egress_subnets = [str(subnet) for subnet in binding.network.egress_subnets] + egress_subnets.append(str(binding.network.interfaces[0].subnet)) + self.vault_kv.request_credentials(relation, egress_subnets, self.get_nonce()) def _on_kv_ready(self, event: VaultKvReadyEvent): """Store the Vault KV credentials in a secret.""" diff --git a/tests/unit/lib/charms/vault_k8s/v0/test_vault_kv.py b/tests/unit/lib/charms/vault_k8s/v0/test_vault_kv.py index b0b34d74..5ec9de4d 100644 --- a/tests/unit/lib/charms/vault_k8s/v0/test_vault_kv.py +++ b/tests/unit/lib/charms/vault_k8s/v0/test_vault_kv.py @@ -15,6 +15,7 @@ VaultKvProvides, VaultKvReadyEvent, VaultKvRequires, + get_egress_subnets_list_from_relation_data, ) from ops import testing from ops.charm import CharmBase @@ -213,12 +214,12 @@ def test_given_1_outstanding_request_when_get_outstanding_kv_requests_then_reque ): suffix = "dummy" nonce = "abcd" - egress_subnet = "10.0.0.1/32" + egress_subnets = ["10.0.0.1/32"] remote_app, remote_unit, _, rel_id = self.setup_relation() self.harness.update_relation_data( rel_id, remote_unit, - key_values={"nonce": nonce, "egress_subnet": egress_subnet}, + key_values={"nonce": nonce, "egress_subnet": ",".join(egress_subnets)}, ) self.harness.update_relation_data( relation_id=rel_id, @@ -234,7 +235,7 @@ def test_given_1_outstanding_request_when_get_outstanding_kv_requests_then_reque app_name=remote_app, unit_name=remote_unit, mount_suffix=suffix, - egress_subnet=egress_subnet, + egress_subnets=egress_subnets, nonce=nonce, ) @@ -244,7 +245,7 @@ def test_given_1_outstanding_and_1_satisfied_request_when_get_outstanding_kv_req suffix = "dummy" nonce_1 = "abcd" nonce_2 = "efgh" - egress_subnet = "10.0.0.1/32" + egress_subnets = ["10.0.0.1/32"] remote_app, remote_unit_1, _, rel_id = self.setup_relation() remote_unit_2 = remote_app + "/1" self.harness.add_relation_unit( @@ -254,12 +255,12 @@ def test_given_1_outstanding_and_1_satisfied_request_when_get_outstanding_kv_req self.harness.update_relation_data( rel_id, remote_unit_1, - key_values={"nonce": nonce_1, "egress_subnet": egress_subnet}, + key_values={"nonce": nonce_1, "egress_subnet": ",".join(egress_subnets)}, ) self.harness.update_relation_data( rel_id, remote_unit_2, - key_values={"nonce": nonce_2, "egress_subnet": egress_subnet}, + key_values={"nonce": nonce_2, "egress_subnet": ",".join(egress_subnets)}, ) self.harness.update_relation_data( relation_id=rel_id, @@ -280,7 +281,7 @@ def test_given_1_outstanding_and_1_satisfied_request_when_get_outstanding_kv_req app_name=remote_app, unit_name=remote_unit_2, mount_suffix=suffix, - egress_subnet=egress_subnet, + egress_subnets=egress_subnets, nonce=nonce_2, ) @@ -290,8 +291,8 @@ def test_given_2_vault_kv_relations_when_get_outstanding_kv_requests_then_outsta suffix = "dummy" nonce_1 = "abcd" nonce_2 = "efgh" - egress_subnet_1 = "10.0.0.1/32" - egress_subnet_2 = "10.0.0.2/32" + egress_subnets_1 = ["10.0.0.1/32", "10.0.1.1/32"] + egress_subnets_2 = ["10.0.0.2/32"] remote_app_1, remote_unit_1, _, rel_id_1 = self.setup_relation() remote_app_2, remote_unit_2, _, rel_id_2 = self.setup_relation( remote_app="vault-kv-requires-b" @@ -299,12 +300,12 @@ def test_given_2_vault_kv_relations_when_get_outstanding_kv_requests_then_outsta self.harness.update_relation_data( rel_id_1, remote_unit_1, - key_values={"nonce": nonce_1, "egress_subnet": egress_subnet_1}, + key_values={"nonce": nonce_1, "egress_subnet": ",".join(egress_subnets_1)}, ) self.harness.update_relation_data( rel_id_2, remote_unit_2, - key_values={"nonce": nonce_2, "egress_subnet": egress_subnet_2}, + key_values={"nonce": nonce_2, "egress_subnet": ",".join(egress_subnets_2)}, ) self.harness.update_relation_data( relation_id=rel_id_1, @@ -330,7 +331,7 @@ def test_given_2_vault_kv_relations_when_get_outstanding_kv_requests_then_outsta app_name=remote_app_2, unit_name=remote_unit_2, mount_suffix=suffix + "b", - egress_subnet=egress_subnet_2, + egress_subnets=egress_subnets_2, nonce=nonce_2, ) @@ -368,7 +369,7 @@ def test_given_2_requests_when_get_kv_requests_then_requests_are_returned(self): suffix = "dummy" nonce1 = "abcd" nonce2 = "efgh" - egress_subnet = "10.0.0.1/32" + egress_subnets = ["10.0.0.1/32"] remote_app, remote_unit_1, _, rel_id = self.setup_relation() remote_unit_2 = remote_app + "/1" self.harness.add_relation_unit( @@ -378,12 +379,12 @@ def test_given_2_requests_when_get_kv_requests_then_requests_are_returned(self): self.harness.update_relation_data( rel_id, remote_unit_1, - key_values={"nonce": nonce1, "egress_subnet": egress_subnet}, + key_values={"nonce": nonce1, "egress_subnet": ",".join(egress_subnets)}, ) self.harness.update_relation_data( rel_id, remote_unit_2, - key_values={"nonce": nonce2, "egress_subnet": egress_subnet}, + key_values={"nonce": nonce2, "egress_subnet": ",".join(egress_subnets)}, ) self.harness.update_relation_data( relation_id=rel_id, @@ -399,7 +400,7 @@ def test_given_2_requests_when_get_kv_requests_then_requests_are_returned(self): app_name=remote_app, unit_name=remote_unit_1, mount_suffix=suffix, - egress_subnet=egress_subnet, + egress_subnets=egress_subnets, nonce=nonce1, ) expected_kv_request_2 = KVRequest( @@ -407,7 +408,7 @@ def test_given_2_requests_when_get_kv_requests_then_requests_are_returned(self): app_name=remote_app, unit_name=remote_unit_2, mount_suffix=suffix, - egress_subnet=egress_subnet, + egress_subnets=egress_subnets, nonce=nonce2, ) assert expected_kv_request_1 in kv_requests @@ -504,3 +505,14 @@ def test_given_relation_changed_when_data_missing_then_ready_event_never_fired( ): self.setup_relation() _on_ready.assert_not_called() + + def test_given_egress_subnets_in_relation_databag_when_get_egress_subnets_list_from_relation_data_then_list_is_returned( # noqa: E501 + self, + ): + relation_datbage_dict = { + "nonce": "abcd", + "egress_subnet": "10.0.0.1/32, 10.0.1.1/32,10.0.2.1/32", + } + assert sorted(get_egress_subnets_list_from_relation_data(relation_datbage_dict)) == sorted( + ["10.0.0.1/32", "10.0.1.1/32", "10.0.2.1/32"] + ) diff --git a/tests/unit/test_charm.py b/tests/unit/test_charm.py index 702fbdf0..00e758b4 100644 --- a/tests/unit/test_charm.py +++ b/tests/unit/test_charm.py @@ -200,13 +200,13 @@ def setup_vault_kv_relation(self) -> tuple: self.harness.set_leader() rel_id = self.harness.add_relation(relation_name, app_name) unit_name = app_name + "/0" - egress_subnet = "10.20.20.20/32" + egress_subnets = ["10.20.20.20/32"] self.harness.add_relation_unit(rel_id, unit_name) self.harness.update_relation_data( - rel_id, unit_name, {"egress_subnet": egress_subnet, "nonce": "0"} + rel_id, unit_name, {"egress_subnet": ",".join(egress_subnets), "nonce": "0"} ) - return (rel_id, egress_subnet) + return (rel_id, egress_subnets) # Test install @patch("ops.model.Container.remove_path") @@ -1396,7 +1396,7 @@ def test_given_prerequisites_are_met_when_new_vault_kv_client_attached_then_appr event.app_name = VAULT_KV_REQUIRER_APPLICATION_NAME event.unit_name = f"{VAULT_KV_REQUIRER_APPLICATION_NAME}/0" event.mount_suffix = "suffix" - event.egress_subnet = "2.2.2.0/24" + event.egress_subnets = ["2.2.2.0/24"] event.nonce = "123123" self.harness.charm._on_new_vault_kv_client_attached(event) self.mock_vault.enable_secrets_engine.assert_called_once_with( @@ -1432,7 +1432,7 @@ def test_given_prerequisites_are_met_when_new_vault_kv_client_attached_then_kv_r event.app_name = VAULT_KV_REQUIRER_APPLICATION_NAME event.unit_name = f"{VAULT_KV_REQUIRER_APPLICATION_NAME}/0" event.mount_suffix = "suffix" - event.egress_subnet = "2.2.2.0/24" + event.egress_subnets = ["2.2.2.0/24"] event.nonce = "123123" self.harness.charm._on_new_vault_kv_client_attached(event) set_vault_url.assert_called() @@ -1457,8 +1457,8 @@ def test_given_prerequisites_are_met_when_related_kv_client_unit_egress_is_updat role_id="root token content", secret_id="whatever secret id", ) - rel_id, egress_subnet = self.setup_vault_kv_relation() - self.mock_vault.read_role_secret.return_value = {"cidr_list": [egress_subnet]} + rel_id, egress_subnets = self.setup_vault_kv_relation() + self.mock_vault.read_role_secret.return_value = {"cidr_list": egress_subnets} mount_suffix = "whatever-suffix" self.harness.update_relation_data( @@ -1499,7 +1499,7 @@ def test_given_prerequisites_are_met_when_new_vault_kv_client_attached_then_kv_m event.app_name = VAULT_KV_REQUIRER_APPLICATION_NAME event.unit_name = f"{VAULT_KV_REQUIRER_APPLICATION_NAME}/0" event.mount_suffix = "suffix" - event.egress_subnet = "2.2.2.0/24" + event.egress_subnets = ["2.2.2.0/24"] event.nonce = "123123" self.harness.charm._on_new_vault_kv_client_attached(event) self.mock_vault.enable_secrets_engine.assert_called_with(