ovsdb-subordinate: Provide chassis certificates to principal

Enable the ovsdb-subordinate interface to provide chassis
certificates to principal.

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.

Related-Bug: #1918271
Change-Id: I867817dfa7dd43cdb9035af87cbac3371dff13a5
This commit is contained in:
Frode Nordahl 2021-05-12 10:36:37 +02:00
parent 93e40a6bd5
commit 55e82469e8
4 changed files with 55 additions and 0 deletions

View File

@ -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

View File

@ -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

View File

@ -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',
})

View File

@ -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', {})