Skip to content
This repository has been archived by the owner on Mar 4, 2024. It is now read-only.

Provide scope for each cred via the ops.provider #41

Merged
merged 2 commits into from
Oct 27, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 9 additions & 6 deletions ops/ops/interface_kube_control/provides.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from collections import namedtuple

from ops import CharmBase, Relation, Unit
from .model import Creds
from typing import List

AuthRequest = namedtuple("KubeControlAuthRequest", ["unit", "user", "group"])
Expand Down Expand Up @@ -100,7 +101,7 @@ def set_dns_port(self, port) -> None:

def set_has_external_cloud_provider(self, has_xcp) -> None:
"""Send indicator to remote units that an external cloud provider is in use."""
value = str(has_xcp).lower()
value = str(has_xcp).title()
for relation in self.relations:
relation.data[self.unit]["has-xcp"] = value

Expand Down Expand Up @@ -128,11 +129,13 @@ def sign_auth_request(
creds = {}
for relation in self.relations:
creds.update(json.loads(relation.data[self.unit].get("creds", "{}")))
creds[request.user] = {
"client_token": client_token,
"kubelet_token": kubelet_token,
"proxy_token": proxy_token,
}
creds[request.user] = Creds(
client_token=client_token,
kubelet_token=kubelet_token,
proxy_token=proxy_token,
scope=request.unit,
).dict()

value = json.dumps(creds)
for relation in self.relations:
relation.data[self.unit]["creds"] = value
Expand Down
58 changes: 58 additions & 0 deletions ops/tests/unit/test_ops_provides.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Copyright 2022 Canonical Ltd.
# See LICENSE file for licensing details.
import unittest.mock as mock

import pytest
from ops.charm import CharmBase
from ops.interface_kube_control import KubeControlProvides


@pytest.fixture(scope="function")
def kube_control_provider():
mock_charm = mock.MagicMock(auto_spec=CharmBase)
mock_charm.framework.model.unit.name = "test/0"
yield KubeControlProvides(mock_charm, "kube-control")


def test_sign_auth_request(kube_control_provider):
with mock.patch.object(
KubeControlProvides, "relations", new_callable=mock.PropertyMock
) as mock_prop:
mock_relation = mock.MagicMock()
mock_relation.data = {kube_control_provider.unit: {}}
mock_prop.return_value = [mock_relation]
mock_request = mock.MagicMock()
mock_request.user = "system:node:juju-561c45-7"
mock_request.unit = "kubernetes-worker/0"

kube_control_provider.sign_auth_request(
request=mock_request,
client_token="admin::client-token-1",
kubelet_token="kubernetes-worker/0::kubelet-token-1",
proxy_token="kube-proxy::proxy-token-1",
)
assert mock_relation.data[kube_control_provider.unit] == {
"creds": '{"system:node:juju-561c45-7": {"client_token": '
'"admin::client-token-1", "kubelet_token": '
'"kubernetes-worker/0::kubelet-token-1", "proxy_token": '
'"kube-proxy::proxy-token-1", "scope": "kubernetes-worker/0"}}',
}

mock_request.user = "system:node:juju-561c45-8"
mock_request.unit = "kubernetes-worker/1"
kube_control_provider.sign_auth_request(
request=mock_request,
client_token="admin::client-token-2",
kubelet_token="kubernetes-worker/1::kubelet-token-2",
proxy_token="kube-proxy::proxy-token-2",
)
assert mock_relation.data[kube_control_provider.unit] == {
"creds": '{"system:node:juju-561c45-7": {"client_token": '
'"admin::client-token-1", "kubelet_token": '
'"kubernetes-worker/0::kubelet-token-1", "proxy_token": '
'"kube-proxy::proxy-token-1", "scope": "kubernetes-worker/0"},'
' "system:node:juju-561c45-8": {"client_token": '
'"admin::client-token-2", "kubelet_token": '
'"kubernetes-worker/1::kubelet-token-2", "proxy_token": '
'"kube-proxy::proxy-token-2", "scope": "kubernetes-worker/1"}}',
}