Skip to content

Commit 379c4de

Browse files
Merge pull request #306 from j3-signalroom/305-add-create_kafka_api_key_pair-and-delete_kafka_api_key-and-unit-tests
Resolved #305.
2 parents 20f9e6a + d1ac3ae commit 379c4de

File tree

6 files changed

+125
-0
lines changed

6 files changed

+125
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ The format is base on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
88
### Added
99
- Issue [#297](https://github.com/j3-signalroom/cc-clients-lib/issues/297)
1010
- Issue [#299](https://github.com/j3-signalroom/cc-clients-lib/issues/299)
11+
- Issue [#305](https://github.com/j3-signalroom/cc-clients-lib/issues/305)
1112

1213
### Changed
1314
- Issue [#301](https://github.com/j3-signalroom/cc-clients-lib/issues/301)

CHANGELOG.pdf

451 Bytes
Binary file not shown.

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ Metric Type|Description
105105
The **Environment Client** provides the following methods:
106106
- `get_environment_list`
107107
- `get_kafka_cluster_list`
108+
- `create_kafka_api_key`
109+
- `delete_kafka_api_key`
108110

109111
## **2.0 Unit Tests**
110112
The library includes unit tests for each client. The tests are located in the `tests` directory. To use them, you must clone the repo locally:
@@ -257,6 +259,8 @@ Unit Test|Command
257259
-|-
258260
Get list of all the Environments|`uv run pytest -s tests/test_environment_client.py::test_get_environment_list`
259261
Get list of the all the Kafka clusters|`uv run pytest -s tests/test_environment_client.py::test_get_kafka_cluster_list`
262+
Create a Kafka API Key|`uv run pytest -s tests/test_environment_client.py::test_create_kafka_api_key`
263+
Delete a Kafka API Key|`uv run pytest -s tests/test_environment_client.py::test_delete_kafka_api_key`
260264

261265
Otherwise, to run all the tests, use the following command:
262266
```shell

README.pdf

990 Bytes
Binary file not shown.

src/cc_clients_python_lib/environment_client.py

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,67 @@ def __init__(self, environment_config: dict):
3030
self.environment_id = environment_config[ENVIRONMENT_CONFIG["environment_id"]]
3131
self.base_url = "https://api.confluent.cloud"
3232

33+
def create_kafka_api_key(self, kafka_cluster_id: str, principal_id: str) -> Tuple[int, str, Dict]:
34+
"""This function submits a RESTful API call to create a Kafka API key pair.
35+
Reference: https://docs.confluent.io/cloud/current/api.html#tag/API-Keys-(iamv2)/operation/createIamV2ApiKey
36+
37+
Arg(s):
38+
kafka_cluster_id (str): The Kafka cluster ID.
39+
principal_id (str): The principal ID for the Kafka API key.
40+
41+
Return(s):
42+
Tuple[int, str, Dict]: A tuple of the HTTP status code, the error message (if any), and the Kafka API key pair.
43+
"""
44+
payload = {
45+
"spec": {
46+
"display_name": "Kafka Cluster API Key",
47+
"description": "API key for Kafka cluster operations",
48+
"owner": {
49+
"id": principal_id
50+
},
51+
"resource": {
52+
"id": kafka_cluster_id
53+
}
54+
}
55+
}
56+
57+
response = requests.post(url=f"{self.base_url}/iam/v2/api-keys",
58+
auth=HTTPBasicAuth(self.confluent_cloud_api_key, self.confluent_cloud_api_secret),
59+
json=payload)
60+
61+
try:
62+
# Raise HTTPError, if occurred.
63+
response.raise_for_status()
64+
65+
api_key_pair = {}
66+
api_key_pair["key"] = response.json().get("id")
67+
api_key_pair["secret"] = response.json().get("spec").get("secret")
68+
69+
return response.status_code, "", api_key_pair
70+
except requests.exceptions.RequestException as e:
71+
return response.status_code, f"Fail to create the Kafka API key pair because {e}. The error details are: {response.json() if response.content else {}}", response.json() if response.content else {}
72+
73+
def delete_kafka_api_key(self, api_key: str) -> Tuple[int, str]:
74+
"""This function submits a RESTful API call to delete a Kafka API key pair.
75+
Reference: https://docs.confluent.io/cloud/current/api.html#tag/API-Keys-(iamv2)/operation/deleteIamV2ApiKey
76+
77+
Arg(s):
78+
api_key (str): The Kafka API key.
79+
80+
Return(s):
81+
Tuple[int, str]: A tuple of the HTTP status code, and error message (if any).
82+
"""
83+
response = requests.delete(url=f"{self.base_url}/iam/v2/api-keys/{api_key}",
84+
auth=HTTPBasicAuth(self.confluent_cloud_api_key, self.confluent_cloud_api_secret))
85+
86+
try:
87+
# Raise HTTPError, if occurred.
88+
response.raise_for_status()
89+
90+
return response.status_code, ""
91+
except requests.exceptions.RequestException as e:
92+
return response.status_code, f"Fail to delete the Kafka API key pair because {e}. The error details are: {response.json() if response.content else {}}"
93+
3394
def get_environment_list(self, page_size: int = DEFAULT_PAGE_SIZE) -> Tuple[int, str, Dict]:
3495
"""This function submits a RESTful API call to get a list of environments.
3596
Reference: https://docs.confluent.io/cloud/current/api.html#tag/Environments-(orgv2)/operation/listOrgV2Environments

tests/test_environment_client.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import json
22
import logging
3+
import time
34
from dotenv import load_dotenv
45
import os
56
import pytest
@@ -21,6 +22,8 @@
2122

2223
# Initialize the global variables.
2324
environment_config = {}
25+
kafka_cluster_id = ""
26+
principal_id = ""
2427

2528

2629
@pytest.fixture(autouse=True)
@@ -34,6 +37,62 @@ def load_configurations():
3437
environment_config[ENVIRONMENT_CONFIG["confluent_cloud_api_secret"]] = os.getenv("CONFLUENT_CLOUD_API_SECRET")
3538
environment_config[ENVIRONMENT_CONFIG["environment_id"]] = os.getenv("ENVIRONMENT_ID")
3639

40+
global kafka_cluster_id
41+
global principal_id
42+
43+
# Set the Kafka cluster ID and owner ID.
44+
kafka_cluster_id = os.getenv("KAFKA_CLUSTER_ID")
45+
principal_id = os.getenv("PRINCIPAL_ID")
46+
47+
def test_create_kafka_api_key():
48+
"""Test the create_kafka_api_key() function."""
49+
50+
# Instantiate the EnvironmentClient class.
51+
environment_client = EnvironmentClient(environment_config=environment_config)
52+
53+
http_status_code, error_message, api_key_pair = environment_client.create_kafka_api_key(kafka_cluster_id=kafka_cluster_id, principal_id=principal_id)
54+
55+
try:
56+
assert http_status_code == HttpStatus.ACCEPTED, f"HTTP Status Code: {http_status_code}"
57+
58+
beautified = json.dumps(api_key_pair, indent=4, sort_keys=True)
59+
logger.info(f"Kafka API Key Pair: {beautified}")
60+
except AssertionError as e:
61+
logger.error(e)
62+
logger.error("HTTP Status Code: %d, Error Message: %s, Kafka API Key Pair: %s", http_status_code, error_message, api_key_pair)
63+
return
64+
65+
def test_delete_kafka_api_key():
66+
"""Test the delete_kafka_api_key() function."""
67+
68+
# Instantiate the EnvironmentClient class.
69+
environment_client = EnvironmentClient(environment_config=environment_config)
70+
71+
http_status_code, error_message, api_key_pair = environment_client.create_kafka_api_key(kafka_cluster_id=kafka_cluster_id, principal_id=principal_id)
72+
73+
try:
74+
assert http_status_code == HttpStatus.ACCEPTED, f"HTTP Status Code: {http_status_code}"
75+
76+
beautified = json.dumps(api_key_pair, indent=4, sort_keys=True)
77+
logger.info(f"Kafka API Key Pair: {beautified}")
78+
except AssertionError as e:
79+
logger.error(e)
80+
logger.error("HTTP Status Code: %d, Error Message: %s, Kafka API Key Pair: %s", http_status_code, error_message, api_key_pair)
81+
return
82+
83+
time.sleep(10) # Wait for 10 seconds before deleting the API key.
84+
85+
http_status_code, error_message = environment_client.delete_kafka_api_key(api_key=api_key_pair["key"])
86+
87+
try:
88+
assert http_status_code == HttpStatus.NO_CONTENT, f"HTTP Status Code: {http_status_code}"
89+
90+
logger.info(f"Successfully deleted Kafka API Key: {api_key_pair['key']}")
91+
except AssertionError as e:
92+
logger.error(e)
93+
logger.error("HTTP Status Code: %d, Error Message: %s", http_status_code, error_message)
94+
return
95+
3796
def test_get_environment_list():
3897
"""Test the get_environment_list() function."""
3998

0 commit comments

Comments
 (0)