cluster-builder 0.3.2__py3-none-any.whl → 0.4.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of cluster-builder might be problematic. Click here for more details.
- cluster_builder/swarmchestrate.py +104 -0
- cluster_builder/templates/deploy_manifest.tf +7 -13
- cluster_builder/templates/registry_secret.tf +52 -0
- {cluster_builder-0.3.2.dist-info → cluster_builder-0.4.0.dist-info}/METADATA +1 -1
- {cluster_builder-0.3.2.dist-info → cluster_builder-0.4.0.dist-info}/RECORD +8 -7
- {cluster_builder-0.3.2.dist-info → cluster_builder-0.4.0.dist-info}/WHEEL +0 -0
- {cluster_builder-0.3.2.dist-info → cluster_builder-0.4.0.dist-info}/licenses/LICENSE +0 -0
- {cluster_builder-0.3.2.dist-info → cluster_builder-0.4.0.dist-info}/top_level.txt +0 -0
|
@@ -591,3 +591,107 @@ class Swarmchestrate:
|
|
|
591
591
|
finally:
|
|
592
592
|
if copy_dir.exists():
|
|
593
593
|
shutil.rmtree(copy_dir)
|
|
594
|
+
|
|
595
|
+
def create_registry_secrets(self, cluster_config: dict):
|
|
596
|
+
"""
|
|
597
|
+
Create Docker registry secrets in Kubernetes using OpenTofu.
|
|
598
|
+
|
|
599
|
+
:param cluster_config: dict with keys:
|
|
600
|
+
{
|
|
601
|
+
"master_ip": "1.2.3.4",
|
|
602
|
+
"ssh_user": "ubuntu",
|
|
603
|
+
"ssh_private_key_path": "/path/to/key.pem",
|
|
604
|
+
"namespace": "optional-namespace",
|
|
605
|
+
"secret_names": ["optional-name1", "optional-name2"]
|
|
606
|
+
}
|
|
607
|
+
"""
|
|
608
|
+
load_dotenv()
|
|
609
|
+
|
|
610
|
+
# Read registry creds from env
|
|
611
|
+
registries = os.getenv("DOCKER_REGISTRIES", "").split(",")
|
|
612
|
+
usernames = os.getenv("DOCKER_USERNAMES", "").split(",")
|
|
613
|
+
passwords = os.getenv("DOCKER_PASSWORDS", "").split(",")
|
|
614
|
+
|
|
615
|
+
if not (len(registries) == len(usernames) == len(passwords)):
|
|
616
|
+
raise RuntimeError("Mismatch in registry, username, and password counts")
|
|
617
|
+
|
|
618
|
+
# Get cluster connection from method input
|
|
619
|
+
master_ip = cluster_config.get("master_ip")
|
|
620
|
+
ssh_user = cluster_config.get("ssh_user")
|
|
621
|
+
ssh_key_path = cluster_config.get("ssh_private_key_path")
|
|
622
|
+
namespace = cluster_config.get("namespace", "default")
|
|
623
|
+
secret_names = cluster_config.get("secret_names", [])
|
|
624
|
+
|
|
625
|
+
if not all([master_ip, ssh_user, ssh_key_path]):
|
|
626
|
+
raise ValueError("Cluster config missing required keys")
|
|
627
|
+
|
|
628
|
+
# Validate secret_names length if provided
|
|
629
|
+
if secret_names and len(secret_names) != len(registries):
|
|
630
|
+
raise RuntimeError("Length of secret_names must match number of registries")
|
|
631
|
+
|
|
632
|
+
# Create temp dir for TF
|
|
633
|
+
temp_dir = Path(self.output_dir) / "registry-secret"
|
|
634
|
+
temp_dir.mkdir(parents=True, exist_ok=True)
|
|
635
|
+
|
|
636
|
+
try:
|
|
637
|
+
# Copy template tf file into temp dir
|
|
638
|
+
tf_source_file = Path(self.template_manager.templates_dir) / "registry_secret.tf"
|
|
639
|
+
if not tf_source_file.exists():
|
|
640
|
+
logger.debug(f"registry_secret.tf not found at: {tf_source_file}")
|
|
641
|
+
raise RuntimeError(f"registry_secret.tf not found at: {tf_source_file}")
|
|
642
|
+
|
|
643
|
+
tf_target = temp_dir / "registry_secret.tf"
|
|
644
|
+
shutil.copy(tf_source_file, tf_target)
|
|
645
|
+
logger.debug(f"Copied registry_secret.tf to {temp_dir}")
|
|
646
|
+
|
|
647
|
+
# Setup env for tofu
|
|
648
|
+
env_vars = os.environ.copy()
|
|
649
|
+
env_vars["TF_LOG"] = os.getenv("TF_LOG", "INFO")
|
|
650
|
+
|
|
651
|
+
# tofu init
|
|
652
|
+
CommandExecutor.run_command(
|
|
653
|
+
["tofu", "init"],
|
|
654
|
+
cwd=str(temp_dir),
|
|
655
|
+
description="Init OpenTofu",
|
|
656
|
+
env=env_vars,
|
|
657
|
+
)
|
|
658
|
+
|
|
659
|
+
# Apply registry secrets
|
|
660
|
+
apply_vars = [
|
|
661
|
+
f"-var=registries={json.dumps(registries)}",
|
|
662
|
+
f"-var=usernames={json.dumps(usernames)}",
|
|
663
|
+
f"-var=passwords={json.dumps(passwords)}",
|
|
664
|
+
f"-var=master_ip={master_ip}",
|
|
665
|
+
f"-var=ssh_user={ssh_user}",
|
|
666
|
+
f"-var=ssh_private_key_path={ssh_key_path}",
|
|
667
|
+
f"-var=namespace={namespace}"
|
|
668
|
+
]
|
|
669
|
+
if secret_names:
|
|
670
|
+
apply_vars.append(f"-var=secret_names={json.dumps(secret_names)}")
|
|
671
|
+
|
|
672
|
+
CommandExecutor.run_command(
|
|
673
|
+
["tofu", "apply", "-auto-approve"] + apply_vars,
|
|
674
|
+
cwd=str(temp_dir),
|
|
675
|
+
description="Apply registry secrets",
|
|
676
|
+
env=env_vars,
|
|
677
|
+
)
|
|
678
|
+
|
|
679
|
+
# Fetch Terraform/OpenTofu output
|
|
680
|
+
output_result = CommandExecutor.run_command(
|
|
681
|
+
["tofu", "output", "-json", "docker_registry_secret_names"],
|
|
682
|
+
cwd=str(temp_dir),
|
|
683
|
+
description="Fetch registry secret names",
|
|
684
|
+
env=env_vars,
|
|
685
|
+
)
|
|
686
|
+
|
|
687
|
+
lines = [line for line in output_result.splitlines() if line.strip()]
|
|
688
|
+
if not lines:
|
|
689
|
+
raise RuntimeError("No output received from OpenTofu for secret names")
|
|
690
|
+
secret_names_list = json.loads(lines[-1])
|
|
691
|
+
logger.info(f"Created registry secrets: {secret_names_list}")
|
|
692
|
+
|
|
693
|
+
return secret_names_list
|
|
694
|
+
|
|
695
|
+
finally:
|
|
696
|
+
logger.debug(f"Cleaning up temp dir: {temp_dir}")
|
|
697
|
+
shutil.rmtree(temp_dir)
|
|
@@ -13,31 +13,25 @@ resource "null_resource" "copy_manifests" {
|
|
|
13
13
|
host = var.master_ip
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
#
|
|
17
|
-
provisioner "remote-exec" {
|
|
18
|
-
inline = [
|
|
19
|
-
"mkdir -p /home/${var.ssh_user}/manifests",
|
|
20
|
-
"sudo chmod 755 /home/${var.ssh_user}/manifests"
|
|
21
|
-
]
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
# Copy the manifests
|
|
16
|
+
# Copy the manifest folder into /tmp
|
|
25
17
|
provisioner "file" {
|
|
26
18
|
source = var.manifest_folder
|
|
27
|
-
destination = "/
|
|
19
|
+
destination = "/tmp/"
|
|
28
20
|
}
|
|
29
21
|
|
|
30
|
-
# Apply namespace.yaml first
|
|
22
|
+
# Apply namespace.yaml first if exists
|
|
31
23
|
provisioner "remote-exec" {
|
|
32
24
|
inline = [
|
|
33
|
-
"
|
|
25
|
+
"folder_name=$(basename ${var.manifest_folder})",
|
|
26
|
+
"if [ -f /tmp/$folder_name/namespace.yaml ]; then sudo -E KUBECONFIG=/etc/rancher/k3s/k3s.yaml kubectl apply -f /tmp/$folder_name/namespace.yaml; fi"
|
|
34
27
|
]
|
|
35
28
|
}
|
|
36
29
|
|
|
37
30
|
# Apply the rest of the manifests
|
|
38
31
|
provisioner "remote-exec" {
|
|
39
32
|
inline = [
|
|
40
|
-
"
|
|
33
|
+
"folder_name=$(basename ${var.manifest_folder})",
|
|
34
|
+
"sudo -E KUBECONFIG=/etc/rancher/k3s/k3s.yaml kubectl apply -R -f /tmp/$folder_name"
|
|
41
35
|
]
|
|
42
36
|
}
|
|
43
37
|
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
variable "registries" {
|
|
2
|
+
type = list(string)
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
variable "usernames" {
|
|
6
|
+
type = list(string)
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
variable "passwords" {
|
|
10
|
+
type = list(string)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
variable "secret_names" {
|
|
14
|
+
type = list(string)
|
|
15
|
+
default = []
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
variable "master_ip" {}
|
|
19
|
+
variable "ssh_user" {}
|
|
20
|
+
variable "ssh_private_key_path" {}
|
|
21
|
+
variable "namespace" {
|
|
22
|
+
default = "default"
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
resource "null_resource" "docker_registry_secrets" {
|
|
26
|
+
count = length(var.registries)
|
|
27
|
+
|
|
28
|
+
connection {
|
|
29
|
+
type = "ssh"
|
|
30
|
+
host = var.master_ip
|
|
31
|
+
user = var.ssh_user
|
|
32
|
+
private_key = file(var.ssh_private_key_path)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
provisioner "remote-exec" {
|
|
36
|
+
inline = [
|
|
37
|
+
<<EOT
|
|
38
|
+
SECRET_NAME=${length(var.secret_names) > 0 ? var.secret_names[count.index] : "regcred-${count.index}"}
|
|
39
|
+
sudo -E KUBECONFIG=/etc/rancher/k3s/k3s.yaml kubectl create secret docker-registry $SECRET_NAME \
|
|
40
|
+
--docker-server="${var.registries[count.index]}" \
|
|
41
|
+
--docker-username="${var.usernames[count.index]}" \
|
|
42
|
+
--docker-password="${var.passwords[count.index]}" \
|
|
43
|
+
--namespace="${var.namespace}" \
|
|
44
|
+
--dry-run=client -o yaml | sudo kubectl apply -f -
|
|
45
|
+
EOT
|
|
46
|
+
]
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
output "docker_registry_secret_names" {
|
|
51
|
+
value = [for i in range(length(var.registries)) : length(var.secret_names) > 0 ? var.secret_names[i] : "regcred-${i}"]
|
|
52
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
cluster_builder/__init__.py,sha256=p2Rb2BTVm-ScqCKE38436WsItY1BjVAnvx7zwmneSLs,256
|
|
2
|
-
cluster_builder/swarmchestrate.py,sha256=
|
|
2
|
+
cluster_builder/swarmchestrate.py,sha256=3cVjj1Qe2LT-N8GUL6W-jaexf6yJS6aKGaqkiUojEO8,27388
|
|
3
3
|
cluster_builder/config/__init__.py,sha256=HqCua7nqa0m4RNrH-wAw-GNZ8PfmKOeYs2Ur81xGIKU,222
|
|
4
4
|
cluster_builder/config/cluster.py,sha256=0CASucE_npbEmGnyR3UmF0v836tcx9HthAiotCh4sSo,5116
|
|
5
5
|
cluster_builder/config/postgres.py,sha256=nQ5QxxI00GmGAbDl_9I1uEU2eBy1D2eJWGzhsBYUFMc,3354
|
|
@@ -7,10 +7,11 @@ cluster_builder/infrastructure/__init__.py,sha256=e8XY3K7Y6FJS-ODr5ufB_myV7btFvY
|
|
|
7
7
|
cluster_builder/infrastructure/executor.py,sha256=oymr_ZP8xAOcNDAuGCp1v4F81-chR3VRotoD732l4q0,2874
|
|
8
8
|
cluster_builder/infrastructure/templates.py,sha256=TAdNP-012L76dOYsd7JVIQOD4K9XNobK9QWfOoYrbeU,4084
|
|
9
9
|
cluster_builder/templates/aws_provider.tf,sha256=VIRuH_-8pYtJ0Mkck38WUSszHiN3DesFOWkx75aoOIY,425
|
|
10
|
-
cluster_builder/templates/deploy_manifest.tf,sha256=
|
|
10
|
+
cluster_builder/templates/deploy_manifest.tf,sha256=kFf3Q6nuvYzFxFbVdGPjiFINN8ep4_8n0BAMx5UD5nQ,1004
|
|
11
11
|
cluster_builder/templates/ha_user_data.sh.tpl,sha256=njvsBRjdKBuUaYbujJ689wI2sfpoHVpr2kkbG9sKzpw,981
|
|
12
12
|
cluster_builder/templates/master_user_data.sh.tpl,sha256=g_uaehoi9Pm_vCx_vJhXCUqAt7DpcqnAi_QPm5VOgWw,1481
|
|
13
13
|
cluster_builder/templates/openstack_provider.tf,sha256=wFUmkws5xSTOM1GW0Jd8JD__VAUBPNF4j1amo2SRyVM,2049
|
|
14
|
+
cluster_builder/templates/registry_secret.tf,sha256=_om5QIQR2lEVDJb-4B7t25uHL66bGLa7XPSBTQ16E-Y,1336
|
|
14
15
|
cluster_builder/templates/worker_user_data.sh.tpl,sha256=9WP6qe6DGMHgFds_loI1N7DEuMeOI6U4SA-g3GYIIIU,1034
|
|
15
16
|
cluster_builder/templates/aws/main.tf,sha256=v_mR6tdH4-E1SKI8FNqfgl-gU2POrKqRfkXCXV1DGFQ,4875
|
|
16
17
|
cluster_builder/templates/edge/main.tf,sha256=8sBL_ofFfhMEH2biPRmB7X4H_SG3JgYygCOEo90yDTY,2255
|
|
@@ -18,8 +19,8 @@ cluster_builder/templates/openstack/main.tf,sha256=uMzArcNE0wbx23Y0x9B7jGIiWIgJd
|
|
|
18
19
|
cluster_builder/utils/__init__.py,sha256=TeronqOND-SIfi0e76lwD1HfUiPO2h2ZfYhLIwZ3Aks,145
|
|
19
20
|
cluster_builder/utils/hcl.py,sha256=VptRAt2Cy0AxowqMJBZ60KGe4Uptji3Y9WiYrDQsrqY,11534
|
|
20
21
|
cluster_builder/utils/logging.py,sha256=rwDViuqG8PMcXJWHOdtdgbGhWMnbSZ4MwfKsXHxu2B4,1242
|
|
21
|
-
cluster_builder-0.
|
|
22
|
-
cluster_builder-0.
|
|
23
|
-
cluster_builder-0.
|
|
24
|
-
cluster_builder-0.
|
|
25
|
-
cluster_builder-0.
|
|
22
|
+
cluster_builder-0.4.0.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
23
|
+
cluster_builder-0.4.0.dist-info/METADATA,sha256=O_6VEjEZY7hdC-Z_t0VV4T2vUGa5OiOXlSZ6yc-d7JU,10937
|
|
24
|
+
cluster_builder-0.4.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
25
|
+
cluster_builder-0.4.0.dist-info/top_level.txt,sha256=fTW8EW1mcWoeWprjwxSHRWpqfXYX8iN-ByEt8HPXIcs,16
|
|
26
|
+
cluster_builder-0.4.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|