From 093b9e205c682a3ee23d31cf09a59bcd22e20255 Mon Sep 17 00:00:00 2001 From: Ivan Chvets Date: Mon, 28 Nov 2022 16:44:29 -0500 Subject: [PATCH] Bug: MLFlow Seldon secrets is incorrectly formatted. https://github.com/canonical/bundle-kubeflow/issues/429 Summary of changes: - Added namespace to endpoint URL encoding. - Added integration testing. --- charms/mlflow-server/src/charm.py | 4 +-- .../tests/integration/test_charm.py | 28 +++++++++++++++++++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/charms/mlflow-server/src/charm.py b/charms/mlflow-server/src/charm.py index 6d9ad385..90fff4bd 100755 --- a/charms/mlflow-server/src/charm.py +++ b/charms/mlflow-server/src/charm.py @@ -352,7 +352,7 @@ def _b64_encode_dict(d): def _minio_credentials_dict(obj_storage): """Returns a dict of minio credentials with the values base64 encoded.""" minio_credentials = { - "AWS_ENDPOINT_URL": f"http://{obj_storage['service']}:{obj_storage['port']}", + "AWS_ENDPOINT_URL": f"http://{obj_storage['service']}.{obj_storage['namespace']}:{obj_storage['port']}", "AWS_ACCESS_KEY_ID": obj_storage["access-key"], "AWS_SECRET_ACCESS_KEY": obj_storage["secret-key"], "USE_SSL": str(obj_storage["secure"]).lower(), @@ -367,7 +367,7 @@ def _seldon_credentials_dict(obj_storage): "RCLONE_CONFIG_S3_PROVIDER": "minio", "RCLONE_CONFIG_S3_ACCESS_KEY_ID": obj_storage["access-key"], "RCLONE_CONFIG_S3_SECRET_ACCESS_KEY": obj_storage["secret-key"], - "RCLONE_CONFIG_S3_ENDPOINT": f"http://{obj_storage['service']}:{obj_storage['port']}", + "RCLONE_CONFIG_S3_ENDPOINT": f"http://{obj_storage['service']}.{obj_storage['namespace']}:{obj_storage['port']}", "RCLONE_CONFIG_S3_ENV_AUTH": "false", } return _b64_encode_dict(credentials) diff --git a/charms/mlflow-server/tests/integration/test_charm.py b/charms/mlflow-server/tests/integration/test_charm.py index 7f90f4f1..ba22ff08 100644 --- a/charms/mlflow-server/tests/integration/test_charm.py +++ b/charms/mlflow-server/tests/integration/test_charm.py @@ -3,6 +3,7 @@ import json import logging +from base64 import b64encode from pathlib import Path from random import choices from string import ascii_lowercase @@ -13,6 +14,7 @@ import yaml from lightkube.core.client import Client from lightkube.models.rbac_v1 import PolicyRule +from lightkube.resources.core_v1 import Secret from lightkube.resources.rbac_authorization_v1 import Role from pytest_lazyfixture import lazy_fixture from pytest_operator.plugin import OpsTest @@ -56,6 +58,32 @@ async def test_successful_deploy(ops_test: OpsTest): assert ops_test.model.applications[CHARM_NAME].units[0].workload_status == "active" +@pytest.mark.abort_on_fail +async def test_relation_and_secrets(ops_test: OpsTest): + """Test information propagation from relation to secrets.""" + # NOTE: This test depends on deployment done in test_build_and_deploy() + test_namespace = ops_test.model_name + lightkube_client = Client(namespace=test_namespace) + + minio_secret = lightkube_client.get( + Secret, name=f"{CHARM_NAME}-minio-secret", namespace=test_namespace + ) + assert minio_secret is not None + + seldon_secret = lightkube_client.get( + Secret, + name=f"{CHARM_NAME}-seldon-init-container-s3-credentials", + namespace=test_namespace + ) + assert seldon_secret is not None + + # check base64 encoding of endpoint URL + test_storage_url = f"http://minio.{test_namespace}:9000" + test_storage_url_b64 = b64encode(test_storage_url.encode("utf-8")).decode("utf-8") + assert minio_secret.data['AWS_ENDPOINT_URL'] == test_storage_url_b64 + assert seldon_secret.data['RCLONE_CONFIG_S3_ENDPOINT'] == test_storage_url_b64 + + async def test_default_bucket_created(ops_test: OpsTest): """Tests whether the default bucket is auto-generated by mlflow.