import platform import os import logging from typing import Optional from kubernetes import client from kubernetes.client import Configuration from kubernetes.config.kube_config import KubeConfigLoader, KubeConfigMerger from kubernetes.client.exceptions import ApiException from kubernetes.config.incluster_config import ( InClusterConfigLoader, SERVICE_TOKEN_FILENAME, SERVICE_CERT_FILENAME, ) logger = logging.getLogger(__name__) def system() -> str: """ Get the current operating system name in lowercase. """ return platform.uname().system.lower() def native_arch() -> str: """ Get the native architecture of the machine in lowercase. """ return platform.machine().lower() _ARCH_ALIAS_MAPPING = { "x86_64": "amd64", "amd64": "amd64", "i386": "386", "i686": "386", "arm64": "arm64", "aarch64": "arm64", "armv7l": "arm", } def arch() -> str: """ Get the architecture of the machine in a standardized format. If the architecture is not recognized, return the native architecture. """ na = native_arch() return _ARCH_ALIAS_MAPPING.get(native_arch(), na) def system_arch() -> str: """ Get the system and architecture in the format "system/arch". """ return f"{system()}/{arch()}" def is_inside_kubernetes() -> bool: """ Check if the code is running inside a Kubernetes cluster. This is determined by the presence of specific environment variables and files. """ return os.getenv("KUBERNETES_SERVICE_HOST") is not None and os.path.exists( "/var/run/secrets/kubernetes.io/serviceaccount/token" ) def is_supported_higress( target_ingress_class: str = "higress", kubeconfig: Optional[str] = None ) -> bool: configuration = Configuration() if kubeconfig and os.path.exists(kubeconfig): cfg_loader = KubeConfigLoader(config_dict=KubeConfigMerger(kubeconfig).config) if not cfg_loader._load_user_token(): cfg_loader._load_user_pass_token() cfg_loader._load_cluster_info() cfg_loader._set_config(configuration) elif is_inside_kubernetes(): cfg_loader = InClusterConfigLoader( token_filename=SERVICE_TOKEN_FILENAME, cert_filename=SERVICE_CERT_FILENAME, ) cfg_loader.load_and_set(configuration) else: return False try: api_client = client.ApiClient(configuration=configuration) networking_client = client.NetworkingV1Api(api_client=api_client) if not target_ingress_class: return False networking_client.read_ingress_class(name=target_ingress_class) return True except ApiException as e: if e.status == 404: return False logger.debug(f"Error checking for {target_ingress_class} IngressClass: {e}") return False