Skip to content

Commit dde21b4

Browse files
committed
wip: standalone cli
1 parent b65f5ac commit dde21b4

8 files changed

Lines changed: 86 additions & 44 deletions

File tree

src/cli.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import os
12
import sys
23
import argparse
34
import signal
@@ -19,7 +20,8 @@ def main():
1920
# Global options
2021
global_group = parser.add_argument_group("global")
2122
global_group.add_argument("-c", "--context", type=str, metavar="CT", default=None, help="Local kubectl context")
22-
global_group.add_argument("-n", "--namespace", type=str, metavar="NS", default=None, help="Target a namespace for backup job run")
23+
global_group.add_argument("-n", "--namespace", type=str, metavar="NS", default=None, help="Target a namespace for backup job run. Using 'default' if not given.")
24+
global_group.add_argument("-i", "--instance", type=str, metavar="NS", default=None, help="Target a running instance of bkup. Using 'bkup' if not given.")
2325
global_group.add_argument("-j", "--job", action="store_true", help="Run backup job(s) based on current backup-map")
2426
global_group.add_argument("-bm", "--backup-map", action="store_true", help="Manage backup-map configuration")
2527

@@ -32,11 +34,21 @@ def main():
3234
args = parser.parse_args()
3335

3436
cluster_context = args.context
37+
os.environ["CLUSTER_CONTEXT"] = cluster_context
38+
3539
namespace_input = args.namespace
3640
if namespace_input:
3741
namespace = namespace_input
3842
else:
3943
namespace = "default"
44+
os.environ["TARGET_NAMESPACES"] = namespace
45+
46+
instance_input = args.instance
47+
if instance_input:
48+
instance = instance_input
49+
else:
50+
instance = 'bkup'
51+
os.environ["INSTALLATION_NAME"] = instance
4052

4153
# Strict validation of -bm sub-options usage
4254
if (args.apply or args.preview or args.get_current) and not args.backup_map:
@@ -51,6 +63,18 @@ def main():
5163

5264

5365
if args.job:
66+
master_ns = config_secret.get_config_secret_namespace(kube)
67+
backup_map_name = backup_map.get_backup_map_name()
68+
69+
# Verify ConfigMap existence before processing
70+
saved_map = backup_map.get_backup_map_content(kube, namespace=master_ns)
71+
if not saved_map or not saved_map.get("namespaces"):
72+
print(f"error: ConfigMap '{backup_map_name}' is missing or empty in namespace '{master_ns}'.")
73+
print("hint: Generate and apply one first using 'bkup -bm -a'")
74+
sys.exit(1)
75+
76+
print(f"{yaml.dump(saved_map, sort_keys=False, default_flow_style=False)}\n")
77+
5478
master.main()
5579

5680
elif args.backup_map:

src/kubernetes/base.py

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import yaml
33
import time
44
import hashlib
5+
import base64
56
from kubernetes import client, config
67

78

@@ -303,8 +304,6 @@ def save_to_configmap(self, name: str, namespace: str, data: dict):
303304

304305
def get_secret_payload(self, name: str, namespace: str) -> dict:
305306
"""Centralized and safe extraction of Secret base64 values decoded into a plain text map."""
306-
import base64
307-
308307
try:
309308
secret = self.core_v1.read_namespaced_secret(name=name, namespace=namespace)
310309
if not secret.data:
@@ -396,25 +395,25 @@ def _launch_generic_job(self, template_path: str, replacements: dict):
396395
if name == "STORAGE_ADDRESS":
397396
val = secret_data.get("storage-address")
398397
if not val:
399-
raise ValueError(f"Required key 'storage-address' missing in Secret 'bkup-config' (namespace: '{master_ns}')")
398+
raise ValueError(f"Required key 'storage-address' missing in 'config' Secret (namespace: '{master_ns}')")
400399
final_overrides[name] = {"name": name, "value": val}
401400

402401
elif name == "STORAGE_USERNAME":
403402
val = secret_data.get("storage-username")
404403
if not val:
405-
raise ValueError(f"Required key 'storage-username' missing in Secret 'bkup-config' (namespace: '{master_ns}')")
404+
raise ValueError(f"Required key 'storage-username' missing in 'config' Secret (namespace: '{master_ns}')")
406405
final_overrides[name] = {"name": name, "value": val}
407406

408407
elif name == "STORAGE_PASSWORD":
409408
val = secret_data.get("storage-password")
410409
if not val:
411-
raise ValueError(f"Required key 'storage-password' missing in Secret 'bkup-config' (namespace: '{master_ns}')")
410+
raise ValueError(f"Required key 'storage-password' missing in 'config' Secret (namespace: '{master_ns}')")
412411
final_overrides[name] = {"name": name, "value": val}
413412

414413
elif name == "CLUSTER_NAME":
415414
val = secret_data.get("cluster-name")
416415
if not val:
417-
raise ValueError(f"Required key 'cluster-name' missing in Secret 'bkup-config' (namespace: '{master_ns}')")
416+
raise ValueError(f"Required key 'cluster-name' missing (namespace: '{master_ns}')")
418417
final_overrides[name] = {"name": name, "value": val}
419418

420419
else:

src/master.py

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
1+
import os
12
import sys
23
import argparse
34
import signal
45
import yaml
56

7+
from src.kubernetes.base import KubernetesBase
68
from src.kubernetes.job_volume import VolumeBackupJob
79
from src.kubernetes.job_postgresql import PostgresBackupJob
810
import src.utils.psql as psql
@@ -117,7 +119,7 @@ def run_backup_job(cluster_context: str, namespace: str):
117119
# STRICT BACKUP-MAP CHECK
118120
# --------------------------------------------------
119121
ns_claims_entries = []
120-
backup_map_config = backup_map.get_backup_map(kube, master_ns=master_ns)
122+
backup_map_config = backup_map.get_backup_map_content(kube, master_ns=master_ns)
121123

122124
if isinstance(backup_map_config, dict) and "namespaces" in backup_map_config:
123125
for ns_entry in backup_map_config.get("namespaces", []):
@@ -351,23 +353,29 @@ def main():
351353
# ----------------------------------
352354
# Reject if kube context if missing
353355
try:
354-
kube = VolumeBackupJob(context=cluster_context, namespace="default")
356+
cluster_context = os.environ["CLUSTER_CONTEXT"]
357+
target_namespaces = os.environ["TARGET_NAMESPACES"]
358+
359+
kube = KubernetesBase(context=cluster_context, namespace=namespace)
355360
kube_client_sigkill = kube
356361
except Exception as e:
357362
print(f"error: {e}")
358363
sys.exit(1)
359364

360-
master_ns = config_secret.get_config_secret_namespace(kube)
361-
kube.namespace = master_ns
365+
# master_ns = config_secret.get_config_secret_namespace(kube)
366+
# kube.namespace = master_ns
362367

363-
# Verify ConfigMap existence before processing
364-
saved_map = backup_map.get_backup_map(kube, master_ns=master_ns)
365-
if not saved_map or not saved_map.get("namespaces"):
366-
print(f"error: ConfigMap 'bkup-backup-map' is missing or empty in namespace '{master_ns}'.")
367-
print("hint: Generate and apply one first using 'bkup -bm -a'")
368-
sys.exit(1)
368+
# backup_map_name = backup_map.get_backup_map_name
369+
# backup_map_ns = master_ns
370+
371+
# # Verify ConfigMap existence before processing
372+
# saved_map = backup_map.get_backup_map_content(kube, namespace=backup_map_ns)
373+
# if not saved_map or not saved_map.get("namespaces"):
374+
# print(f"error: ConfigMap '{backup_map_name}' is missing or empty in namespace '{backup_map_ns}'.")
375+
# print("hint: Generate and apply one first using 'bkup -bm -a'")
376+
# sys.exit(1)
369377

370-
print(f"{yaml.dump(saved_map, sort_keys=False, default_flow_style=False)}\n")
378+
# print(f"{yaml.dump(saved_map, sort_keys=False, default_flow_style=False)}\n")
371379

372380
# If a single namespace is targeted via -n, execute only this one
373381
if namespace_input:

src/utils/backup_map.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@ def get_backup_map_name():
99
return f"{general_helper.get_installation_name()}-backup-map"
1010

1111

12-
def get_backup_map(kube, master_ns: str = None) -> dict:
12+
def get_backup_map_content(kube, namespace: str = None) -> dict:
1313
"""Get existing ConfigMap of the backup-map."""
1414
cm_name = get_backup_map_name()
1515

16-
target_ns = master_ns if master_ns else kube.get_namespace()
16+
target_ns = namespace if namespace else kube.get_namespace()
1717
saved_map = kube.get_configmap(name=cm_name, namespace=target_ns)
1818

1919
if not saved_map:

src/utils/config_secret.py

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,16 +6,12 @@ def get_config_secret_name():
66
return f"{general_helper.get_installation_name()}-backup-map"
77

88

9-
def get_config_secret_namespace(kube_client) -> str:
9+
def get_config_secret_namespace(kube) -> str:
1010
"""Find the namespace containing the 'config' Secret."""
11-
12-
secret_name = f"{general_helper.get_installation_name()}-config"
13-
14-
for ns in kube_client.list_namespaces():
15-
try:
16-
if kube_client.get_secret_payload(name=secret_name, namespace=ns):
11+
try:
12+
for ns in kube.list_namespaces():
13+
secret_name = f"{general_helper.get_installation_name()}-config"
14+
if kube.get_secret_payload(f"{secret_name}-config", namespace=ns):
1715
return ns
18-
except Exception:
19-
continue
20-
21-
raise RuntimeError("Error: Secret 'config' not found in any namespace.")
16+
except Exception as e:
17+
print(f"Error: Secret 'config' not found in any namespace. {e}")

templates_install/config.secret.yaml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@ metadata:
55
namespace: ${NAMESPACE}
66
type: Opaque
77
stringData:
8-
backup-map-namespace: ${NAMESPACE} # Can be anything else, but default is the same as current secret
9-
cluster-name: changeme
108
storage-address: changeme
119
storage-username: changeme
1210
storage-password: changeme

templates_install/master.pod.ci.yaml

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,23 @@ spec:
1111
imagePullPolicy: Always
1212
env:
1313
- name: CLUSTER_NAME
14-
valueFrom:
15-
secretKeyRef:
16-
name: bkup-config
17-
key: cluster-name
18-
optional: false
14+
value: ${CLUSTER_NAME}
1915
- name: NAMESPACE
2016
valueFrom:
2117
fieldRef:
2218
fieldPath: metadata.namespace
23-
imagePullSecrets:
19+
- name: INSTALLATION_NAME
20+
value: bkup
21+
- name: WORKER_VALUES
22+
value: |
23+
resources:
24+
requests:
25+
cpu: 100m
26+
memory: 128Mi
27+
ephemeral-storage: 50Mi
28+
limits:
29+
cpu: 1000m
30+
memory: 512Mi
31+
ephemeral-storage: 2Gi
2432
- name: registry-auth-bkup
2533
serviceAccountName: bkup

templates_install/master.pod.latest.yaml

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,24 @@ spec:
1111
imagePullPolicy: Always
1212
env:
1313
- name: CLUSTER_NAME
14-
valueFrom:
15-
secretKeyRef:
16-
name: bkup-config
17-
key: cluster-name
18-
optional: false
14+
value: ${CLUSTER_NAME}
1915
- name: NAMESPACE
2016
valueFrom:
2117
fieldRef:
2218
fieldPath: metadata.namespace
19+
- name: INSTALLATION_NAME
20+
value: bkup
21+
- name: WORKER_VALUES
22+
value: |
23+
resources:
24+
requests:
25+
cpu: 100m
26+
memory: 128Mi
27+
ephemeral-storage: 50Mi
28+
limits:
29+
cpu: 1000m
30+
memory: 512Mi
31+
ephemeral-storage: 2Gi
2332
imagePullSecrets:
2433
- name: registry-auth-bkup
2534
serviceAccountName: bkup

0 commit comments

Comments
 (0)