Skip to content

Commit

Permalink
replace commands with api call for replace
Browse files Browse the repository at this point in the history
  • Loading branch information
mabulgu committed May 31, 2024
1 parent 4e72b14 commit e189690
Show file tree
Hide file tree
Showing 12 changed files with 87 additions and 69 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ RUN apk add --update \
curl \
&& rm -rf /var/cache/apk/*
RUN adduser -D kfkuser
RUN pip install strimzi-kafka-cli==0.1.0a79
RUN pip install strimzi-kafka-cli==0.1.0a80
USER kfkuser
RUN mkdir /home/kfkuser/.kube
RUN curl https://raw.githubusercontent.com/SystemCraftsman/strimzi-kafka-cli/main/tests/files/yaml/kubeconfig -o /home/kfkuser/.kube/config
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,10 @@ Please see [pyproject.toml](https://github.com/SystemCraftsman/strimzi-kafka-cli
kfk --version
```

If you want to change the `kubectl` and `Strimzi resources` folder, you can simply change their version with the help of some environment variables in order to let Strimzi Kafka CLI download the version you want, or change the PATH of any if you want to use a custom kubectl or Strimzi binary folder. Current versions are recommended, so use these environment variables at your own risk.
You can change where you want to locate the `kubectl`, `Strimzi resources`, or `Strimzi CLI` files/folders. You can use the following environment variables:

**STRIMZI_KAFKA_CLI_BASE_PATH:** Set this if you want to have a custom Strimzi Kafka CLI folder. It is `~/.strimzi-kafka-cli` as default.

**STRIMZI_KAFKA_CLI_STRIMZI_PATH:** Set this if you want to use a custom Strimzi/AMQ Streams.
**STRIMZI_KAFKA_CLI_STRIMZI_PATH:** Set this if you want to use a custom Strimzi/AMQ Streams. We only recommend this when using AMQ Streams instead of Strimzi.

**STRIMZI_KAFKA_CLI_KUBECTL_PATH:** Set this if you want to use a custom kubectl.
17 changes: 8 additions & 9 deletions kfk/commands/clusters.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@
)
from kfk.config import STRIMZI_PATH, STRIMZI_VERSION
from kfk.kubectl_command_builder import Kubectl
from kfk.kubernetes_commons import create_using_yaml, delete_using_yaml
from kfk.kubernetes_commons import (
create_using_yaml,
delete_using_yaml,
replace_using_yaml,
)
from kfk.messages import Messages
from kfk.option_extensions import NotRequiredIf

Expand Down Expand Up @@ -202,14 +206,9 @@ def alter(cluster, replicas, zk_replicas, config, delete_config, namespace):

cluster_yaml = yaml.dump(cluster_dict)
cluster_temp_file = create_temp_file(cluster_yaml)
os.system(
Kubectl()
.apply()
.from_file("{cluster_temp_file_path}")
.namespace(namespace)
.build()
.format(cluster_temp_file_path=cluster_temp_file.name)
)

replace_using_yaml(cluster_temp_file.name, namespace)

cluster_temp_file.close()
else:
os.system(Kubectl().edit().kafkas(cluster).namespace(namespace).build())
Expand Down
12 changes: 4 additions & 8 deletions kfk/commands/connect/clusters.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
create_using_yaml,
delete_object,
delete_using_yaml,
replace_using_yaml,
)
from kfk.messages import Errors, Messages
from kfk.utils import is_valid_url
Expand Down Expand Up @@ -362,14 +363,9 @@ def alter(cluster, replicas, config_file, namespace):

cluster_yaml = yaml.dump(cluster_dict)
cluster_temp_file = create_temp_file(cluster_yaml)
os.system(
Kubectl()
.replace()
.from_file("{cluster_temp_file_path}")
.namespace(namespace)
.build()
.format(cluster_temp_file_path=cluster_temp_file.name)
)

replace_using_yaml(cluster_temp_file.name, namespace)

cluster_temp_file.close()
else:
os.system(Kubectl().edit().kafkaconnects(cluster).namespace(namespace).build())
Expand Down
15 changes: 6 additions & 9 deletions kfk/commands/connect/connectors.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@
from kfk.config import STRIMZI_PATH, STRIMZI_VERSION
from kfk.constants import SpecialTexts
from kfk.kubectl_command_builder import Kubectl
from kfk.kubernetes_commons import create_using_yaml, delete_using_yaml
from kfk.kubernetes_commons import (
create_using_yaml,
delete_using_yaml,
replace_using_yaml,
)

CONNECTOR_SKIPPED_PROPERTIES = (
SpecialTexts.CONNECTOR_NAME,
Expand Down Expand Up @@ -199,14 +203,7 @@ def alter(config_file, cluster, namespace):
connector_yaml = yaml.dump(connector_dict)
connector_temp_file = create_temp_file(connector_yaml)

os.system(
Kubectl()
.replace()
.from_file("{topic_temp_file_path}")
.namespace(namespace)
.build()
.format(topic_temp_file_path=connector_temp_file.name)
)
replace_using_yaml(connector_temp_file.name, namespace)

connector_temp_file.close()

Expand Down
15 changes: 6 additions & 9 deletions kfk/commands/topics.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@
from kfk.config import STRIMZI_PATH, STRIMZI_VERSION
from kfk.constants import KAFKA_PORT
from kfk.kubectl_command_builder import Kubectl
from kfk.kubernetes_commons import create_using_yaml, delete_using_yaml
from kfk.kubernetes_commons import (
create_using_yaml,
delete_using_yaml,
replace_using_yaml,
)
from kfk.option_extensions import NotRequiredIf, RequiredIf


Expand Down Expand Up @@ -249,14 +253,7 @@ def alter(
topic_yaml = yaml.dump(topic_dict)
topic_temp_file = create_temp_file(topic_yaml)

os.system(
Kubectl()
.apply()
.from_file("{topic_temp_file_path}")
.namespace(namespace)
.build()
.format(topic_temp_file_path=topic_temp_file.name)
)
replace_using_yaml(topic_temp_file.name, namespace)

topic_temp_file.close()

Expand Down
15 changes: 6 additions & 9 deletions kfk/commands/users.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@
)
from kfk.config import STRIMZI_PATH, STRIMZI_VERSION
from kfk.kubectl_command_builder import Kubectl
from kfk.kubernetes_commons import create_using_yaml, delete_using_yaml
from kfk.kubernetes_commons import (
create_using_yaml,
delete_using_yaml,
replace_using_yaml,
)
from kfk.option_extensions import NotRequiredIf, RequiredIf
from kfk.utils import snake_to_camel_case

Expand Down Expand Up @@ -306,14 +310,7 @@ def alter(
user_yaml = yaml.dump(user_dict)
user_temp_file = create_temp_file(user_yaml)

os.system(
Kubectl()
.apply()
.from_file("{user_temp_file_path}")
.namespace(namespace)
.build()
.format(user_temp_file_path=user_temp_file.name)
)
replace_using_yaml(user_temp_file.name, namespace)

user_temp_file.close()

Expand Down
2 changes: 1 addition & 1 deletion kfk/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import sys
from pathlib import Path

STRIMZI_VERSION = "0.40.0"
STRIMZI_VERSION = "0.41.0"
KUBECTL_VERSION = "v1.29.3"


Expand Down
8 changes: 0 additions & 8 deletions kfk/kubectl_command_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,6 @@ def get(self):
self.cmd_str = self.cmd_str + SPACE + "get"
return self

def apply(self):
self.cmd_str = self.cmd_str + SPACE + "apply"
return self

def replace(self):
self.cmd_str = self.cmd_str + SPACE + "replace"
return self

def describe(self):
self.cmd_str = self.cmd_str + SPACE + "describe"
return self
Expand Down
26 changes: 26 additions & 0 deletions kfk/kubernetes_commons.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,17 @@ def delete_using_yaml(file_path, namespace):
)


def replace_using_yaml(file_path, namespace):
_operate_using_yaml(
api_client,
file_path,
"replace",
yaml_objects=None,
verbose=True,
namespace=namespace,
)


def _operate_using_yaml(
k8s_client,
yaml_file=None,
Expand Down Expand Up @@ -242,6 +253,21 @@ def _delete_using_yaml_object(k8s_api, yml_object, object_type, **kwargs):
_delete_object(k8s_api, name, object_type, **kwargs)


@yaml_object_argument_filter
def _replace_using_yaml_object(k8s_api, yml_object, object_type, **kwargs):
if hasattr(k8s_api, f"replace_namespaced_{object_type}"):
if "namespace" in yml_object["metadata"]:
namespace = yml_object["metadata"]["namespace"]
kwargs["namespace"] = namespace
resp = getattr(k8s_api, f"replace_namespaced_{object_type}")(
body=yml_object, **kwargs
)
else:
kwargs.pop("namespace", None)
resp = getattr(k8s_api, f"replace_{object_type}")(body=yml_object, **kwargs)
return resp


def _delete_object(k8s_api, name, object_type, delete_options_version="V1", **kwargs):
try:
if hasattr(k8s_api, f"delete_namespaced_{object_type}"):
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[project]
name = "strimzi-kafka-cli"
version = "0.1.0-alpha79"
version = "0.1.0-alpha80"
description = "Command Line Interface for Strimzi Kafka Operator"
authors = [{ name = "Aykut Bulgu", email = "aykut@systemcraftsman.com" }]
readme = "README.md"
Expand Down
38 changes: 26 additions & 12 deletions tests/test_topics_command.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,8 @@ def test_create_topic(self, mock_create_using_yaml, mock_create_temp_file):
result_topic_yaml = mock_create_temp_file.call_args[0][0]
assert expected_topic_yaml == result_topic_yaml

mock_create_using_yaml.assert_called_once()

@mock.patch("kfk.commands.topics.create_temp_file")
@mock.patch("kfk.commands.topics.create_using_yaml")
def test_create_topic_with_config(
Expand Down Expand Up @@ -256,9 +258,9 @@ def test_delete_topic(self, mock_delete_using_yaml):

@mock.patch("kfk.commands.topics.create_temp_file")
@mock.patch("kfk.commons.get_resource_yaml")
@mock.patch("kfk.commands.topics.os")
@mock.patch("kfk.commands.topics.replace_using_yaml")
def test_alter_topic_with_no_params(
self, mock_os, mock_get_resource_yaml, mock_create_temp_file
self, mock_replace_using_yaml, mock_get_resource_yaml, mock_create_temp_file
):
with open("tests/files/yaml/topic.yaml") as file:
expected_topic_yaml = file.read()
Expand All @@ -283,11 +285,13 @@ def test_alter_topic_with_no_params(
result_topic_yaml = mock_create_temp_file.call_args[0][0]
assert expected_topic_yaml == result_topic_yaml

mock_replace_using_yaml.assert_called_once()

@mock.patch("kfk.commands.topics.create_temp_file")
@mock.patch("kfk.commons.get_resource_yaml")
@mock.patch("kfk.commands.topics.os")
@mock.patch("kfk.commands.topics.replace_using_yaml")
def test_alter_topic_without_config(
self, mock_os, mock_get_resource_yaml, mock_create_temp_file
self, mock_replace_using_yaml, mock_get_resource_yaml, mock_create_temp_file
):
with open("tests/files/yaml/topic.yaml") as file:
topic_yaml = file.read()
Expand Down Expand Up @@ -318,11 +322,13 @@ def test_alter_topic_without_config(
result_topic_yaml = mock_create_temp_file.call_args[0][0]
assert expected_topic_yaml == result_topic_yaml

mock_replace_using_yaml.assert_called_once()

@mock.patch("kfk.commands.topics.create_temp_file")
@mock.patch("kfk.commons.get_resource_yaml")
@mock.patch("kfk.commands.topics.os")
@mock.patch("kfk.commands.topics.replace_using_yaml")
def test_alter_topic_with_config(
self, mock_os, mock_get_resource_yaml, mock_create_temp_file
self, mock_replace_using_yaml, mock_get_resource_yaml, mock_create_temp_file
):
with open("tests/files/yaml/topic.yaml") as file:
topic_yaml = file.read()
Expand Down Expand Up @@ -355,11 +361,13 @@ def test_alter_topic_with_config(
result_topic_yaml = mock_create_temp_file.call_args[0][0]
assert expected_topic_yaml == result_topic_yaml

mock_replace_using_yaml.assert_called_once()

@mock.patch("kfk.commands.topics.create_temp_file")
@mock.patch("kfk.commons.get_resource_yaml")
@mock.patch("kfk.commands.topics.os")
@mock.patch("kfk.commands.topics.replace_using_yaml")
def test_alter_topic_with_two_configs(
self, mock_os, mock_get_resource_yaml, mock_create_temp_file
self, mock_replace_using_yaml, mock_get_resource_yaml, mock_create_temp_file
):
with open("tests/files/yaml/topic.yaml") as file:
topic_yaml = file.read()
Expand Down Expand Up @@ -394,11 +402,13 @@ def test_alter_topic_with_two_configs(
result_topic_yaml = mock_create_temp_file.call_args[0][0]
assert expected_topic_yaml == result_topic_yaml

mock_replace_using_yaml.assert_called_once()

@mock.patch("kfk.commands.topics.create_temp_file")
@mock.patch("kfk.commons.get_resource_yaml")
@mock.patch("kfk.commands.topics.os")
@mock.patch("kfk.commands.topics.replace_using_yaml")
def test_alter_topic_with_two_configs_delete_one_config(
self, mock_os, mock_get_resource_yaml, mock_create_temp_file
self, mock_replace_using_yaml, mock_get_resource_yaml, mock_create_temp_file
):
with open("tests/files/yaml/topic_with_two_configs.yaml") as file:
topic_yaml = file.read()
Expand Down Expand Up @@ -427,11 +437,13 @@ def test_alter_topic_with_two_configs_delete_one_config(
result_topic_yaml = mock_create_temp_file.call_args[0][0]
assert expected_topic_yaml == result_topic_yaml

mock_replace_using_yaml.assert_called_once()

@mock.patch("kfk.commands.topics.create_temp_file")
@mock.patch("kfk.commons.get_resource_yaml")
@mock.patch("kfk.commands.topics.os")
@mock.patch("kfk.commands.topics.replace_using_yaml")
def test_alter_topic_with_two_configs_delete_two_configs(
self, mock_os, mock_get_resource_yaml, mock_create_temp_file
self, mock_replace_using_yaml, mock_get_resource_yaml, mock_create_temp_file
):
with open("tests/files/yaml/topic_with_two_configs.yaml") as file:
topic_yaml = file.read()
Expand Down Expand Up @@ -461,3 +473,5 @@ def test_alter_topic_with_two_configs_delete_two_configs(
expected_topic_yaml = file.read()
result_topic_yaml = mock_create_temp_file.call_args[0][0]
assert expected_topic_yaml == result_topic_yaml

mock_replace_using_yaml.assert_called_once()

0 comments on commit e189690

Please sign in to comment.