def state_cluster(api_client=None): """ List component of cluster. This is a main component of the input for the controller """ load_kubernetes_config() api = kubernetes.client.CustomObjectsApi(api_client=api_client) group = "kubeinit.org" version = "v1alpha1" namespace = "pystol" plural = "pystolactions" pretty = 'true' ret = [] try: resp = api.list_namespaced_custom_object(group=group, version=version, namespace=namespace, plural=plural, pretty=pretty) for action in resp['items']: ret.append({'name': action['metadata']['name'], 'creationTimestamp': action['metadata']['creationTimestamp'], 'action_state': action['spec']['action_state'], 'workflow_state': action['spec']['workflow_state']}) except Exception: print("No objects found...") return ret
def state_pods(api_client=None): """ Return pods. This returns some pod data """ data_pods = [] try: load_kubernetes_config() core_v1 = kubernetes.client.CoreV1Api(api_client=api_client) pods = core_v1.list_pod_for_all_namespaces().items except Exception as e: print("Cant connect to the cluster: %s" % (e)) return [] for pod in pods: data_pods.append({ 'name': pod.metadata.name, 'namespace': pod.metadata.namespace, 'host_ip': pod.status.host_ip, 'pod_ip': pod.status.pod_ip, 'phase': pod.status.phase }) return data_pods
def list_actions(): """ List Pystol actions from the cluster. This is a main component of the input for the controller """ load_kubernetes_config() api = kubernetes.client.CustomObjectsApi() group = "pystol.org" version = "v1alpha1" namespace = "pystol" plural = "pystolactions" pretty = 'true' x = PrettyTable() x.field_names = ["Name", "Creation", "Action state", "Workflow state"] try: resp = api.list_namespaced_custom_object(group=group, version=version, namespace=namespace, plural=plural, pretty=pretty) for action in resp['items']: x.add_row([ action['metadata']['name'], action['metadata']['creationTimestamp'], action['spec']['action_state'], action['spec']['workflow_state'] ]) except ApiException: print("No objects found...") print(x)
def cluster_name_configured(api_client=None): """ Get the current cluster name. This method should return the cluster name """ cluster_name = "Not found" load_kubernetes_config() core_v1 = kubernetes.client.CoreV1Api(api_client=api_client) try: # OpenShift case cd = core_v1.read_namespaced_config_map(name='cluster-config-v1', namespace='kube-system', pretty='true') if cd: # This will have a big yaml file # we need to convert to a dict raw = cd.data["install-config"] # We get the YAML from the data field of the configmap # And fetch the value we need cluster_name = yaml.safe_load(raw)["metadata"]["name"] print("Cluster name computed from OpenShift case") return cluster_name except Exception: print("Cant find clustername for OpenShift case") try: if api_client.configuration.host is not None: return urlparse(api_client.configuration.host).hostname except Exception: print("Cant find the clustername in the config object") # If we dont manage to find it we fall back to the CLI as a last resource try: command = 'kubectl config view -o jsonpath="{.clusters[].name}"' output = subprocess.check_output(command, stderr=subprocess.STDOUT, shell=True) print(output) return output.decode('utf-8') except Exception: print("Cant find the clustername at all") return cluster_name
def state_namespaces(api_client=None): """ Return namespaces. This returns some namespace data """ datanamespaces = [] try: load_kubernetes_config() core_v1 = kubernetes.client.CoreV1Api(api_client=api_client) namespaces = core_v1.list_namespace().items except Exception as e: print("Cant connect to the cluster: %s" % (e)) return [] for namespace in namespaces: datanamespaces.append({'name': namespace.metadata.name, 'status': namespace.status.phase}) return datanamespaces
def hexagons_data(api_client=None): """ Get the hexagons data for the index. This method fetch the data for the index """ hexa_data = [] load_kubernetes_config() core_v1 = kubernetes.client.CoreV1Api(api_client=api_client) try: nodes_list = core_v1.list_node().items except Exception: print("Error listing nodes") nodes_list = [] for node in nodes_list: node_name = node.metadata.name node_labels = node.metadata.labels if "node-role.kubernetes.io/master" in node_labels: if node_labels['node-role.kubernetes.io/master'] == 'true': node_role = "Master" else: node_role = "Non master" else: node_role = "Non master" allocatable = node.status.allocatable node_info = node.status.node_info hdata = {} hdata['name'] = node_name hdata['role'] = node_role hdata['cpu'] = allocatable["cpu"] if 'ephemeral-storage' in allocatable: hdata['ephstorage'] = allocatable["ephemeral-storage"] else: hdata['ephstorage'] = 0 hdata['mem'] = allocatable["memory"] hdata['maxpods'] = allocatable["pods"] hdata['arch'] = node_info.architecture hdata['crver'] = node_info.container_runtime_version hdata['kernelver'] = node_info.kernel_version hdata['kubeproxyver'] = node_info.kube_proxy_version hdata['kubeletver'] = node_info.kubelet_version hdata['os'] = node_info.operating_system state_info = compute_node_resources( node_name=node_name, api_client=api_client) hdata['state_info'] = state_info max_pods = int(int(allocatable["pods"]) * 1.5) field_selector = ("spec.nodeName=" + node_name) pods = core_v1.list_pod_for_all_namespaces(limit=max_pods, field_selector=field_selector).items hdata['pods'] = [] for pod in pods: hdata['pods'].append({'name': pod.metadata.name, 'namespace': pod.metadata.namespace, 'host_ip': pod.status.host_ip, 'pod_ip': pod.status.pod_ip, 'phase': pod.status.phase}) hexa_data.append(hdata) return hexa_data
def deploy_pystol(api_client=None): """ Install Pystol from Python. This is a main component of the input for the controller """ load_kubernetes_config() v1 = kubernetes.client.CoreV1Api(api_client=api_client) deployment = kubernetes.client.AppsV1Api(api_client=api_client) rbac = kubernetes.client.RbacAuthorizationV1Api(api_client=api_client) if api_client == None: apicli = kubernetes.client.ApiClient() else: apicli = api_client with open( os.path.join(os.path.dirname(__file__), "templates/latest/pystol.upstreamvalues.yaml")) as f: values = yaml.safe_load(f) with open( os.path.join(os.path.dirname(__file__), "templates/latest/pystol.namespace.yaml")) as f: try: resp = v1.create_namespace(body=yaml.safe_load(f)) print(" " + u"\U0001F4E6" + " Namespace created.") print(" '%s'" % resp.metadata.name) except ApiException: print(" " + u"\u2757" + " Namespace creation warning.") print(" Maybe it is already created.") ''' with open(os.path.join(os.path.dirname(__file__), "templates/latest/pystol.configmap.yaml.j2")) as f: template = Template(f.read()) cm = template.render(values) try: resp = v1.create_namespaced_config_map( body=yaml.safe_load(cm), namespace="pystol") print(" " + u"\U0001F4E6" + " Config map created.") print(" '%s'" % resp.metadata.name) except ApiException: print(" " + u"\u2757" + " Config map creation warning.") print(" Maybe it is already created.") ''' try: resp = kubernetes.utils.create_from_yaml( k8s_client=apicli, yaml_file=os.path.join(os.path.dirname(__file__), "templates/latest/pystol.crd.yaml"), namespace="pystol") print(" " + u"\U0001F4E6" + " CRD created.") print(" '%s'" % resp.metadata.name) except FailToCreateError: print(" " + u"\u2757" + " CRD creation warning.") print(" Maybe it is already created.") except Exception: print(" " + u"\U0001F4E6" + " CRD created.") print(" We need to wait for a permanent fix, until then...") print(" https://github.com/kubernetes-client/python/issues/1022") # print("CRD problem - ApiClient->create_from_yaml: %s\n" % e) # print("The CRD was created but an exception is raised") # print("Other error, see:") # print("https://github.com/kubernetes-client/python/issues/1022") with open( os.path.join(os.path.dirname(__file__), "templates/latest/pystol.serviceaccount.yaml")) as f: try: resp = v1.create_namespaced_service_account(namespace="pystol", body=yaml.safe_load(f)) print(" " + u"\U0001F4E6" + " Service account created.") print(" '%s'" % resp.metadata.name) except ApiException: print(" " + u"\u2757" + " Service account creation warning.") print(" Maybe it is already created.") with open( os.path.join(os.path.dirname(__file__), "templates/latest/pystol.clusterrole.yaml")) as f: try: resp = rbac.create_cluster_role(body=yaml.safe_load(f)) print(" " + u"\U0001F4E6" + " Role created.") print(" '%s'" % resp.metadata.name) except ApiException: print(" " + u"\u2757" + " Role creation warning.") print(" Maybe it is already created.") with open( os.path.join( os.path.dirname(__file__), "templates/latest/pystol.clusterrolebinding.yaml")) as f: try: resp = rbac.create_cluster_role_binding(body=yaml.safe_load(f)) print(" " + u"\U0001F4E6" + " Cluster role bindings created.") print(" '%s'" % resp.metadata.name) except ApiException: print(" " + u"\u2757" + " Cluster role binding creation warning.") print(" Maybe it is already created.") with open( os.path.join(os.path.dirname(__file__), "templates/latest/pystol.controller.yaml.j2")) as f: template = Template(f.read()) rendered_deployment = template.render(values) try: resp = deployment.create_namespaced_deployment( body=yaml.safe_load(rendered_deployment), namespace="pystol") print(" " + u"\U0001F4E6" + " Operator deployment created.") print(" '%s'" % resp.metadata.name) except ApiException: print(" " + u"\u2757" + " Operator deployment creation warning.") print(" Maybe it is already created.") with open( os.path.join(os.path.dirname(__file__), "templates/latest/pystol.ui.yaml.j2")) as f: template = Template(f.read()) rendered_deployment = template.render(values) try: resp = deployment.create_namespaced_deployment( body=yaml.safe_load(rendered_deployment), namespace="pystol") print(" " + u"\U0001F4E6" + " UI operator created.") print(" '%s'" % resp.metadata.name) except ApiException: print(" " + u"\u2757" + " UI deployment creation warning.") print(" Maybe it is already created.") with open( os.path.join(os.path.dirname(__file__), "templates/latest/pystol.service.yaml")) as f: try: resp = v1.create_namespaced_service(namespace="pystol", body=yaml.safe_load(f)) print(" " + u"\U0001F4E6" + " Service created.") print(" '%s'" % resp.metadata.name) except ApiException: print(" " + u"\u2757" + " Service creation warning.") print(" Maybe it is already created.")
def compute_allocated_resources(api_client=None): """ Get the allocated resources. This will get the cluster resources usage """ load_kubernetes_config() core_v1 = kubernetes.client.CoreV1Api(api_client=api_client) s_i = {'pods': {'allocatable': Q_('0 pods'), 'allocated': Q_('0 pods'), 'percentage': 0}, 'cpu': {'allocatable': Q_('0 m'), 'allocated': Q_('0 m'), 'percentage': 0}, 'mem': {'allocatable': Q_('0 Ki'), 'allocated': Q_('0 Ki'), 'percentage': 0}, 'storage': {'allocatable': Q_('0 Ki'), 'allocated': Q_('0 Ki'), 'percentage': 0}} try: nodes_list = core_v1.list_node().items except Exception as e: print("Something bad happened: %s" % (e)) return {'pods': {'allocatable': Q_('0 pods'), 'allocated': Q_('0 pods'), 'percentage': 0}, 'cpu': {'allocatable': Q_('0 m'), 'allocated': Q_('0 m'), 'percentage': 0}, 'mem': {'allocatable': Q_('0 Ki'), 'allocated': Q_('0 Ki'), 'percentage': 0}, 'storage': {'allocatable': Q_('0 Ki'), 'allocated': Q_('0 Ki'), 'percentage': 0}} for node in nodes_list: node_name = node.metadata.name node_stats = compute_node_resources( node_name=node_name, api_client=api_client) s_i['pods']['allocatable'] = (s_i['pods']['allocatable'] + node_stats['pods']['allocatable']) s_i['pods']['allocated'] = (s_i['pods']['allocated'] + node_stats['pods']['allocated']) s_i['cpu']['allocatable'] = (s_i['cpu']['allocatable'] + node_stats['cpu']['allocatable']) s_i['cpu']['allocated'] = (s_i['cpu']['allocated'] + node_stats['cpu']['allocated']) s_i['mem']['allocatable'] = (s_i['mem']['allocatable'] + node_stats['mem']['allocatable']) s_i['mem']['allocated'] = (s_i['mem']['allocated'] + node_stats['mem']['allocated']) s_i['storage']['allocatable'] = (s_i['storage']['allocatable'] + node_stats['storage']['allocatable']) s_i['storage']['allocated'] = (s_i['storage']['allocated'] + node_stats['storage']['allocated']) if int(s_i['pods']['allocatable'].magnitude) == 0: s_i['pods']['percentage'] = 0 else: s_i['pods']['percentage'] = ( (int(s_i['pods']['allocated'].magnitude) * 100) // (int(s_i['pods']['allocatable'].magnitude))) if int(s_i['cpu']['allocatable'].magnitude) == 0: s_i['cpu']['percentage'] = 0 else: s_i['cpu']['percentage'] = ( (int(s_i['cpu']['allocated'].magnitude) * 100) // (int(s_i['cpu']['allocatable'].magnitude))) if int(s_i['mem']['allocatable'].magnitude) == 0: s_i['mem']['percentage'] = 0 else: s_i['mem']['percentage'] = ( (int(s_i['mem']['allocated'].magnitude) * 100) // (int(s_i['mem']['allocatable'].magnitude))) if int(s_i['storage']['allocatable'].magnitude) == 0: s_i['storage']['percentage'] = 0 else: s_i['storage']['percentage'] = ( (int(s_i['storage']['allocated'].magnitude) * 100) // (int(s_i['storage']['allocatable'].magnitude))) return s_i
def compute_node_resources(node_name=None, api_client=None): """ Get the node allocated resources. This will get the node resources usage """ load_kubernetes_config() core_v1 = kubernetes.client.CoreV1Api(api_client=api_client) s_i = {'pods': {'allocatable': Q_('0 pods'), 'allocated': Q_('0 pods'), 'percentage': 0}, 'cpu': {'allocatable': Q_('0 m'), 'allocated': Q_('0 m'), 'percentage': 0}, 'mem': {'allocatable': Q_('0 Ki'), 'allocated': Q_('0 Ki'), 'percentage': 0}, 'storage': {'allocatable': Q_('0 Ki'), 'allocated': Q_('0 Ki'), 'percentage': 0}} field_selector = ("metadata.name=" + node_name) try: node = core_v1.list_node( field_selector=field_selector).items[0] except Exception as e: print("Something bad happened: %s" % (e)) node_name = node.metadata.name allocatable = node.status.allocatable max_pods = int(int(allocatable["pods"]) * 1.5) field_selector = ("status.phase!=Succeeded,status.phase!=Failed," + "spec.nodeName=" + node_name) if 'cpu' in allocatable: cpu_allocatable = Q_(allocatable["cpu"]) cpu_allocatable.ito(ureg.m) s_i["cpu"]["allocatable"] = cpu_allocatable if 'memory' in allocatable: mem_allocatable = Q_(allocatable["memory"]) mem_allocatable.ito(ureg.Mi) s_i["mem"]["allocatable"] = mem_allocatable if 'ephemeral-storage' in allocatable: storage_allocatable = Q_(allocatable["ephemeral-storage"]) storage_allocatable.ito(ureg.Mi) s_i["storage"]["allocatable"] = storage_allocatable s_i["pods"]["allocatable"] = max_pods * ureg.pods pods = core_v1.list_pod_for_all_namespaces(limit=max_pods, field_selector=field_selector).items s_i["pods"]["allocated"] = len(pods) * ureg.pods # compute the allocated resources cpureqs, memreqs, storagereqs = [], [], [] # cpulmts, memlmts, storagelmts = [], [], [] for pod in pods: for container in pod.spec.containers: res = container.resources reqs = defaultdict(lambda: 0, res.requests or {}) # lmts = defaultdict(lambda: 0, res.limits or {}) cpureqs.append(Q_(reqs["cpu"])) memreqs.append(Q_(reqs["memory"])) storagereqs.append(Q_(reqs["ephemeral-storage"])) # cpulmts.append(Q_(lmts["cpu"])) # memlmts.append(Q_(lmts["memory"])) # storagelmts.append(Q_(lmts["ephemeral-storage"])) cpu_allocated = sum(cpureqs) cpu_allocated.ito(ureg.m) s_i["cpu"]["allocated"] = cpu_allocated mem_allocated = sum(memreqs) mem_allocated.ito(ureg.Mi) s_i["mem"]["allocated"] = mem_allocated storage_allocated = sum(storagereqs) storage_allocated.ito(ureg.Mi) s_i["storage"]["allocated"] = storage_allocated if int(s_i['pods']['allocatable'].magnitude) == 0: s_i['pods']['percentage'] = 0 else: s_i['pods']['percentage'] = ( (int(s_i['pods']['allocated'].magnitude) * 100) // (int(s_i['pods']['allocatable'].magnitude))) if int(s_i['cpu']['allocatable'].magnitude) == 0: s_i['cpu']['percentage'] = 0 else: s_i['cpu']['percentage'] = ( (int(s_i['cpu']['allocated'].magnitude) * 100) // (int(s_i['cpu']['allocatable'].magnitude))) if int(s_i['mem']['allocatable'].magnitude) == 0: s_i['mem']['percentage'] = 0 else: s_i['mem']['percentage'] = ( (int(s_i['mem']['allocated'].magnitude) * 100) // (int(s_i['mem']['allocatable'].magnitude))) if int(s_i['storage']['allocatable'].magnitude) == 0: s_i['storage']['percentage'] = 0 else: s_i['storage']['percentage'] = ( (int(s_i['storage']['allocated'].magnitude) * 100) // (int(s_i['storage']['allocatable'].magnitude))) return s_i
def get_action(name, debug=False, api_client=None): """ Get Pystol action details. This is a main component of the input for the controller """ load_kubernetes_config() api = kubernetes.client.CustomObjectsApi(api_client=api_client) group = "pystol.org" version = "v1alpha1" namespace = "pystol" plural = "pystolactions" try: resp = api.get_namespaced_custom_object(group=group, version=version, namespace=namespace, plural=plural, name=name) print(" " + u"\U0001F4AC" + " General information") print(" Action: " + resp['spec']['namespace'] + "." + resp['spec']['collection'] + "." + resp['spec']['role']) print(" Extra variables: " + resp['spec']['extra_vars']) print(" Source: " + resp['spec']['source']) print(" " + u"\U0001F4AC" + " Status information") print(" Action state: " + resp['spec']['action_state']) print(" Workflow state: " + resp['spec']['workflow_state']) prefix = " Std output: " preferredwidth = 70 wrapper = textwrap.TextWrapper(initial_indent=prefix, width=preferredwidth, subsequent_indent=' ' * len(prefix)) print(wrapper.fill(resp['spec']['action_stdout'])) prefix = " Std error: " preferredwidth = 70 wrapper = textwrap.TextWrapper(initial_indent=prefix, width=preferredwidth, subsequent_indent=' ' * len(prefix)) print(wrapper.fill(resp['spec']['action_stderr'])) except ApiException: print(" " + u"\U0001F914" + " Object not found, perhaps you have a typo.") if debug: api = kubernetes.client.BatchV1Api(api_client=api_client) namespace = "pystol" pretty = 'true' try: resp = api.read_namespaced_job(name=name, namespace=namespace, pretty=pretty) print("---- Job description begins ----") print(resp) print("---- Job description ends ----") except ApiException: print(" " + u"\U0001F914" + " Job not found, perhaps you have a typo.") api = kubernetes.client.CoreV1Api(api_client=api_client) namespace = "pystol" pretty = 'true' try: resp = api.list_namespaced_pod(namespace=namespace, pretty=pretty) found = False for pod in resp.items: if name in pod.metadata.name: found = True resp = api.read_namespaced_pod_log(name=pod.metadata.name, namespace=namespace, pretty=pretty) print("---- Pod logs begins ----") print("Logs from: " + pod.metadata.name) print(resp) print("---- Pod logs ends ----") if not found: print(" " + u"\U0001F914" + " Pod not found, perhaps you have a typo.") except ApiException: print(" " + u"\U0001F914" + " Pod not found, perhaps you have a typo.")
def list_actions(api_client=None, debug=False): """ List Pystol actions from the cluster. This is a main component of the input for the controller """ load_kubernetes_config() api = kubernetes.client.CustomObjectsApi(api_client=api_client) group = "pystol.org" version = "v1alpha1" namespace = "pystol" plural = "pystolactions" pretty = 'true' x = PrettyTable() x.field_names = ["Name", "Creation", "Action state", "Workflow state"] ret = [] try: resp = api.list_namespaced_custom_object(group=group, version=version, namespace=namespace, plural=plural, pretty=pretty) for action in resp['items']: name = action['metadata']['name'] job_description = "" pod_logs = "" if debug: namespace = "pystol" pretty = 'true' apiO = kubernetes.client.BatchV1Api(api_client=api_client) try: resp = apiO.read_namespaced_job(name=name, namespace=namespace, pretty=pretty) job_description = resp except ApiException: print("Job not found") apiO = kubernetes.client.CoreV1Api(api_client=api_client) try: resp = apiO.list_namespaced_pod(namespace=namespace, pretty=pretty) found = False for pod in resp.items: if name in pod.metadata.name: found = True resp = apiO.read_namespaced_pod_log( name=pod.metadata.name, namespace=namespace, pretty=pretty) pod_logs = resp if not found: print("Pod not found.") except ApiException: print("Pod not found.") ret.append({ 'name': action['metadata']['name'], 'creationTimestamp': action['metadata']['creationTimestamp'], 'action_state': action['spec']['action_state'], 'workflow_state': action['spec']['workflow_state'], 'stdout': action['spec']['action_stdout'], 'stderr': action['spec']['action_stderr'], 'job_description': job_description, 'pod_logs': pod_logs }) x.add_row([ action['metadata']['name'], action['metadata']['creationTimestamp'], action['spec']['action_state'], action['spec']['workflow_state'] ]) except Exception as e: print("No objects found or error...") return [] print(x) return ret
def purge_pystol(api_client=None): """ Purge Pystol from the cluster. This is a main component of the input for the controller """ load_kubernetes_config() v1 = kubernetes.client.CoreV1Api(api_client=api_client) name = 'pystol' pretty = 'true' orphan_dependents = True # propagation_policy = 'Foreground' propagation_policy = 'Background' body = kubernetes.client.V1DeleteOptions() try: v1.delete_namespace(name, pretty=pretty, orphan_dependents=orphan_dependents, propagation_policy=propagation_policy, body=body) print(" " + u"\U0001F9F9" + " Namespace removed.") except ApiException: print(" " + u"\u2757" + " Namespace removing warning.") print(" Can't remove it, maybe it's gone...") name = 'pystol-service' namespace = 'pystol' pretty = 'true' orphan_dependents = True propagation_policy = 'Background' body = kubernetes.client.V1DeleteOptions() try: v1.delete_namespaced_service(name, namespace=namespace, pretty=pretty, orphan_dependents=orphan_dependents, propagation_policy=propagation_policy, body=body) print(" " + u"\U0001F9F9" + " Service removed.") except ApiException: print(" " + u"\u2757" + " Service removing warning.") print(" Can't remove it, maybe it's gone...") name = 'pystol-config' namespace = 'pystol' pretty = 'true' orphan_dependents = True propagation_policy = 'Background' body = kubernetes.client.V1DeleteOptions() try: v1.delete_namespaced_config_map(name, namespace=namespace, pretty=pretty, orphan_dependents=orphan_dependents, propagation_policy=propagation_policy, body=body) print(" " + u"\U0001F9F9" + " Config map removed.") except ApiException: print(" " + u"\u2757" + " Config map removing warning.") print(" Can't remove it, maybe it's gone...") name = 'pystol' namespace = 'pystol' pretty = 'true' orphans = True propagation = 'Background' body = kubernetes.client.V1DeleteOptions() try: v1.delete_namespaced_service_account(name, namespace=namespace, pretty=pretty, orphan_dependents=orphans, propagation_policy=propagation, body=body) print(" " + u"\U0001F9F9" + " Service account removed.") except ApiException: print(" " + u"\u2757" + " Service account removing warning.") print(" Can't remove it, maybe it's gone...") rbac = kubernetes.client.RbacAuthorizationV1Api(api_client=api_client) name = 'pystol' pretty = 'true' orphan_dependents = True propagation_policy = 'Background' body = kubernetes.client.V1DeleteOptions() try: rbac.delete_cluster_role(name, pretty=pretty, orphan_dependents=orphan_dependents, propagation_policy=propagation_policy, body=body) print(" " + u"\U0001F9F9" + " Cluster role removed.") except ApiException: print(" " + u"\u2757" + " Cluster role removing warning.") print(" Can't remove it, maybe it's gone...") rbac = kubernetes.client.RbacAuthorizationV1Api(api_client=api_client) name = 'pystol' pretty = 'true' orphan_dependents = True propagation_policy = 'Background' body = kubernetes.client.V1DeleteOptions() try: rbac.delete_cluster_role_binding(name, pretty=pretty, orphan_dependents=orphan_dependents, propagation_policy=propagation_policy, body=body) print(" " + u"\U0001F9F9" + " Cluster role binding removed.") except ApiException: print(" " + u"\u2757" + " Cluster role binding removing warning.") print(" Can't remove it, maybe it's gone...") ext = kubernetes.client.ApiextensionsV1beta1Api(api_client=api_client) name = 'pystolactions.pystol.org' pretty = 'true' orphans = True propagation = 'Background' body = kubernetes.client.V1DeleteOptions() try: ext.delete_custom_resource_definition(name, pretty=pretty, orphan_dependents=orphans, propagation_policy=propagation, body=body) print(" " + u"\U0001F9F9" + " CRD removed.") except ApiException: print(" " + u"\u2757" + " CRD removing warning.") print(" Can't remove it, maybe it's gone...")