Skip to content

Commit

Permalink
Remove field module_name from opta secret (#110)
Browse files Browse the repository at this point in the history
* fix

* fix

* fix

* done
  • Loading branch information
NitinAgg authored Feb 25, 2021
1 parent 3ef860b commit e32760a
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 83 deletions.
6 changes: 6 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
build-binary:
echo $(VERSION) > ./config/version.txt
pipenv run pyinstaller opta.spec

lint:
pipenv run ./scripts/lint.py

test:
pipenv run pytest .
43 changes: 17 additions & 26 deletions opta/commands/secret.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@
from kubernetes.config import load_kube_config

from opta.amplitude import amplitude_client
from opta.core.generator import gen_all
from opta.core.kubernetes import configure_kubectl
from opta.exceptions import UserErrors
from opta.layer import Layer
from opta.module import Module


@click.group()
Expand All @@ -17,28 +18,19 @@ def secret() -> None:
pass


def get_module(module_name: str, env: Optional[str], config: str) -> Module:
layer = Layer.load_from_yaml(config, env)
target_module = layer.get_module(module_name)

if target_module is None:
raise UserErrors(f"Invalid target module {module_name}. Not found in layer")
else:
return target_module


@secret.command()
@click.argument("module_name")
@click.argument("secret")
@click.option("--env", default=None, help="The env to use when loading the config file")
@click.option("--config", default="opta.yml", help="Opta config file", show_default=True)
def view(module_name: str, secret: str, env: Optional[str], config: str) -> None:
def view(secret: str, env: Optional[str], config: str) -> None:
"""View a given secret of a k8s service"""
target_module = get_module(module_name, env, config)
layer = Layer.load_from_yaml(config, env)
amplitude_client.send_event(amplitude_client.VIEW_SECRET_EVENT)
gen_all(layer)
configure_kubectl(layer)
load_kube_config()
v1 = CoreV1Api()
api_response = v1.read_namespaced_secret("secret", target_module.layer_name)
api_response = v1.read_namespaced_secret("secret", layer.name)
if secret not in api_response.data:
raise UserErrors(
f"Secret {secret} was not specified for the app. You sure you set it in your yaml?"
Expand All @@ -48,38 +40,37 @@ def view(module_name: str, secret: str, env: Optional[str], config: str) -> None


@secret.command(name="list")
@click.argument("module_name")
@click.option("--env", default=None, help="The env to use when loading the config file")
@click.option("--config", default="opta.yml", help="Opta config file", show_default=True)
def list_command(module_name: str, env: Optional[str], config: str) -> None:
def list_command(env: Optional[str], config: str) -> None:
"""List the secrets setup for the given k8s service module"""
target_module = get_module(module_name, env, config)
layer = Layer.load_from_yaml(config, env)
amplitude_client.send_event(amplitude_client.LIST_SECRETS_EVENT)

gen_all(layer)
configure_kubectl(layer)
load_kube_config()
v1 = CoreV1Api()
api_response = v1.read_namespaced_secret("secret", target_module.layer_name)
api_response = v1.read_namespaced_secret("secret", layer.name)

for key in api_response.data:
print(key)


@secret.command()
@click.argument("module_name")
@click.argument("secret")
@click.argument("value")
@click.option("--env", default=None, help="The env to use when loading the config file")
@click.option("--config", default="opta.yml", help="Opta config file", show_default=True)
def update(
module_name: str, secret: str, value: str, env: Optional[str], config: str
) -> None:
def update(secret: str, value: str, env: Optional[str], config: str) -> None:
"""Update a given secret of a k8s service with a new value"""
target_module = get_module(module_name, env, config)
layer = Layer.load_from_yaml(config, env)
gen_all(layer)
configure_kubectl(layer)
amplitude_client.send_event(amplitude_client.UPDATE_SECRET_EVENT)
secret_value = base64.b64encode(value.encode("utf-8")).decode("utf-8")
patch = [{"op": "replace", "path": f"/data/{secret}", "value": secret_value}]
load_kube_config()
v1 = CoreV1Api()
v1.patch_namespaced_secret("secret", target_module.layer_name, patch)
v1.patch_namespaced_secret("secret", layer.name, patch)

print("Success")
83 changes: 26 additions & 57 deletions tests/plugins/test_secret_manager.py
Original file line number Diff line number Diff line change
@@ -1,57 +1,24 @@
# type: ignore
import base64
import os

import pytest
from click.testing import CliRunner
from kubernetes.client import CoreV1Api, V1Secret
from pytest_mock import MockFixture, mocker # noqa

from opta.amplitude import AmplitudeClient, amplitude_client
from opta.commands.secret import get_module, list_command, update, view
from opta.module import Module
from opta.commands.secret import list_command, update, view
from opta.layer import Layer


class TestSecretManager:
def test_get_module_no_config(self, mocker: MockFixture): # noqa
mocked_path_exists = mocker.patch("os.path.exists")
mocked_path_exists.return_value = False
with pytest.raises(Exception):
get_module("a", "c", "d")
mocked_path_exists.assert_called_once_with("d")

def test_get_module_all_good(self):

target_module = get_module(
"app",
"dummy-env",
os.path.join(
os.path.dirname(os.path.dirname(__file__)),
"plugins",
"dummy_config1.yaml",
),
)

assert target_module.name == "app"

def test_get_module_no_secret(self):
with pytest.raises(Exception) as excinfo:
get_module(
"app",
"dummy-env",
os.path.join(
os.path.dirname(os.path.dirname(__file__)),
"plugins",
"dummy_config2.yaml",
),
)
assert "Secret not found" in str(excinfo.value)

def test_view(self, mocker: MockFixture): # noqa
mocked_get_module = mocker.patch("opta.commands.secret.get_module")
mocked_module = mocker.Mock(spec=Module)
mocked_module.layer_name = "dummy_layer"
mocked_get_module.return_value = mocked_module
mocker.patch("opta.commands.secret.gen_all")
mocker.patch("opta.commands.secret.configure_kubectl")

mocked_load_layer = mocker.patch("opta.commands.secret.Layer.load_from_yaml")
mocked_layer = mocker.Mock(spec=Layer)
mocked_layer.name = "dummy_layer"
mocked_load_layer.return_value = mocked_layer

mocked_kube_load_config = mocker.patch("opta.commands.secret.load_kube_config")

Expand All @@ -72,26 +39,27 @@ def test_view(self, mocker: MockFixture): # noqa

runner = CliRunner()
result = runner.invoke(
view,
["dummyapp", "dummysecret", "--env", "dummyenv", "--config", "dummyconfig"],
view, ["dummysecret", "--env", "dummyenv", "--config", "dummyconfig"],
)
assert result.exit_code == 0
mocked_kube_load_config.assert_called_once_with()
mocked_client.read_namespaced_secret.assert_called_once_with(
"secret", "dummy_layer"
)
mocked_get_module.assert_called_once_with("dummyapp", "dummyenv", "dummyconfig")
mocked_load_layer.assert_called_once_with("dummyconfig", "dummyenv")
mocked_amplitude_client.send_event.assert_called_once_with(
amplitude_client.VIEW_SECRET_EVENT
)

def test_list_secrets(self, mocker: MockFixture): # noqa
mocked_print = mocker.patch("builtins.print")
mocker.patch("opta.commands.secret.gen_all")
mocker.patch("opta.commands.secret.configure_kubectl")

mocked_get_module = mocker.patch("opta.commands.secret.get_module")
mocked_module = mocker.Mock(spec=Module)
mocked_module.layer_name = "dummy_layer"
mocked_get_module.return_value = mocked_module
mocked_load_layer = mocker.patch("opta.commands.secret.Layer.load_from_yaml")
mocked_layer = mocker.Mock(spec=Layer)
mocked_layer.name = "dummy_layer"
mocked_load_layer.return_value = mocked_layer

mocked_kube_load_config = mocker.patch("opta.commands.secret.load_kube_config")

Expand All @@ -112,24 +80,26 @@ def test_list_secrets(self, mocker: MockFixture): # noqa

runner = CliRunner()
result = runner.invoke(
list_command, ["dummyapp", "--env", "dummyenv", "--config", "dummyconfig"],
list_command, ["--env", "dummyenv", "--config", "dummyconfig"],
)
assert result.exit_code == 0
mocked_kube_load_config.assert_called_once_with()
mocked_client.read_namespaced_secret.assert_called_once_with(
"secret", "dummy_layer"
)
mocked_get_module.assert_called_once_with("dummyapp", "dummyenv", "dummyconfig")
mocked_load_layer.assert_called_once_with("dummyconfig", "dummyenv")
mocked_amplitude_client.send_event.assert_called_once_with(
amplitude_client.LIST_SECRETS_EVENT
)
mocked_print.assert_has_calls([mocker.call("ALGOLIA_WRITE_KEY")])

def test_update(self, mocker: MockFixture): # noqa
mocked_get_module = mocker.patch("opta.commands.secret.get_module")
mocked_module = mocker.Mock(spec=Module)
mocked_module.layer_name = "dummy_layer"
mocked_get_module.return_value = mocked_module
mocker.patch("opta.commands.secret.gen_all")
mocker.patch("opta.commands.secret.configure_kubectl")
mocked_load_layer = mocker.patch("opta.commands.secret.Layer.load_from_yaml")
mocked_layer = mocker.Mock(spec=Layer)
mocked_layer.name = "dummy_layer"
mocked_load_layer.return_value = mocked_layer

mocked_kube_load_config = mocker.patch("opta.commands.secret.load_kube_config")

Expand All @@ -146,7 +116,6 @@ def test_update(self, mocker: MockFixture): # noqa
result = runner.invoke(
update,
[
"dummyapp",
"dummysecret",
"dummysecretvalue",
"--env",
Expand All @@ -164,7 +133,7 @@ def test_update(self, mocker: MockFixture): # noqa
mocked_client.patch_namespaced_secret.assert_called_once_with(
"secret", "dummy_layer", patch
)
mocked_get_module.assert_called_once_with("dummyapp", "dummyenv", "dummyconfig")
mocked_load_layer.assert_called_once_with("dummyconfig", "dummyenv")
mocked_amplitude_client.send_event.assert_called_once_with(
amplitude_client.UPDATE_SECRET_EVENT
)

0 comments on commit e32760a

Please sign in to comment.