import os import yaml import logging import time import subprocess from kubernetes import client, config # Configure logging logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') # Function to replace placeholders with values def replace_placeholders(data, placeholders): if 'spec' in data: if 'destination' in data['spec'] and 'namespace' in data['spec']['destination']: data['spec']['destination']['namespace'] = placeholders['spec']['destination']['namespace'] if 'project' in data['spec']: data['spec']['project'] = placeholders['spec']['project'] if 'source' in data['spec']: if 'path' in data['spec']['source']: parts = data['spec']['source']['path'].split('/') parts[0] = placeholders['spec']['source']['parentPath'] data['spec']['source']['path'] = '/'.join(parts) if 'repoURL' in data['spec']['source']: data['spec']['source']['repoURL'] = placeholders['spec']['source']['repoURL'] return data # Function to check the status of a pod def check_pod_status(namespace, pod_name): config.load_kube_config() v1 = client.CoreV1Api() try: pod = v1.read_namespaced_pod(name=pod_name, namespace=namespace) if pod.status.phase == "Running": logging.info(f"Pod {pod_name} is running.") ready_containers = 0 total_containers = len(pod.spec.containers) for container_status in pod.status.container_statuses: if container_status.ready: ready_containers += 1 if ready_containers == total_containers: logging.info(f"All containers in pod {pod_name} are ready ({ready_containers}/{total_containers}).") return True else: logging.info(f"Not all containers in pod {pod_name} are ready ({ready_containers}/{total_containers}).") return False else: logging.info(f"Pod {pod_name} is not running. Current status: {pod.status.phase}") return False except client.exceptions.ApiException as e: logging.error(f"Exception when calling CoreV1Api->read_namespaced_pod: {e}") return False # Function to apply YAML file and wait for pod status def apply_and_wait(file_path, placeholders): with open(file_path, 'r') as f: data = yaml.safe_load(f) data = replace_placeholders(data, placeholders) # Write the modified YAML to a temporary file temp_file = "temp_application.yaml" with open(temp_file, 'w') as f: yaml.dump(data, f) # Apply the YAML file logging.info(f"Applying YAML file: {file_path}") subprocess.run(["kubectl", "apply", "-f", temp_file], check=True) # Extract the pod name and namespace from the YAML pod_name = data['metadata']['name'] namespace = data['spec']['destination']['namespace'] # Wait for the pod to be ready logging.info(f"Waiting for pod {pod_name} in namespace {namespace} to be ready...") while not check_pod_status(namespace, pod_name): time.sleep(10) # Wait for 10 seconds before checking again logging.info(f"Pod {pod_name} is ready. Proceeding to the next file.") # Save the modified YAML to the specified directory save_dir = os.path.expanduser('~/Configurations/ApplicationControl/') os.makedirs(save_dir, exist_ok=True) save_path = os.path.join(save_dir, os.path.basename(file_path)) with open(save_path, 'w') as f: yaml.dump(data, f) # Clean up the temporary file os.remove(temp_file) # Load the placeholders from placeholders.yaml with open('placeholders.yaml', 'r') as f: placeholders = yaml.safe_load(f) # Iterate through files inside the 01, 02, 03, 04 dirs and apply the application control YAMLs in the cluster # The script waits until the pod is ready in each iteration for dir in sorted(os.listdir(".")): if not os.path.isdir(dir): continue if not dir.startswith("0"): continue if dir.startswith("05"): continue for file in sorted(os.listdir(dir)): if not file.endswith(".yaml") and not file.endswith(".yml"): continue file_path = os.path.join(dir, file) apply_and_wait(file_path, placeholders) # Iterate through files inside the 05 dir and apply the application control YAMLs in the cluster # The script does not need to wait until the pod is ready in each iteration for file in sorted(os.listdir("05")): if not file.endswith(".yaml") and not file.endswith(".yml"): continue file_path = os.path.join("05", file) with open(file_path, 'r') as f: data = yaml.safe_load(f) data = replace_placeholders(data, placeholders) # Write the modified YAML to a temporary file temp_file = "temp_application.yaml" with open(temp_file, 'w') as f: yaml.dump(data, f) # Apply the YAML file logging.info(f"Applying YAML file: {file_path}") subprocess.run(["kubectl", "apply", "-f", temp_file], check=True) # Save the modified YAML to the specified directory save_dir = os.path.expanduser('~/Configurations/ApplicationControl/') os.makedirs(save_dir, exist_ok=True) save_path = os.path.join(save_dir, os.path.basename(file_path)) with open(save_path, 'w') as f: yaml.dump(data, f) # Clean up the temporary file os.remove(temp_file)