diff --git a/src/ovsdb_subordinate/provides.py b/src/ovsdb_subordinate/provides.py index b8d374f..3cf8da7 100644 --- a/src/ovsdb_subordinate/provides.py +++ b/src/ovsdb_subordinate/provides.py @@ -67,6 +67,32 @@ class OVSDBSubordinateProvides(Endpoint): for relation in self.relations: relation.to_publish['ovn-configured'] = ovn_configured + def publish_chassis_certificates(self, ca_cert, certificate, private_key): + """Publish the chassis certificates. + + This is useful for related charms providing payloads that expect direct + communication with the OVN databases. + + While a principal and subordinate charm executes in the same + environment, the payload usually execute under different service + accounts and as such it is impractical and may be less secure to + attempt to provide direct on-disk file access. + + :param ca_cert: CA Certificate data + :type ca_cert: str + :param certificate: Certificate data + :type certificate: str + :param private_key: Private key data + :type private_key: str + :returns: Nothing, method called for its side effect + """ + for relation in self.relations: + relation.to_publish['chassis-certificates'] = { + 'ca_cert': ca_cert, + 'certificate': certificate, + 'private_key': private_key, + } + @property def interface_requests(self): """Retrieve current interface requests diff --git a/src/ovsdb_subordinate/requires.py b/src/ovsdb_subordinate/requires.py index 4245e02..239cee4 100644 --- a/src/ovsdb_subordinate/requires.py +++ b/src/ovsdb_subordinate/requires.py @@ -48,6 +48,18 @@ class OVSDBSubordinateRequires(Endpoint): """ return self.all_joined_units.received.get('ovn-configured', False) + @property + def chassis_certificates(self): + """Retrieve chassis certificates from relation data + + :returns: Certificate data + {'ca_cert': '-----BEGIN ...', + 'certificate': '-----BEGIN ...', + 'private_key': '-----BEGIN ...'} + :rtype: Dict[str,str] + """ + return self.all_joined_units.received.get('chassis-certificates', {}) + def _add_interface_request(self, bridge, ifname, ifdata): """Retrieve interface requests from relation and add/update requests diff --git a/unit_tests/test_ovsdb_subordinate_provides.py b/unit_tests/test_ovsdb_subordinate_provides.py index 8f94409..53f3815 100644 --- a/unit_tests/test_ovsdb_subordinate_provides.py +++ b/unit_tests/test_ovsdb_subordinate_provides.py @@ -142,3 +142,13 @@ class TestOVSDBSubordinateProvides(test_utils.PatchHelper): 'some-relation.interfaces.new_requests') self.clear_flag.assert_called_once_with( 'endpoint.some-relation.changed.create-interfaces') + + def test_publish_chassis_certificates(self): + to_publish = self.patch_topublish() + self.target.publish_chassis_certificates('a', 'b', 'c') + to_publish.__setitem__.assert_called_once_with( + 'chassis-certificates', { + 'ca_cert': 'a', + 'certificate': 'b', + 'private_key': 'c', + }) diff --git a/unit_tests/test_ovsdb_subordinate_requires.py b/unit_tests/test_ovsdb_subordinate_requires.py index 169b48a..de10c09 100644 --- a/unit_tests/test_ovsdb_subordinate_requires.py +++ b/unit_tests/test_ovsdb_subordinate_requires.py @@ -149,3 +149,10 @@ class TestOVSDBSubordinateRequires(test_utils.PatchHelper): 'some-relation.interfaces.created') self.clear_flag.assert_called_once_with( 'endpoint.some-relation.changed.interfaces-created') + + def test_chassis_certificates(self): + self.patch_target('_all_joined_units') + self._all_joined_units.received.get.return_value = {'fake': 'cert'} + self.assertEquals(self.target.chassis_certificates, {'fake': 'cert'}) + self._all_joined_units.received.get.assert_called_once_with( + 'chassis-certificates', {})