Skip to content

Commit 40904ee

Browse files
committed
use dedicated classes as input for add registry credentials method
1 parent 8d665b4 commit 40904ee

File tree

4 files changed

+124
-102
lines changed

4 files changed

+124
-102
lines changed

datacrunch/containers/__init__.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,10 @@
2121
Secret,
2222
RegistryCredential,
2323
ContainersService,
24+
BaseRegistryCredentials,
25+
DockerHubCredentials,
26+
GithubCredentials,
27+
GCRCredentials,
28+
AWSECRCredentials,
29+
CustomRegistryCredentials,
2430
)

datacrunch/containers/containers.py

Lines changed: 79 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
from dataclasses import dataclass, field
2-
from dataclasses_json import dataclass_json, config, Undefined # type: ignore
1+
from dataclasses import dataclass
2+
from dataclasses_json import dataclass_json, Undefined # type: ignore
33
from typing import List, Optional, Dict
44
from enum import Enum
55

@@ -275,6 +275,79 @@ class RegistryCredential:
275275
created_at: str
276276

277277

278+
@dataclass_json
279+
@dataclass
280+
class BaseRegistryCredentials:
281+
"""Base class for registry credentials"""
282+
name: str
283+
type: ContainerRegistryType
284+
285+
286+
@dataclass_json
287+
@dataclass
288+
class DockerHubCredentials(BaseRegistryCredentials):
289+
"""Credentials for DockerHub registry"""
290+
username: str
291+
access_token: str
292+
293+
def __init__(self, name: str, username: str, access_token: str):
294+
super().__init__(name=name, type=ContainerRegistryType.DOCKERHUB)
295+
self.username = username
296+
self.access_token = access_token
297+
298+
299+
@dataclass_json
300+
@dataclass
301+
class GithubCredentials(BaseRegistryCredentials):
302+
"""Credentials for GitHub Container Registry"""
303+
username: str
304+
access_token: str
305+
306+
def __init__(self, name: str, username: str, access_token: str):
307+
super().__init__(name=name, type=ContainerRegistryType.GITHUB)
308+
self.username = username
309+
self.access_token = access_token
310+
311+
312+
@dataclass_json
313+
@dataclass
314+
class GCRCredentials(BaseRegistryCredentials):
315+
"""Credentials for Google Container Registry"""
316+
service_account_key: str
317+
318+
def __init__(self, name: str, service_account_key: str):
319+
super().__init__(name=name, type=ContainerRegistryType.GCR)
320+
self.service_account_key = service_account_key
321+
322+
323+
@dataclass_json
324+
@dataclass
325+
class AWSECRCredentials(BaseRegistryCredentials):
326+
"""Credentials for AWS Elastic Container Registry"""
327+
access_key_id: str
328+
secret_access_key: str
329+
region: str
330+
ecr_repo: str
331+
332+
def __init__(self, name: str, access_key_id: str, secret_access_key: str, region: str, ecr_repo: str):
333+
super().__init__(name=name, type=ContainerRegistryType.AWS_ECR)
334+
self.access_key_id = access_key_id
335+
self.secret_access_key = secret_access_key
336+
self.region = region
337+
self.ecr_repo = ecr_repo
338+
339+
340+
@dataclass_json
341+
@dataclass
342+
class CustomRegistryCredentials(BaseRegistryCredentials):
343+
"""Credentials for custom container registries"""
344+
docker_config_json: str
345+
346+
def __init__(self, name: str, docker_config_json: str):
347+
super().__init__(name=name, type=ContainerRegistryType.CUSTOM)
348+
self.docker_config_json = docker_config_json
349+
350+
278351
class ContainersService:
279352
"""Service for managing container deployments"""
280353

@@ -581,73 +654,13 @@ def get_registry_credentials(self) -> List[RegistryCredential]:
581654
response = self.client.get(CONTAINER_REGISTRY_CREDENTIALS_ENDPOINT)
582655
return [RegistryCredential.from_dict(credential) for credential in response.json()]
583656

584-
def add_registry_credentials(
585-
self,
586-
name: str,
587-
registry_type: ContainerRegistryType,
588-
username: str = None,
589-
access_token: str = None,
590-
service_account_key: str = None,
591-
docker_config_json: str = None,
592-
access_key_id: str = None,
593-
secret_access_key: str = None,
594-
region: str = None,
595-
ecr_repo: str = None
596-
) -> None:
657+
def add_registry_credentials(self, credentials: BaseRegistryCredentials) -> None:
597658
"""Add registry credentials
598659
599-
:param name: name of the credentials
600-
:type name: str
601-
:param registry_type: type of registry (e.g. ContainerRegistryType.DOCKERHUB)
602-
:type registry_type: ContainerRegistryType
603-
:param username: registry username (required for DOCKERHUB and GITHUB)
604-
:type username: str
605-
:param access_token: registry access token (required for DOCKERHUB and GITHUB)
606-
:type access_token: str
607-
:param service_account_key: service account key JSON string (required for GCR)
608-
:type service_account_key: str
609-
:param docker_config_json: docker config JSON string (required for CUSTOM)
610-
:type docker_config_json: str
611-
:param access_key_id: AWS access key ID (required for AWS_ECR)
612-
:type access_key_id: str
613-
:param secret_access_key: AWS secret access key (required for AWS_ECR)
614-
:type secret_access_key: str
615-
:param region: AWS region (required for AWS_ECR)
616-
:type region: str
617-
:param ecr_repo: ECR repository URL (required for AWS_ECR)
618-
:type ecr_repo: str
660+
:param credentials: Registry credentials object
661+
:type credentials: BaseRegistryCredentials
619662
"""
620-
data = {
621-
"name": name,
622-
"type": registry_type.value
623-
}
624-
625-
# Add specific parameters based on registry type
626-
if registry_type == ContainerRegistryType.DOCKERHUB or registry_type == ContainerRegistryType.GITHUB:
627-
if not username or not access_token:
628-
raise ValueError(
629-
f"Username and access_token are required for {registry_type.value} registry type")
630-
data["username"] = username
631-
data["access_token"] = access_token
632-
elif registry_type == ContainerRegistryType.GCR:
633-
if not service_account_key:
634-
raise ValueError(
635-
"service_account_key is required for GCR registry type")
636-
data["service_account_key"] = service_account_key
637-
elif registry_type == ContainerRegistryType.AWS_ECR:
638-
if not all([access_key_id, secret_access_key, region, ecr_repo]):
639-
raise ValueError(
640-
"access_key_id, secret_access_key, region, and ecr_repo are required for AWS_ECR registry type")
641-
data["access_key_id"] = access_key_id
642-
data["secret_access_key"] = secret_access_key
643-
data["region"] = region
644-
data["ecr_repo"] = ecr_repo
645-
elif registry_type == ContainerRegistryType.CUSTOM:
646-
if not docker_config_json:
647-
raise ValueError(
648-
"docker_config_json is required for CUSTOM registry type")
649-
data["docker_config_json"] = docker_config_json
650-
663+
data = credentials.to_dict()
651664
self.client.post(CONTAINER_REGISTRY_CREDENTIALS_ENDPOINT, data)
652665

653666
def delete_registry_credentials(self, credentials_name: str) -> None:

examples/containers/registry_credentials_example.py

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
import os
22
from datacrunch import DataCrunchClient
3-
from datacrunch.containers.containers import ContainerRegistryType
3+
from datacrunch.containers import (
4+
DockerHubCredentials,
5+
GithubCredentials,
6+
GCRCredentials,
7+
AWSECRCredentials,
8+
CustomRegistryCredentials
9+
)
410

511
# Environment variables
612
DATACRUNCH_CLIENT_ID = os.environ.get('DATACRUNCH_CLIENT_ID')
@@ -11,21 +17,21 @@
1117
client_secret=DATACRUNCH_CLIENT_SECRET)
1218

1319
# Example 1: DockerHub Credentials
14-
datacrunch_client.containers.add_registry_credentials(
20+
dockerhub_creds = DockerHubCredentials(
1521
name="my-dockerhub-creds",
16-
registry_type=ContainerRegistryType.DOCKERHUB,
1722
username="your-dockerhub-username",
1823
access_token="your-dockerhub-access-token"
1924
)
25+
datacrunch_client.containers.add_registry_credentials(dockerhub_creds)
2026
print("Created DockerHub credentials")
2127

2228
# Example 2: GitHub Container Registry Credentials
23-
datacrunch_client.containers.add_registry_credentials(
29+
github_creds = GithubCredentials(
2430
name="my-github-creds",
25-
registry_type=ContainerRegistryType.GITHUB,
2631
username="your-github-username",
2732
access_token="your-github-token"
2833
)
34+
datacrunch_client.containers.add_registry_credentials(github_creds)
2935
print("Created GitHub credentials")
3036

3137
# Example 3: Google Container Registry (GCR) Credentials
@@ -43,22 +49,22 @@
4349
"client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/your-service-account%40your-project.iam.gserviceaccount.com"
4450
}"""
4551

46-
datacrunch_client.containers.add_registry_credentials(
52+
gcr_creds = GCRCredentials(
4753
name="my-gcr-creds",
48-
registry_type=ContainerRegistryType.GCR,
4954
service_account_key=gcr_service_account_key
5055
)
56+
datacrunch_client.containers.add_registry_credentials(gcr_creds)
5157
print("Created GCR credentials")
5258

5359
# Example 4: AWS ECR Credentials
54-
datacrunch_client.containers.add_registry_credentials(
60+
aws_creds = AWSECRCredentials(
5561
name="my-aws-ecr-creds",
56-
registry_type=ContainerRegistryType.AWS_ECR,
5762
access_key_id="AKIAEXAMPLE123456",
5863
secret_access_key="wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY",
5964
region="eu-north-1",
6065
ecr_repo="887841266746.dkr.ecr.eu-north-1.amazonaws.com"
6166
)
67+
datacrunch_client.containers.add_registry_credentials(aws_creds)
6268
print("Created AWS ECR credentials")
6369

6470
# Example 5: Custom Registry Credentials
@@ -70,11 +76,11 @@
7076
}
7177
}"""
7278

73-
datacrunch_client.containers.add_registry_credentials(
79+
custom_creds = CustomRegistryCredentials(
7480
name="my-custom-registry-creds",
75-
registry_type=ContainerRegistryType.CUSTOM,
7681
docker_config_json=custom_docker_config
7782
)
83+
datacrunch_client.containers.add_registry_credentials(custom_creds)
7884
print("Created Custom registry credentials")
7985

8086
# Delete all registry credentials

tests/unit_tests/containers/test_containers.py

Lines changed: 22 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@
2727
ScalingTriggers,
2828
QueueLoadScalingTrigger,
2929
UtilizationScalingTrigger,
30+
DockerHubCredentials,
31+
GCRCredentials,
32+
AWSECRCredentials,
33+
CustomRegistryCredentials,
3034
)
3135
from datacrunch.exceptions import APIException
3236

@@ -740,27 +744,17 @@ def test_add_registry_credentials(self, containers_service, registry_credentials
740744
)
741745

742746
# act
743-
containers_service.add_registry_credentials(
744-
REGISTRY_CREDENTIAL_NAME,
745-
ContainerRegistryType.DOCKERHUB,
746-
"username",
747-
"token"
747+
creds = DockerHubCredentials(
748+
name=REGISTRY_CREDENTIAL_NAME,
749+
username="username",
750+
access_token="token"
748751
)
752+
containers_service.add_registry_credentials(creds)
749753

750754
# assert
751755
assert responses.assert_call_count(
752756
registry_credentials_endpoint, 1) is True
753-
754-
@responses.activate
755-
def test_add_registry_credentials_validation_error(self, containers_service):
756-
# act & assert
757-
with pytest.raises(ValueError) as excinfo:
758-
containers_service.add_registry_credentials(
759-
REGISTRY_CREDENTIAL_NAME,
760-
ContainerRegistryType.DOCKERHUB,
761-
# Missing username and token
762-
)
763-
assert "Username and access_token are required" in str(excinfo.value)
757+
assert responses.calls[0].request.body == '{"name": "test-credential", "registry_type": "dockerhub", "username": "username", "access_token": "token"}'
764758

765759
@responses.activate
766760
def test_add_registry_credentials_gcr(self, containers_service, registry_credentials_endpoint):
@@ -773,15 +767,16 @@ def test_add_registry_credentials_gcr(self, containers_service, registry_credent
773767

774768
# act
775769
service_account_key = '{"key": "value"}'
776-
containers_service.add_registry_credentials(
777-
REGISTRY_CREDENTIAL_NAME,
778-
ContainerRegistryType.GCR,
770+
creds = GCRCredentials(
771+
name=REGISTRY_CREDENTIAL_NAME,
779772
service_account_key=service_account_key
780773
)
774+
containers_service.add_registry_credentials(creds)
781775

782776
# assert
783777
assert responses.assert_call_count(
784778
registry_credentials_endpoint, 1) is True
779+
assert responses.calls[0].request.body == '{"name": "test-credential", "registry_type": "gcr", "service_account_key": {"key": "value"}}'
785780

786781
@responses.activate
787782
def test_add_registry_credentials_aws_ecr(self, containers_service, registry_credentials_endpoint):
@@ -793,18 +788,19 @@ def test_add_registry_credentials_aws_ecr(self, containers_service, registry_cre
793788
)
794789

795790
# act
796-
containers_service.add_registry_credentials(
797-
REGISTRY_CREDENTIAL_NAME,
798-
ContainerRegistryType.AWS_ECR,
791+
creds = AWSECRCredentials(
792+
name=REGISTRY_CREDENTIAL_NAME,
799793
access_key_id="test-key",
800794
secret_access_key="test-secret",
801795
region="us-west-2",
802796
ecr_repo="test.ecr.aws.com"
803797
)
798+
containers_service.add_registry_credentials(creds)
804799

805800
# assert
806801
assert responses.assert_call_count(
807802
registry_credentials_endpoint, 1) is True
803+
assert responses.calls[0].request.body == '{"name": "test-credential", "registry_type": "aws-ecr", "access_key_id": "test-key", "secret_access_key": "test-secret", "region": "us-west-2", "ecr_repo": "test.ecr.aws.com"}'
808804

809805
@responses.activate
810806
def test_add_registry_credentials_custom(self, containers_service, registry_credentials_endpoint):
@@ -817,15 +813,16 @@ def test_add_registry_credentials_custom(self, containers_service, registry_cred
817813

818814
# act
819815
docker_config = '{"auths": {"registry.example.com": {"auth": "base64-encoded"}}}'
820-
containers_service.add_registry_credentials(
821-
REGISTRY_CREDENTIAL_NAME,
822-
ContainerRegistryType.CUSTOM,
816+
creds = CustomRegistryCredentials(
817+
name=REGISTRY_CREDENTIAL_NAME,
823818
docker_config_json=docker_config
824819
)
820+
containers_service.add_registry_credentials(creds)
825821

826822
# assert
827823
assert responses.assert_call_count(
828824
registry_credentials_endpoint, 1) is True
825+
assert responses.calls[0].request.body == '{"name": "test-credential", "registry_type": "custom", "docker_config_json": {"auths": {"registry.example.com": {"auth": "base64-encoded"}}}}'
829826

830827
@responses.activate
831828
def test_delete_registry_credentials(self, containers_service, registry_credentials_endpoint):

0 commit comments

Comments
 (0)