def _ensure_crds() -> None:
    """
    ensure_crds makes sure that all the required CRDs have been created
    """
    crdv1 = client.ApiextensionsV1beta1Api()
    crd = _load_mongodb_crd()

    k8s_conditions.ignore_if_doesnt_exist(
        lambda: crdv1.delete_custom_resource_definition("mongodb.mongodb.com"))

    # Make sure that the CRD has being deleted before trying to create it again
    if not k8s_conditions.wait(
            lambda: crdv1.list_custom_resource_definition(
                field_selector="metadata.name==mongodb.mongodb.com"),
            lambda crd_list: len(crd_list.items) == 0,
            timeout=5,
            sleep_time=0.5,
    ):
        raise Exception(
            "Execution timed out while waiting for the CRD to be deleted")

    # TODO: fix this, when calling create_custom_resource_definition, we get the error
    # ValueError("Invalid value for `conditions`, must not be `None`")
    # but the crd is still successfully created
    try:
        crdv1.create_custom_resource_definition(body=crd)
    except ValueError as e:
        pass

    print("Ensured CRDs")
def get_clients():
    """
	Get clusters, clients for each cluster, and the active cluster
	:return: ((Dict) {cluster : context}
			  (Dict) {cluster : {client_type : client}}
			  (str) name of active cluster)
	"""
    clusters = k8s_config.update_available_clusters()
    contexts, active_context = config.list_kube_config_contexts(
    )  # assuming current active cluster is the hub
    active_cluster = active_context["context"]["cluster"]
    clients = {}
    for cluster in clusters:
        context = clusters[cluster]
        # building all clients for all clusters
        clients[cluster] = {}
        clients[cluster]["apps_client"] = client.AppsV1Api(
            api_client=config.new_client_from_config(context=context))
        clients[cluster]["batch_client"] = client.BatchV1Api(
            api_client=config.new_client_from_config(context=context))
        clients[cluster]["core_client"] = client.CoreV1Api(
            api_client=config.new_client_from_config(context=context))
        clients[cluster]["ext_client"] = client.ExtensionsV1beta1Api(
            api_client=config.new_client_from_config(context=context))
        clients[cluster]["api_client"] = client.ApiextensionsV1beta1Api(
            api_client=config.new_client_from_config(context=context))
        clients[cluster]["customs_client"] = client.CustomObjectsApi(
            api_client=config.new_client_from_config(context=context))

    return clusters, clients, active_cluster
def check_crd_deleted():
    """
    Function for checking CRD (Custom Resource Defination) is deleted or not
    If CRD is not deleted in 60 seconds,function asserts

    Args:
       None

    Returns:
       None

    Raises:
        Raises an exception on kubernetes client api failure and asserts

    """
    var = True
    count = 12
    list_crd_api_instance = client.ApiextensionsV1beta1Api()
    while (var and count > 0):
        try:
            list_crd_api_response = list_crd_api_instance.read_custom_resource_definition(
                pretty=True, name="ibm-spectrum-scale-csi")
            LOGGER.debug(list_crd_api_response)
            LOGGER.info("still deleting crd")
            count -= 1
            time.sleep(5)

        except ApiException:
            LOGGER.info("crd deleted")
            var = False

    if count <= 0:
        LOGGER.error("crd is not deleted")
        assert False
def create_crd():
    """
    Create IBM Spectrum Scale CSI Operator CRD (Custom Resource Defination) Object

    Args:
       None

    Returns:
       None

    Raises:
        Raises an ValueError exception but it is expected. hence we pass.

    """
    filepath = "../../operator/deploy/crds/csiscaleoperators.csi.ibm.com.crd.yaml"
    try:
        with open(filepath, "r") as f:
            loadcrd_yaml = yaml.full_load(f.read())
    except yaml.YAMLError as exc:
        print("Error in configuration file:", exc)
        assert False

    crd_api_instance = client.ApiextensionsV1beta1Api()
    try:
        LOGGER.info(
            "Creating IBM SpectrumScale CRD object using csiscaleoperators.csi.ibm.com.crd.yaml file"
        )
        crd_api_response = crd_api_instance.create_custom_resource_definition(
            loadcrd_yaml, pretty=True)
        LOGGER.debug(str(crd_api_response))
    except ValueError:
        LOGGER.info(
            "while there is valuerror expection,but CRD created successfully")
def check_crd_exists():
    """
    Checks custom resource defination exists or not

    Args:
       None

    Returns:
       return True  , if crd exists
       return False , if crd does not exists

    Raises:
        None

    """
    read_crd_api_instance = client.ApiextensionsV1beta1Api()
    try:
        read_crd_api_response = read_crd_api_instance.read_custom_resource_definition(
            pretty=True, name="csiscaleoperators.csi.ibm.com")
        LOGGER.debug(str(read_crd_api_response))
        LOGGER.info("crd exists")
        return True
    except ApiException:
        LOGGER.info("crd does not exist")
        return False
Exemple #6
0
    def __init__(self, bearer_token=None):
        '''
        Initialize connection to Kubernetes
        '''
        self.bearer_token = bearer_token
        api_client = None

        try:
            config.load_incluster_config()
        except config.config_exception.ConfigException:
            config.load_kube_config()

        if self.bearer_token:
            # Configure API key authorization: Bearer Token
            configuration = client.Configuration()
            configuration.api_key_prefix['authorization'] = 'Bearer'
            configuration.api_key['authorization'] = self.bearer_token
            api_client = client.ApiClient(configuration)

        self.client = client.CoreV1Api(api_client)
        self.batch_api = client.BatchV1Api(api_client)
        self.batch_v1beta1_api = client.BatchV1beta1Api(api_client)
        self.custom_objects = client.CustomObjectsApi(api_client)
        self.api_extensions = client.ApiextensionsV1beta1Api(api_client)
        self.extension_api = client.ExtensionsV1beta1Api(api_client)
        self.apps_v1_api = client.AppsV1Api(api_client)
Exemple #7
0
def get_crds() -> Optional[Dict]:
    crdv1 = client.ApiextensionsV1beta1Api()
    try:
        crd = crdv1.list_custom_resource_definition(pretty="true")
    except ApiException as e:
        print("Exception when calling list_custom_resource_definition: %s\n" % e)
        return None
    return crd.to_dict()
Exemple #8
0
def validate_cluster(splunk, record):
    from kubernetes import client
    try:
        connection_stanza = splunklib.client.Stanza(splunk,
                                                    "",
                                                    skip_refresh=True)
        connection_stanza.refresh(
            state=splunklib.data.record({"content": record}))
        config = create_client_configuration(connection_stanza)
        api_client = client.ApiClient(config)
        version_api = client.VersionApi(api_client)
        version_api.get_code()
    except errors.ApplicationError as e:
        raise Exception("Could not connect to Kubernetes.\n\n%s" % e)
    except Exception:
        raise Exception(traceback.format_exc())
    try:
        extensions_api = client.ApiextensionsV1beta1Api(api_client)
        crd = extensions_api.read_custom_resource_definition(
            "standalones.enterprise.splunk.com")
        if crd.spec.version != "v1alpha2":
            raise errors.ApplicationError(
                "Unexpected Splunk Operator version: %s" % crd.spec.version)
    except client.rest.ApiException as e:
        if e.status == 404:
            raise errors.ApplicationError("Could not find Splunk Operator.")
        raise
    except errors.ApplicationError:
        raise
    except Exception:
        raise Exception(traceback.format_exc())
    try:
        indexer_server_count = 0
        for server in record.indexer_server.split(","):
            components = server.split(":")
            if len(components) != 2:
                raise errors.ApplicationError(
                    "Expect format \"<server>:<port>,...\" for indexer server. Got \"%s\""
                    % (server))
            hostname = components[0].strip()
            port = int(components[1].strip())
            import socket
            s = socket.socket()
            try:
                s.connect((hostname, port))
            except Exception as e:
                raise errors.ApplicationError(
                    "Could not connect to indexer server \"%s\": %s" %
                    (server, e))
            finally:
                s.close()
            indexer_server_count += 1
        if indexer_server_count == 0:
            raise errors.ApplicationError("Invalid or misssing indexer server")
    except errors.ApplicationError:
        raise
    except Exception:
        raise Exception(traceback.format_exc())
Exemple #9
0
    def __init__(self,
                 group: str,
                 version: str,
                 plural: str,
                 namespace: str,
                 template_cr: Dict,
                 labels: Dict) -> None:
        """Constructor."""
        if 'KUBERNETES_PORT' in os.environ:
            _LOGGER.info('%s/%s: Handler starting "incluster_config" mode', group, plural)
            config.load_incluster_config()
        else:
            _LOGGER.info('%s/%s: Handler starting "kube_config" mode', group, plural)
            config.load_kube_config()

        # Instantiate required K8s APIs
        self.core_api = client.CoreV1Api()
        self.crd_api = client.ApiextensionsV1beta1Api()
        self.co_api = client.CustomObjectsApi()

        # K8s stream watcher
        self.watcher = watch.Watch()

        # Configs set to specify which CRs to monitor/control
        self.group = group
        self.version = version
        self.plural = plural
        self.namespace = namespace

        self.label_selector = ''
        for k, val in labels.items():
            self.label_selector += k + '=' + val + ','
        self.label_selector = self.label_selector[:-1]

        # Latest resource version processed by watcher
        self.resv_watcher = ''

        # Callback stack for watch on cr
        self.callbacks = {
            'ADDED': OrderedDict(),
            'MODIFIED': OrderedDict(),
            'DELETED': OrderedDict(),
            'REPROCESS': OrderedDict()
            }

        # JSON template used while creating custom resources
        self.raw_cr = template_cr

        # Lock objects to synchronize processing of CRs
        self.cr_locks = defaultdict(threading.RLock)
        # Dict to save thread exceptions
        self.thread_exceptions = {}
        # Init threads
        self.watcher_thread = threading.Thread(target=self._watch_on_crs_loop, daemon=True)
        self.reprocess_thread = threading.Thread(target=self._reprocess_crs_loop)
        # Control flag for thread
        self.thread_run = True
        self.number_executor_threads = 1
Exemple #10
0
def confirm_custom_resource_definition(context):
    if context is None:
        raise SystemExit(
            "invalid empty context for CustomResourceDefinition given")
    load_kube(context)
    api = client.ApiextensionsV1beta1Api()
    return general_confirm("CustomResourceDefinition",
                           lambda: api.list_custom_resource_definition(),
                           lambda i: i.metadata.name)
Exemple #11
0
def crds_applied():
    print("Checking for CRDs")
    v1_ext = client.ApiextensionsV1beta1Api()
    for x in range(5):
        if x != 0:
            time.sleep(SLEEP_INTERVAL)
        current_crds = [x["spec"]["names"]["kind"].lower() for x in v1_ext.list_custom_resource_definition().to_dict()['items']]
        if "configuration" in current_crds and "instance" in current_crds:
            return True
    return False
Exemple #12
0
    def _create_custom_resource_definitions(self):
        if self._crd:
            return

        api = client.ApiextensionsV1beta1Api()
        self._crd = \
            CustomResourceDefinitionLoader._custom_resource_definition()
        try:
            api.create_custom_resource_definition(self._crd)
        except client.rest.ApiException:
            pass
Exemple #13
0
def wait_for_custom_resource_definition_is_away(context, name):
    if name is None:
        raise SystemExit(
            "invalid empty name for CustomResourceDefinition given")
    if context is None:
        raise SystemExit("invalid empty name context given")
    load_kube(context)
    print("check removal of", "CustomResourceDefinition", name)
    api = client.ApiextensionsV1beta1Api()
    return general_away_check(
        None, "CustomResourceDefinition", name,
        lambda: api.read_custom_resource_definition_with_http_info(name))
Exemple #14
0
 def Read_Custom_Resource_Definition_Status(self, name):
     configuration = client.Configuration()
     api_instance = client.ApiextensionsV1beta1Api(
         client.ApiClient(configuration))
     try:
         api_response = api_instance.read_custom_resource_definition_status(
             name, pretty='true')
         pprint(api_response)
     except ApiException as e:
         print(
             "Exception when calling ApiextensionsV1beta1Api->read_custom_resource_definition_status: %s\n"
             % e)
Exemple #15
0
def remove_custom_resource_definition(context, name):
    if context is None:
        raise SystemExit(
            "invalid empty context for CustomResourceDefinition given")
    if name is None:
        raise SystemExit(
            "invalid empty name for CustomResourceDefinition given")

    load_kube(context)
    api = client.ApiextensionsV1beta1Api()
    ret, status, _ = api.delete_custom_resource_definition_with_http_info(name)
    handle_status(ret, status, "CustomResourceDefinition", None, name)
    def __init__(self):
        # Create Kubernetes config.
        load_incluster_config()
        config = Configuration()
        config.debug = Settings.KUBERNETES_SERVICE_DEBUG
        self.api_client = client.ApiClient(config)

        # Re-usable API client instances.
        self.core_api = client.CoreV1Api(self.api_client)
        self.custom_objects_api = client.CustomObjectsApi(self.api_client)
        self.extensions_api = client.ApiextensionsV1beta1Api(self.api_client)
        self.apps_api = client.AppsV1beta1Api(self.api_client)
Exemple #17
0
 def verify_can_run(self):
     v1 = client.ApiextensionsV1beta1Api(self.api_client)
     current_crds = [
         x['spec']['names']['kind'].lower()
         for x in v1.list_custom_resource_definition().to_dict()['items']
     ]
     if 'nfsbucket' not in current_crds:
         print(
             "You need to create the CRD with kubectl apply -f nfs-crd.yaml"
         )
         raise RuntimeError(
             "CRD does not exist in kubernetes cluster, controller can not start!"
         )
Exemple #18
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()
Exemple #19
0
def deploy_operator(namespace, operator_yaml):
    # We use `kubectl` here because for the kubernetes client we would
    # need to handle the document kind individually.
    kubectl(["apply", "-f", operator_yaml])
    operator_deployed = False

    def is_operator_deployed(event):
        if (event["type"] == "ADDED"
                and event["object"].metadata.name == "mssql-operator"):
            return True, event["object"]
        else:
            return False, event["object"]

    apps_api = kclient.AppsV1Api()
    operator_success, operator_deployed = kube_watch_event(
        is_operator_deployed,
        apps_api.list_namespaced_deployment,
        namespace=namespace,
        timeout_seconds=10)
    log(LogLevel.ALL, "operator deployed:", operator_success)

    def is_crd_deployed(event):
        expected = "sqlservers.mssql.microsoft.com"
        if (event["type"] == "ADDED"
                and event["object"].metadata.name == expected):
            return True, event["object"]
        else:
            return False, event["object"]

    extensions_api = kclient.ApiextensionsV1beta1Api()

    # We need to sleep here.
    # Kubernetes client API will raise the following exception if the operator
    # is not fully deployed when trying to list_custom_resource_definition:
    # File "kubernetes/client/models/v1beta1_custom_resource_definition_status.py", line 105, in conditions # noqa: E501
    #   raise ValueError("Invalid value for `conditions`, must not be `None`")
    log(LogLevel.ALL, "Waiting 10 seconds...")
    time.sleep(10)

    # Wait for crd to be deployed.
    log(LogLevel.ALL,
        "Waiting for Custom Resource Definition to be initialized")
    log(LogLevel.INFO,
        "This can be slow during the first deployment because we need to",
        "pull docker images")
    kube_watch_event(is_crd_deployed,
                     extensions_api.list_custom_resource_definition)

    return operator_success
Exemple #20
0
 def __init__(self,
              context=None,
              usecloning=False,
              host='127.0.0.1',
              port=22,
              user='******',
              debug=False):
     self.host = host
     self.port = port
     self.user = user
     self.usecloning = usecloning
     self.conn = 'OK'
     contexts, current = config.list_kube_config_contexts()
     if context is not None:
         contexts = [
             entry for entry in contexts if entry['name'] == context
         ]
         if contexts:
             context = contexts[0]
             contextname = context['name']
         else:
             self.conn = None
     else:
         context = current
         contextname = current['name']
     config.load_kube_config(context=contextname)
     if 'namespace' in context['context']:
         self.namespace = context['context']['namespace']
     else:
         self.namespace = 'default'
     self.crds = client.CustomObjectsApi()
     extensions = client.ApiextensionsV1beta1Api()
     current_crds = [
         x for x in extensions.list_custom_resource_definition().to_dict()
         ['items'] if x['spec']['names']['kind'].lower() == 'virtualmachine'
     ]
     if not current_crds:
         common.pprint("Kubevirt not installed", color='red')
         self.conn = None
         self.host = context
         return
     self.core = client.CoreV1Api()
     self.debug = debug
     if host == '127.0.0.1' and len(contextname.split('/')) == 3 and len(
             contextname.split('/')[1].split(':')) == 2:
         self.host = contextname.split('/')[1].split(':')[0].replace(
             '-', '.')
     return
Exemple #21
0
    def create_crd(cls):
        api_extensions_api = client.ApiextensionsV1beta1Api()
        crd = {
            "apiVersion": "apiextensions.k8s.io/v1beta1",
            "kind": "CustomResourceDefinition",
            "metadata": {
                "name": cls.name_plural() + "." + GROUP
            },
            "spec": {
                "group": GROUP,
                "version": cls.version(),
                "scope": "Cluster"
                if issubclass(cls, SystemResourceModel) else "Namespaced",
                "names": {
                    "plural": cls.name_plural(),
                    "singular": cls.name_singular(),
                    "kind": cls.kind(),
                    "listKind": cls.list_kind(),
                }
            }
        }

        # Patching the client to get around this issue:
        # https://github.com/kubernetes-incubator/client-python/issues/415
        @property
        def accepted_names(self):
            return self._accepted_names

        @accepted_names.setter
        def accepted_names(self, accepted_names):
            self._accepted_names = accepted_names

        @property
        def conditions(self):
            return self._conditions

        @conditions.setter
        def conditions(self, conditions):
            self._conditions = conditions

        V1beta1CustomResourceDefinitionStatus.accepted_names = accepted_names
        V1beta1CustomResourceDefinitionStatus.conditions = conditions
        try:
            api_extensions_api.create_custom_resource_definition(crd)
        except ApiException as e:
            # If it already exists don't error
            if e.status != 409:
                raise
def kube_apis(cli_arguments) -> KubeApis:
    """
    Set up kubernets-client to operate in cluster.

    :param cli_arguments: a set of command-line arguments
    :return: KubeApis
    """
    context_name = cli_arguments['context']
    kubeconfig = cli_arguments['kubeconfig']
    config.load_kube_config(config_file=kubeconfig, context=context_name, persist_config=False)
    v1 = client.CoreV1Api()
    extensions_v1_beta1 = client.ExtensionsV1beta1Api()
    rbac_v1_beta1 = client.RbacAuthorizationV1beta1Api()
    api_extensions_v1_beta1 = client.ApiextensionsV1beta1Api()
    custom_objects = client.CustomObjectsApi()
    return KubeApis(v1, extensions_v1_beta1, rbac_v1_beta1, api_extensions_v1_beta1, custom_objects)
Exemple #23
0
 def __init__(self):
     check_microk8s_kube_config_file()
     load_kubernetes_config()
     self.api_client = client.ApiClient()
     self.custom_def_cli = client.CustomObjectsApi()
     self.core_cli = client.CoreV1Api()
     self.apps_cli = client.AppsV1Api()
     self.rbac_cli = client.RbacAuthorizationV1Api()
     self.extenstion_cli = client.ExtensionsV1beta1Api()
     self.crd_cli = client.ApiextensionsV1beta1Api()
     self.storage_cli = client.StorageV1Api()
     self.admission_cli = client.AdmissionregistrationV1beta1Api()
     self.delete_options = client.V1DeleteOptions()
     self.delete_options.grace_period_seconds = 2
     self.delete_options.propagation_policy = 'Foreground'
     self.core_cli.api_client.configuration.assert_hostname = False
     self.apps_cli.api_client.configuration.assert_hostname = False
Exemple #24
0
    def create_crds(self):
        # API Extensions V1 beta1 API client.
        crd_api = client.ApiextensionsV1beta1Api()

        crd_dir = os.path.join(os.path.dirname(__file__), '../resources/crds')
        crd_paths = [os.path.abspath(os.path.join(crd_dir, name))
                     for name in os.listdir(crd_dir)]

        for path in crd_paths:
            with open(path) as crd_file:
                crd_json = json.dumps(
                    yaml.load(crd_file.read()), sort_keys=True, indent=2)
                crd = deserialize_object(
                    crd_json, 'V1beta1CustomResourceDefinition')
                try:
                    crd_api.create_custom_resource_definition(crd)
                except Exception:
                    pass
 def __init__(self, squirrel):
     self.squirrel = squirrel
     config.load_incluster_config()
     self.configuration = client.Configuration()
     self.configuration.assert_hostname = False
     self.api_client = client.api_client.ApiClient(
         configuration=self.configuration)
     self.v1 = client.ApiextensionsV1beta1Api(self.api_client)
     print("Creating definition")
     for d in ["nuts.yml", "nutcrackers.yml"]:
         self.definition = '%s/%s' % (squirrel.squirrel_controller, d)
         with open(self.definition) as data:
             body = yaml.load(data)
         try:
             self.v1.create_custom_resource_definition(body)
         except Exception as e:
             print("Ignoring error: %s" % e)
     self.crds = client.CustomObjectsApi(self.api_client)
Exemple #26
0
    def __init__(self):
        atexit.register(self.clean_up)

        if 'KUBERNETES_PORT' in os.environ:
            config.load_incluster_config()
        else:
            config.load_kube_config()
        self.configuration = client.Configuration()
        self.configuration.assert_hostname = False
        self.api_client = client.api_client.ApiClient(
            configuration=self.configuration)
        self.v1_client = client.ApiextensionsV1beta1Api(self.api_client)
        self.crd_client = client.CustomObjectsApi(self.api_client)

        self.jobs = {}

        # launch default clean up process
        self.clean_up()
Exemple #27
0
 def wait_for_crd(cls):
     name = cls.name_plural() + "." + GROUP
     api_extensions_api = client.ApiextensionsV1beta1Api()
     while True:
         try:
             crd = api_extensions_api.read_custom_resource_definition(name)
             for cond in crd.status.conditions:
                 if cond.type == "Established":
                     return
                 if cond.type == "NamesAccepted":
                     if cond.status == "False":
                         raise ValueError(
                             "Failed to create CRD {0}: name conflict: {1}".
                             format(name, cond.message))
         except ApiException as e:
             # If it doesn't exist just wait, k8s may be slow
             if e.status != 404:
                 raise
         time.sleep(1)
Exemple #28
0
    def __init__(self, *args, **kwargs):
        """
        Constructor

        Args:
        args     -- posistional arguments
        kwargs   -- Named arguments

        Returns:
        K8s object
        """
        super(K8s, self).__init__(*args, **kwargs)

        lib.log.debug("K8s init", extra=dict(**kwargs))

        kube_config = kwargs["kube_config"] if "kube_config" in kwargs else ""
        if kube_config and len(kube_config) > 0:
            lib.log.info("using kube_config=%s", kube_config)
            config.load_kube_config(config_file=kube_config)
        else:
            lib.log.info("no kube_config, running in-cluster")
            config.load_incluster_config()

        self.v1 = client.CoreV1Api()
        self.v1App = client.AppsV1Api()
        self.v1ext = client.ExtensionsV1beta1Api()
        self.v1beta1 = client.ApiextensionsV1beta1Api()
        self.custom = client.CustomObjectsApi()
        self.auto_scaler = client.AutoscalingV1Api()
        self.rbac = client.RbacAuthorizationV1Api()

        if 'cluster_name' in kwargs:
            lib.log.info("using explicit cluster_set= %s, cluster_name=%s",
                         kwargs.get('cluster_set'), kwargs.get('cluster_name'))
            self.cluster_info = {
                "cluster.name": kwargs.get('cluster_name'),
                "cluster.set": kwargs.get('cluster_set')
            }
        else:
            lib.log.info("getting cluster info")
            self.cluster_info = self.get_cluster_info()
            lib.log.debug("kube-system/cluster-data ConfigMap: {}".format(
                self.cluster_info))
Exemple #29
0
def _ensure_crds():
    """
    ensure_crds makes sure that all the required CRDs have been created
    """
    crdv1 = client.ApiextensionsV1beta1Api()
    crd = _load_mongodb_crd()

    ignore_if_doesnt_exist(
        lambda: crdv1.delete_custom_resource_definition("mongodb.mongodb.com")
    )

    # TODO: fix this, when calling create_custom_resource_definition, we get the error
    # ValueError("Invalid value for `conditions`, must not be `None`")
    # but the crd is still successfully created
    try:
        crdv1.create_custom_resource_definition(body=crd)
    except ValueError as e:
        pass

    print("Ensured CRDs")
 def create_scaling_decision_crd(self):
     definition = '../../example/scaling_decision_crd.yml'
     v1 = client.ApiextensionsV1beta1Api()
     current_crds = [
         x['spec']['names']['kind'].lower()
         for x in v1.list_custom_resource_definition().to_dict()['items']
     ]
     # print(current_crds)
     if 'decision' not in current_crds:
         print("Creating Decision definition")
         with open(definition) as data:
             body = yaml.load(data, Loader=yaml.Loader)
             # print(yaml.dump(body))
         try:
             v1.create_custom_resource_definition(body)
         except ValueError as exception:  # Check: https://github.com/kubernetes-client/python/issues/1098
             if str(
                     exception
             ) == 'Invalid value for `conditions`, must not be `None`':
                 print("Skipping invalid \'conditions\' value...")
             else:
                 raise exception