def __init__(self): config.load_kube_config() self.K8SAppsV1Client = client.AppsV1Api() self.K8SCoreV1Client = client.CoreV1Api() self.K8SStorageV1Client = client.StorageV1Api() self.K8SRbacAuthorizationV1Client = client.RbacAuthorizationV1Api() self.K8SPolicyV1beta1Client = client.PolicyV1beta1Api()
def delete_pdb(pdb_name, pdb_namespace): """deleting the specified pod disruption budget""" poly_client = client.PolicyV1beta1Api() # TODO: handle failing api request api_response = poly_client.delete_namespaced_pod_disruption_budget( pdb_name, pdb_namespace) print(api_response)
def _detect_api_object(self, api_version): # Due to https://github.com/kubernetes-client/python/issues/387 if api_version == 'apps/v1beta1': return client.AppsV1beta1Api() if api_version == 'v1': return client.CoreV1Api() if api_version == 'extensions/v1beta1': return client.ExtensionsV1beta1Api() if api_version == 'batch/v1': return client.BatchV1Api() if api_version == 'batch/v2alpha1': return client.BatchV2alpha1Api() if api_version == 'batch/v1beta1': return client.BatchV1beta1Api() if api_version == 'policy/v1beta1': return client.PolicyV1beta1Api() if api_version == 'storage.k8s.io/v1': return client.StorageV1Api() if api_version == 'apps/v1': return client.AppsV1Api() if api_version == 'autoscaling/v1': return client.AutoscalingV1Api() if api_version == 'rbac.authorization.k8s.io/v1': return client.RbacAuthorizationV1Api() if api_version == 'scheduling.k8s.io/v1alpha1': return client.SchedulingV1alpha1Api() if api_version == 'scheduling.k8s.io/v1beta1': return client.SchedulingV1beta1Api() if api_version == 'test/test': return K8sClientMock(self.name)
def create_kube_apiserver_instance_client(cluster_url,service_account_secret,node_type): """ Kubernetes library have several core kinds for getting data with cluster api server. For each Object type we have different core and we should use those function to get correct and reliable result. create_kube_apiserver_instance_client function pass core instance due to node type. """ node_type=node_type.lower() configuration = kubernetes.client.Configuration() token = '%s' % (service_account_secret) configuration.api_key={"authorization":"Bearer "+ token} configuration.host = cluster_url configuration.verify_ssl=False configuration.debug = False client.Configuration.set_default(configuration) if node_type in ["pod","service","serviceaccount"]: api_client = client.CoreV1Api() if node_type in ["deployment","replicaset"]: api_client = client.AppsV1Api() if node_type in ["networkpolicy"]: api_client = client.NetworkingV1Api() if node_type in ["podsecuritypolicy"]: api_client = client.PolicyV1beta1Api() if node_type in ["rolebinding","role","clusterrole","clusterrolebinding"]: api_client = client.RbacAuthorizationV1beta1Api() return api_client
def __init__(self, namespace, config): """Initializes the Kafka manager Loads the Kubernetes resource definitions from the yml files into the instance and then configures those resources based on the provided config Args: config - Configuration options for the Kafka resources in the cluster; dict namespace - Namespace to deploy the Kafka resources into; string """ with open("kafka.yml") as f: kafka_yml = list(safe_load_all(f)) self.kafka_service = kafka_yml[0] self.kafka_pdb = kafka_yml[1] self.kafka = kafka_yml[2] self.kafka_metrics_service = kafka_yml[3] self.kafka_metrics = kafka_yml[4] self.kafka_pvc = kafka_yml[5] self.__config = config self.__namespace = namespace self.__v1_api = client.CoreV1Api() self.__v1_policy_api = client.PolicyV1beta1Api() self.__v1_apps_api = client.AppsV1Api() self.__configure_kafka()
def confirm_pod_security_policy(context): if context is None: raise SystemExit("invalid empty context for PodSecurityPolicy given") load_kube(context) api = client.PolicyV1beta1Api() return general_confirm("PodSecurityPolicy", lambda: api.list_pod_security_policy(), lambda i: i.metadata.name)
def remove_pod_security_policy(context, name): if context is None: raise SystemExit("invalid empty context for PodSecurityPolicy given") if name is None: raise SystemExit("invalid empty name for PodSecurityPolicy given") load_kube(context) api = client.PolicyV1beta1Api() ret, status, _ = api.delete_pod_security_policy_with_http_info(name) handle_status(ret, status, "PodSecurityPolicy", None, name)
def __init__(self) -> None: kube_config.load_kube_config(config_file='/etc/kubernetes/admin.conf') models.V1beta1PodDisruptionBudgetStatus.disrupted_pods = property( fget=lambda *args, **kwargs: models. V1beta1PodDisruptionBudgetStatus.disrupted_pods(*args, **kwargs), fset=_set_disrupted_pods, ) self.deployments = kube_client.AppsV1Api() self.core = kube_client.CoreV1Api() self.policy = kube_client.PolicyV1beta1Api()
def get_pdbs(label_selector): """get_pdb returns all pod disruptino budgets from all namespaces""" print('geeting pdbs with labesl', label_selector) poly_client = client.PolicyV1beta1Api() pdbs = [] # TODO: handle failing api request raw_pdbs = poly_client.list_pod_disruption_budget_for_all_namespaces( label_selector=label_selector) for pdb in raw_pdbs.items: pdbs.append(pdb.to_dict()) return pdbs
def wait_for_pod_security_policy_is_up(context, name): if name is None: raise SystemExit("invalid empty name for PodSecurityPolicy given") if context is None: raise SystemExit("invalid empty name context given") load_kube(context) print("check availability of", "PodSecurityPolicy", name) api = client.PolicyV1beta1Api() return general_up_check( None, "PodSecurityPolicy", name, lambda: api.read_pod_security_policy_with_http_info(name))
def create_pod_security_policy_with_api(namespace): """Create pod security policy.""" # Using the API because of LP:1886694 logging.info('Creating pod security policy with K8s API') _load_kube_config() metadata = client.V1ObjectMeta( namespace=namespace, name='controller', labels={'app': 'metallb'} ) policy_spec = client.PolicyV1beta1PodSecurityPolicySpec( allow_privilege_escalation=False, default_allow_privilege_escalation=False, fs_group=client.PolicyV1beta1FSGroupStrategyOptions( ranges=[client.PolicyV1beta1IDRange(max=65535, min=1)], rule='MustRunAs' ), host_ipc=False, host_network=False, host_pid=False, privileged=False, read_only_root_filesystem=True, required_drop_capabilities=['ALL'], run_as_user=client.PolicyV1beta1RunAsUserStrategyOptions( ranges=[client.PolicyV1beta1IDRange(max=65535, min=1)], rule='MustRunAs' ), se_linux=client.PolicyV1beta1SELinuxStrategyOptions( rule='RunAsAny', ), supplemental_groups=client.PolicyV1beta1SupplementalGroupsStrategyOptions( ranges=[client.PolicyV1beta1IDRange(max=65535, min=1)], rule='MustRunAs' ), volumes=['configMap', 'secret', 'emptyDir'], ) body = client.PolicyV1beta1PodSecurityPolicy(metadata=metadata, spec=policy_spec) with client.ApiClient() as api_client: api_instance = client.PolicyV1beta1Api(api_client) try: api_instance.create_pod_security_policy(body, pretty=True) return True except ApiException as err: logging.exception("Exception when calling PolicyV1beta1Api" "->create_pod_security_policy.") if err.status != 409: # ignoring 409 (AlreadyExists) errors return False else: return True
def confirm_pod_disruption_budget(context, namespace): if context is None: raise SystemExit("invalid empty context for PodDisruptionBudget given") if namespace is None: raise SystemExit( "invalid empty namespace for PodDisruptionBudget given") load_kube(context) api = client.PolicyV1beta1Api() return general_confirm( "PodDisruptionBudget", lambda: api.list_namespaced_pod_disruption_budget(namespace), lambda i: i.metadata.name)
def __init__(self) -> None: kube_config.load_kube_config(config_file=os.environ.get( 'KUBECONFIG', KUBE_CONFIG_PATH), ) models.V1beta1PodDisruptionBudgetStatus.disrupted_pods = property( fget=lambda *args, **kwargs: models. V1beta1PodDisruptionBudgetStatus.disrupted_pods(*args, **kwargs), fset=_set_disrupted_pods, ) self.deployments = kube_client.AppsV1Api() self.core = kube_client.CoreV1Api() self.policy = kube_client.PolicyV1beta1Api() self.apiextensions = kube_client.ApiextensionsV1beta1Api() self.custom = kube_client.CustomObjectsApi()
def __init__(self): # https://github.com/kubernetes-client/python/issues/309 warnings.simplefilter("ignore", ResourceWarning) self.config = config.load_kube_config() self.k8s_client = client.ApiClient() self.core_v1 = client.CoreV1Api() self.apps_v1 = client.AppsV1Api() self.batch_v1_beta1 = client.BatchV1beta1Api() self.custom_objects_api = client.CustomObjectsApi() self.policy_v1_beta1 = client.PolicyV1beta1Api()
def delete_pod_security_policy_with_api(name): """Delete pod security policy.""" logging.info('Deleting pod security policy named "controller" with K8s API') _load_kube_config() body = client.V1DeleteOptions() with client.ApiClient() as api_client: api_instance = client.PolicyV1beta1Api(api_client) try: api_instance.delete_pod_security_policy(name=name, body=body, pretty=True) return True except ApiException: logging.exception("Exception when calling PolicyV1beta1Api" "->delete_pod_security_policy.")
def remove_pod_disruption_budget(context, namespace, name): if context is None: raise SystemExit("invalid empty context for PodDisruptionBudget given") if namespace is None: raise SystemExit( "invalid empty namespace for PodDisruptionBudget given") if name is None: raise SystemExit("invalid empty name for PodDisruptionBudget given") load_kube(context) api = client.PolicyV1beta1Api() ret, status, _ = api.delete_namespaced_pod_disruption_budget_with_http_info( name, namespace=namespace) handle_status(ret, status, "PodDisruptionBudget", namespace, name)
def wait_for_pod_disruption_budget_is_up(context, namespace, name): if name is None: raise SystemExit("invalid empty name for PodDisruptionBudget given") if context is None: raise SystemExit("invalid empty name context given") if namespace is None: raise SystemExit("invalid empty name namespace given") load_kube(context) print("check availability of", "PodDisruptionBudget", name, "in namespace", namespace) api = client.PolicyV1beta1Api() return general_up_check( namespace, "PodDisruptionBudget", name, lambda: api.read_namespaced_pod_disruption_budget_with_http_info( name, namespace=namespace))
def create_pdb(pdb_namespace, pdb): """creaing the pod disruption budget in the specified namespace""" poly_client = client.PolicyV1beta1Api() # TODO: handle complete selector object selector = client.models.v1_label_selector.V1LabelSelector( match_labels=pdb['spec']['selector']['match_labels']) # TODO: handle complete spec object spec = client.models.v1beta1_pod_disruption_budget_spec.V1beta1PodDisruptionBudgetSpec( selector=selector, min_available=pdb['spec']['min_available']) # TODO: maybe use real metadata object instead of trusting dict serialisation body = client.models.v1beta1_pod_disruption_budget.V1beta1PodDisruptionBudget( spec=spec, metadata=pdb['metadata']) # TODO: handle failing api request api_response = poly_client.create_namespaced_pod_disruption_budget( pdb_namespace, body) print(api_response)
def crud_pod_security_policy_with_api(namespace, psp, action): """Create pod security policy.""" # Using the API because of LP:1886694 logging.info("Creating pod security policy with K8s API") _load_kube_config() body = client.ExtensionsV1beta1PodSecurityPolicy(**psp) with client.ApiClient() as api_client: api_instance = client.PolicyV1beta1Api(api_client) try: if action.lower() == "create": api_instance.create_pod_security_policy(body, pretty=True) elif action.lower() == "delete": api_instance.delete_pod_security_policy( name=psp["metadata"]["name"], pretty=True) except ApiException as err: if err.status == 409: # ignore "already exists" errors so that we can recover from # partially failed setups return else: raise
def __init__(self): self.core = client.CoreV1Api() self.certs = client.CertificatesV1beta1Api() self.rbac = client.RbacAuthorizationV1Api() self.settings_api = client.SettingsV1alpha1Api() self.policy = client.PolicyV1beta1Api()
from kubernetes import client, config config.load_kube_config(os.getenv('KUBECONFIG')) configuration = kubernetes.client.Configuration() # Configure API key authorization: BearerToken configuration.assert_hostname = False # Uncomment below to setup prefix (e.g. Bearer) for API key, if needed # configuration.api_key_prefix['authorization'] = 'Bearer' # Defining host is optional and default to http://localhost configuration.host = "http://localhost" # Enter a context with an instance of the API kubernetes.client with kubernetes.client.ApiClient(configuration) as api_client: # Create an instance of the API class api_instance = client.PolicyV1beta1Api() body = kubernetes.client.PolicyV1beta1PodSecurityPolicy( metadata={'name': "holi"}, spec={ "runAsUser": { "rule": "RunAsAny" }, "seLinux": { "rule": "RunAsAny" }, "supplementalGroups": { "rule": "RunAsAny" }, "fsGroup": { "rule": "RunAsAny" }
async def create_chaos_experiment( meta: ResourceChunk, body: Dict[str, Any], spec: ResourceChunk, namespace: str, logger: logging.Logger, **kwargs) -> NoReturn: """ Create a new pod running a Chaos Toolkit instance until it terminates. """ v1 = client.CoreV1Api() v1rbac = client.RbacAuthorizationV1Api() v1policy = client.PolicyV1beta1Api() cm = await get_config_map(v1, spec, namespace) psp = await get_default_psp(v1policy) keep_resources_on_delete = spec.get("keep_resources_on_delete", False) if keep_resources_on_delete: logger.info("Resources will be kept even when the CRO is deleted") ns, ns_tpl = await create_ns(v1, cm, spec) if ns_tpl: if not keep_resources_on_delete: kopf.adopt(ns_tpl, owner=body) await update_namespace(v1, ns, ns_tpl) logger.info(f"chaostoolkit resources will be created in namespace '{ns}'") name_suffix = generate_name_suffix() logger.info(f"Suffix for resource names will be '-{name_suffix}'") sa_tpl = await create_sa(v1, cm, spec, ns, name_suffix) if sa_tpl: if not keep_resources_on_delete: kopf.adopt(sa_tpl, owner=body) await update_sa(v1, ns, sa_tpl) logger.info(f"Created service account") role_tpl = await create_role( v1rbac, cm, spec, ns, name_suffix, psp=psp) if role_tpl: if not keep_resources_on_delete: kopf.adopt(role_tpl, owner=body) await update_role(v1rbac, ns, role_tpl) logger.info(f"Created role") role_binding_tpl = await create_role_binding( v1rbac, cm, spec, ns, name_suffix) if role_binding_tpl: if not keep_resources_on_delete: kopf.adopt(role_binding_tpl, owner=body) await update_role_binding(v1rbac, ns, role_binding_tpl) logger.info(f"Created rolebinding") cm_tpl = await create_experiment_env_config_map( v1, ns, spec.get("pod", {}).get("env", {}).get( "configMapName", "chaostoolkit-env")) if cm_tpl: if not keep_resources_on_delete: kopf.adopt(cm_tpl, owner=body) await update_config_map(v1, ns, cm_tpl) logger.info(f"Created experiment's env vars configmap") pod_tpl = await create_pod(v1, cm, spec, ns, name_suffix, meta) if pod_tpl: if not keep_resources_on_delete: kopf.adopt(pod_tpl, owner=body) await update_pod(v1, ns, pod_tpl) logger.info("Chaos Toolkit started")
async def create_chaos_experiment(meta: ResourceChunk, body: Dict[str, Any], spec: ResourceChunk, namespace: str, logger: logging.Logger, **kwargs) -> NoReturn: """ Create a new pod running a Chaos Toolkit instance until it terminates. If experiment is scheduled, create a new cronJob that will periodically create a Chaos Toolkit instance. """ v1 = client.CoreV1Api() v1rbac = client.RbacAuthorizationV1Api() v1policy = client.PolicyV1beta1Api() v1cron = client.BatchV1beta1Api() cm = await get_config_map(v1, spec, namespace) psp = await get_default_psp(v1policy) keep_resources_on_delete = spec.get("keep_resources_on_delete", False) if keep_resources_on_delete: logger.info("Resources will be kept even when the CRO is deleted") ns, ns_tpl = await create_ns(v1, cm, spec) if ns_tpl: if not keep_resources_on_delete: kopf.adopt(ns_tpl, owner=body) await update_namespace(v1, ns, ns_tpl) logger.info(f"chaostoolkit resources will be created in namespace '{ns}'") name_suffix = generate_name_suffix() logger.info(f"Suffix for resource names will be '-{name_suffix}'") sa_tpl = await create_sa(v1, cm, spec, ns, name_suffix) if sa_tpl: if not keep_resources_on_delete: kopf.adopt(sa_tpl, owner=body) await update_sa(v1, ns, sa_tpl) logger.info(f"Created service account") role_tpl = await create_role(v1rbac, cm, spec, ns, name_suffix, psp=psp) if role_tpl: if not keep_resources_on_delete: kopf.adopt(role_tpl, owner=body) logger.info(f"Created role") role_binding_tpl = await create_role_binding(v1rbac, cm, spec, ns, name_suffix) if role_binding_tpl: if not keep_resources_on_delete: kopf.adopt(role_binding_tpl, owner=body) await update_role_binding(v1rbac, ns, role_binding_tpl) logger.info(f"Created rolebinding") cm_tpl = await create_experiment_env_config_map( v1, ns, spec.get("pod", {}).get("env", {}).get("configMapName", "chaostoolkit-env")) if cm_tpl: if not keep_resources_on_delete: kopf.adopt(cm_tpl, owner=body) await update_config_map(v1, ns, cm_tpl) logger.info(f"Created experiment's env vars configmap") schedule = spec.get("schedule", {}) if schedule: if schedule.get('kind').lower() == 'cronjob': # when schedule defined, we cannot create the pod directly, # we must create a cronJob with the pod definition pod_tpl = await create_pod(v1, cm, spec, ns, name_suffix, meta, apply=False) if pod_tpl: cron_tpl = await create_cron_job(v1cron, cm, spec, ns, name_suffix, meta, pod_tpl=pod_tpl) if cron_tpl: if not keep_resources_on_delete: kopf.adopt(cron_tpl, owner=body) await update_cron_job(v1cron, ns, cron_tpl) logger.info("Chaos Toolkit scheduled") else: # create pod for running experiment right away pod_tpl = await create_pod(v1, cm, spec, ns, name_suffix, meta) if pod_tpl: if not keep_resources_on_delete: kopf.adopt(pod_tpl, owner=body) await update_pod(v1, ns, pod_tpl) logger.info("Chaos Toolkit started")