Ejemplo n.º 1
0
 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()
Ejemplo n.º 2
0
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)
Ejemplo n.º 3
0
 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)
Ejemplo n.º 4
0
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
Ejemplo n.º 5
0
    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()
Ejemplo n.º 6
0
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)
Ejemplo n.º 7
0
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)
Ejemplo n.º 8
0
 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()
Ejemplo n.º 9
0
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
Ejemplo n.º 10
0
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))
Ejemplo n.º 11
0
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
Ejemplo n.º 12
0
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)
Ejemplo n.º 13
0
 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()
Ejemplo n.º 14
0
    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()
Ejemplo n.º 15
0
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.")
Ejemplo n.º 16
0
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)
Ejemplo n.º 17
0
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))
Ejemplo n.º 18
0
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
Ejemplo n.º 20
0
 def __init__(self):
     self.core = client.CoreV1Api()
     self.certs = client.CertificatesV1beta1Api()
     self.rbac = client.RbacAuthorizationV1Api()
     self.settings_api = client.SettingsV1alpha1Api()
     self.policy = client.PolicyV1beta1Api()
Ejemplo n.º 21
0
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"
            }
Ejemplo n.º 22
0
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")
Ejemplo n.º 23
0
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")