Skip to content

Commit

Permalink
! Fix broken UTs
Browse files Browse the repository at this point in the history
+ Add isort
* Run isort

J:DEF-160
  • Loading branch information
JPLachance committed Jan 19, 2024
1 parent c812174 commit 9749d67
Show file tree
Hide file tree
Showing 7 changed files with 120 additions and 13 deletions.
19 changes: 18 additions & 1 deletion poetry.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ vulture = "2.10"
[tool.poetry.group.dev.dependencies]
types-pyyaml = "^6.0.12.12"
types-setuptools = "^69.0.0.20240115"
pytest-mock = "^3.12.0"
isort = "^5.13.2"

[tool.stew.ci]
black = true
Expand All @@ -40,6 +42,7 @@ pylint = { args = ["src/"] }
vulture = { args = ["src/", "tests/"] }
pydocstyle = {args = ["src/", "--ignore=D104,D213,D203,D107,D202"]}
pycodestyle = { args = ["src/", "--max-line-length=120","--ignore=E203,W503,W504"] }
isort = { check-args = ["--check", "."], autofix-args = ["."] }

[tool.stew.ci.custom-runners.pytest]
check-args = ["--cov", "src", "--cov-report", "term", "--cov-report", "html", "--cov-report", "xml", "--junit-xml=reports/test_results.xml"]
Expand Down Expand Up @@ -70,6 +73,10 @@ min_confidence = 61
[tool.black]
line-length = 120

[tool.isort]
profile = "black"
line_length = 120

[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
5 changes: 3 additions & 2 deletions src/kubernetes_operator/iam_mapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@
from copy import deepcopy
from os import environ
from pathlib import Path
from typing import List, Any
from typing import Any, List

import kopf
import yaml
from kubernetes import client, config # type: ignore
from kubernetes.client.models.v1_config_map import V1ConfigMap

from kubernetes import client, config # type: ignore

logger = logging.getLogger("operator")

try:
Expand Down
8 changes: 0 additions & 8 deletions src/mypy.ini

This file was deleted.

1 change: 1 addition & 0 deletions tests/.vulture_whitelist.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
login_mocks
49 changes: 49 additions & 0 deletions tests/kubernetes_operator/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import dataclasses
from unittest.mock import Mock

import pytest


@dataclasses.dataclass(frozen=True, eq=False, order=False)
class LoginMocks:
pykube_in_cluster: Mock = None
pykube_from_file: Mock = None
pykube_from_env: Mock = None
client_in_cluster: Mock = None
client_from_file: Mock = None


@pytest.fixture()
def login_mocks(mocker):
"""
Make all client libraries potentially optional, but do not skip the tests:
skipping the tests is the tests' decision, not this mocking fixture's one.
"""
kwargs = {}
try:
import pykube
except ImportError:
pass
else:
cfg = pykube.KubeConfig(
{
"current-context": "self",
"clusters": [{"name": "self", "cluster": {"server": "localhost"}}],
"contexts": [{"name": "self", "context": {"cluster": "self", "namespace": "default"}}],
}
)
kwargs.update(
pykube_in_cluster=mocker.patch.object(pykube.KubeConfig, "from_service_account", return_value=cfg),
pykube_from_file=mocker.patch.object(pykube.KubeConfig, "from_file", return_value=cfg),
pykube_from_env=mocker.patch.object(pykube.KubeConfig, "from_env", return_value=cfg),
)
try:
import kubernetes
except ImportError:
pass
else:
kwargs.update(
client_in_cluster=mocker.patch.object(kubernetes.config, "load_incluster_config"),
client_from_file=mocker.patch.object(kubernetes.config, "load_kube_config"),
)
return LoginMocks(**kwargs)
44 changes: 42 additions & 2 deletions tests/kubernetes_operator/test_iam_mapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@

import yaml
from pytest import fixture, raises
from kubernetes import client

import src.kubernetes_operator.iam_mapping as iam_mapping
from kubernetes import client

BASE_PATH = "src.kubernetes_operator.iam_mapping"

Expand Down Expand Up @@ -95,6 +94,11 @@
PLURAL = "iamidentitymappings"


@fixture(autouse=True)
def no_config_needed(login_mocks):
pass


@fixture
def api_client():
with patch(f"{BASE_PATH}.API") as client_mock:
Expand Down Expand Up @@ -136,13 +140,17 @@ def run_sync(coroutine):


def test_create_mapping_userarn(mock_apply_identity_mappings, api_client):
import src.kubernetes_operator.iam_mapping as iam_mapping

run_sync(iam_mapping.create_mapping(spec=SPEC_USER_MARK, diff=DIFF_NEW_USER_MARK))

mock_apply_identity_mappings.assert_called_with(CONFIGMAP, [SPEC_USER_JOHNDOE, SPEC_CSEC_ADMIN, SPEC_USER_MARK])
api_client.read_namespaced_config_map.assert_called_with("aws-auth", "kube-system")


def test_create_mapping_rolearn(mock_apply_identity_mappings, api_client):
import src.kubernetes_operator.iam_mapping as iam_mapping

run_sync(iam_mapping.create_mapping(spec=SPEC_CSEC_MAINTENANCE, diff=DIFF_NEW_ROLE_CSEC_MAINTENANCE))

mock_apply_identity_mappings.assert_called_with(
Expand All @@ -152,6 +160,8 @@ def test_create_mapping_rolearn(mock_apply_identity_mappings, api_client):


def test_update_mapping_userarn(mock_apply_identity_mappings, api_client):
import src.kubernetes_operator.iam_mapping as iam_mapping

spec_user_johndoe_updated = {
"groups": ["system:masters", "some-other-group-namespace-admin", "new-group-to-update"],
"userarn": "arn:aws:iam::000000000000:user/johndoe",
Expand All @@ -166,26 +176,34 @@ def test_update_mapping_userarn(mock_apply_identity_mappings, api_client):


def test_delete_mapping_userarn(mock_apply_identity_mappings, api_client):
import src.kubernetes_operator.iam_mapping as iam_mapping

run_sync(iam_mapping.delete_mapping(spec=SPEC_USER_JOHNDOE))

mock_apply_identity_mappings.assert_called_with(CONFIGMAP, [SPEC_CSEC_ADMIN])
api_client.read_namespaced_config_map.assert_called_with("aws-auth", "kube-system")


def test_delete_mapping_rolearn(mock_apply_identity_mappings, api_client):
import src.kubernetes_operator.iam_mapping as iam_mapping

run_sync(iam_mapping.delete_mapping(spec=SPEC_CSEC_ADMIN))

mock_apply_identity_mappings.assert_called_with(CONFIGMAP, [SPEC_USER_JOHNDOE])
api_client.read_namespaced_config_map.assert_called_with("aws-auth", "kube-system")


def test_check_synchronization_no_diff(api_client, custom_objects_api):
import src.kubernetes_operator.iam_mapping as iam_mapping

assert iam_mapping.check_synchronization()
api_client.read_namespaced_config_map.assert_called_with("aws-auth", "kube-system")
custom_objects_api.list_cluster_custom_object.assert_called_with(GROUP, VERSION, PLURAL)


def test_check_synchronization_no_diff_with_ignored_identity(api_client, custom_objects_api):
import src.kubernetes_operator.iam_mapping as iam_mapping

data = {
"mapRoles": yaml.safe_dump([SPEC_CSEC_ADMIN, SPEC_USER_SYSTEM_NODE_TO_IGNORE]),
"mapUsers": yaml.safe_dump([SPEC_USER_JOHNDOE]),
Expand All @@ -204,6 +222,8 @@ def test_check_synchronization_no_diff_with_ignored_identity(api_client, custom_
environ, {"IGNORED_CM_IDENTITIES": f"{SPEC_USER_MARK.get('username')},{SPEC_CSEC_MAINTENANCE.get('username')}"}
)
def test_check_synchronization_no_diff_with_ignored_identity_env(api_client, custom_objects_api):
import src.kubernetes_operator.iam_mapping as iam_mapping

data = {
"mapRoles": yaml.safe_dump([SPEC_CSEC_MAINTENANCE, SPEC_CSEC_ADMIN, SPEC_USER_SYSTEM_NODE_TO_IGNORE]),
"mapUsers": yaml.safe_dump([SPEC_USER_JOHNDOE, SPEC_USER_MARK]),
Expand All @@ -219,6 +239,8 @@ def test_check_synchronization_no_diff_with_ignored_identity_env(api_client, cus


def test_check_synchronization_with_diff(api_client, custom_objects_api):
import src.kubernetes_operator.iam_mapping as iam_mapping

modified_iam_identity_mapping = custom_objects_api.list_cluster_custom_object.return_value
modified_iam_identity_mapping["items"].pop()
custom_objects_api.list_cluster_custom_object.return_value = modified_iam_identity_mapping
Expand All @@ -230,6 +252,8 @@ def test_check_synchronization_with_diff(api_client, custom_objects_api):


def test_full_synchronize(mock_apply_identity_mappings, api_client, custom_objects_api):
import src.kubernetes_operator.iam_mapping as iam_mapping

iam_mapping.full_synchronize()

mock_apply_identity_mappings.assert_called_with(CONFIGMAP, [SPEC_USER_JOHNDOE, SPEC_CSEC_ADMIN])
Expand All @@ -238,6 +262,8 @@ def test_full_synchronize(mock_apply_identity_mappings, api_client, custom_objec


def test_apply_cm_identity_mappings_with_userarn(api_client):
import src.kubernetes_operator.iam_mapping as iam_mapping

run_sync(iam_mapping.apply_cm_identity_mappings(CONFIGMAP, [SPEC_USER_JOHNDOE]))

expected_cm_data = {"mapRoles": yaml.safe_dump([]), "mapUsers": yaml.safe_dump([SPEC_USER_JOHNDOE])}
Expand All @@ -248,6 +274,8 @@ def test_apply_cm_identity_mappings_with_userarn(api_client):


def test_apply_cm_identity_mappings_with_rolearn(api_client):
import src.kubernetes_operator.iam_mapping as iam_mapping

run_sync(iam_mapping.apply_cm_identity_mappings(CONFIGMAP, [SPEC_CSEC_ADMIN]))

expected_cm_data = {"mapRoles": yaml.safe_dump([SPEC_CSEC_ADMIN]), "mapUsers": yaml.safe_dump([])}
Expand All @@ -258,6 +286,8 @@ def test_apply_cm_identity_mappings_with_rolearn(api_client):


def test_apply_cm_identity_mappings_with_unknown_mapping(api_client, caplog):
import src.kubernetes_operator.iam_mapping as iam_mapping

caplog.set_level(logging.WARNING)
some_unknown_spec = {"groups": ["system:masters"], "arn": "arn:aws:iam::000000000000:user/bob", "username": "bob"}

Expand All @@ -275,6 +305,8 @@ def test_apply_cm_identity_mappings_with_unknown_mapping(api_client, caplog):


def test_apply_cm_identity_mappings_with_userarn_and_rolearn_and_unknown_mapping(api_client, caplog):
import src.kubernetes_operator.iam_mapping as iam_mapping

caplog.set_level(logging.WARNING)
some_unknown_spec = {"groups": ["system:masters"], "arn": "arn:aws:iam::000000000000:user/bob", "username": "bob"}

Expand All @@ -291,6 +323,8 @@ def test_apply_cm_identity_mappings_with_userarn_and_rolearn_and_unknown_mapping


def test_apply_cm_identity_mappings_with_no_mapping(api_client):
import src.kubernetes_operator.iam_mapping as iam_mapping

run_sync(iam_mapping.apply_cm_identity_mappings(CONFIGMAP, []))

expected_cm_data = {"mapRoles": yaml.safe_dump([]), "mapUsers": yaml.safe_dump([])}
Expand All @@ -301,20 +335,26 @@ def test_apply_cm_identity_mappings_with_no_mapping(api_client):


def test_get_cm_identity_mappings_with_empty_mapusers_skips():
import src.kubernetes_operator.iam_mapping as iam_mapping

ret = iam_mapping.get_cm_identity_mappings(CONFIGMAP_MISSING_MAPUSERS)

assert len(ret) == 1
assert ret[0] == SPEC_CSEC_ADMIN


def test_get_cm_identity_mappings_with_empty_maproles_skips():
import src.kubernetes_operator.iam_mapping as iam_mapping

ret = iam_mapping.get_cm_identity_mappings(CONFIGMAP_MISSING_MAPROLES)

assert len(ret) == 1
assert ret[0] == SPEC_USER_JOHNDOE


def test_get_cm_identity_mappings_with_empty_configmap_returns_no_identity():
import src.kubernetes_operator.iam_mapping as iam_mapping

ret = iam_mapping.get_cm_identity_mappings(CONFIGMAP_MISSING_DATA)

assert len(ret) == 0

0 comments on commit 9749d67

Please sign in to comment.