Пример #1
0
    def _find_cluster_in_org(self, cluster_name, is_org_admin_search=False):
        """Invoke set of all (vCD/PKS)brokers in the org to find the cluster.

        'is_org_admin_search' is used here to prevent cluster creation with
        same cluster-name by users within org. If it is true,
        cluster list is filtered by the org name of the logged-in user.

        If cluster found:
            Return a tuple of (cluster and the broker instance used to find
            the cluster)
        Else:
            (None, None) if cluster not found.
        """
        vcd_broker = VcdBroker(self.req_headers, self.req_spec)
        try:
            return vcd_broker.get_cluster_info(cluster_name), vcd_broker
        except Exception as err:
            LOGGER.debug(f"Get cluster info on {cluster_name} failed "
                         f"on vCD with error: {err}")

        pks_ctx_list = self._create_pks_context_for_all_accounts_in_org()
        for pks_ctx in pks_ctx_list:
            pksbroker = PKSBroker(self.req_headers, self.req_spec, pks_ctx)
            try:
                return pksbroker.get_cluster_info(
                    cluster_name=cluster_name,
                    is_org_admin_search=is_org_admin_search), pksbroker
            except PksServerError as err:
                LOGGER.debug(f"Get cluster info on {cluster_name} failed "
                             f"on {pks_ctx['host']} with error: {err}")

        return None, None
    def find_cluster_in_org(self, cluster_name, is_org_admin_search=False):
        """Invoke vCD broker to find the cluster in the org.

        'is_org_admin_search' is used here to prevent cluster creation with
        same cluster-name by users within org. If it is true,
        cluster list is filtered by the org name of the logged-in user.

        If cluster found:
            Return a tuple of (cluster and the broker instance used to find
            the cluster)
        Else:
            (None, None) if cluster not found.
        """
        vcd_broker = VcdBroker(self.tenant_auth_token, self.req_spec)
        try:
            return vcd_broker.get_cluster_info(cluster_name), vcd_broker
        except ClusterNotFoundError as err:
            # If a cluster is not found, then broker_manager will
            # decide if it wants to raise an error or ignore it if was it just
            # scanning the broker to check if it can handle the cluster request
            # or not.
            LOGGER.debug(f"Get cluster info on {cluster_name}"
                         f"on vCD failed with error: {err}")
        except CseDuplicateClusterError as err:
            LOGGER.debug(f"Get cluster info on {cluster_name}"
                         f"on vCD failed with error: {err}")
            raise
        except Exception as err:
            LOGGER.debug(f"Get cluster info on {cluster_name} failed "
                         f"on vCD with error: {err}")
        return None, None
Пример #3
0
    def _find_cluster_in_org(self, cluster_name):
        """Invoke set of all (vCD/PKS)brokers in the org to find the cluster.

        If cluster found:
            Return a tuple of (cluster and the broker instance used to find
            the cluster)
        Else:
            (None, None) if cluster not found.
        """
        vcd_broker = VcdBroker(self.req_headers, self.req_spec)
        try:
            return vcd_broker.get_cluster_info(cluster_name), vcd_broker
        except Exception as err:
            LOGGER.debug(f"Get cluster info on {cluster_name} failed "
                         f"on vCD with error: {err}")

        pks_ctx_list = self._create_pks_context_for_all_accounts_in_org()
        for pks_ctx in pks_ctx_list:
            pksbroker = PKSBroker(self.req_headers, self.req_spec, pks_ctx)
            try:
                return pksbroker.get_cluster_info(cluster_name=cluster_name),\
                    pksbroker
            except Exception as err:
                LOGGER.debug(f"Get cluster info on {cluster_name} failed "
                             f"on {pks_ctx['host']} with error: {err}")

        return None, None
def cluster_upgrade(request_data, op_ctx: ctx.OperationContext):
    """Request handler for cluster upgrade operation.

    data validation handled in broker

    :return: Dict
    """
    vcd_broker = VcdBroker(op_ctx)
    return vcd_broker.upgrade_cluster(data=request_data)
def cluster_upgrade_plan(request_data, op_ctx: ctx.OperationContext):
    """Request handler for cluster upgrade-plan operation.

    data validation handled in broker

    :return: List[Tuple(str, str)]
    """
    vcd_broker = VcdBroker(op_ctx)
    return vcd_broker.get_cluster_upgrade_plan(data=request_data)
Пример #6
0
def cluster_info(request_data, request_context: ctx.RequestContext):
    """Request handler for cluster info operation.

    Required data: cluster_name
    Optional data and default values: org_name=None, ovdc_name=None

    (data validation handled in broker)

    :return: Dict
    """
    vcd_broker = VcdBroker(request_context)
    return vcd_broker.get_cluster_info(data=request_data)
def cluster_config(request_data, op_ctx: ctx.OperationContext):
    """Request handler for cluster config operation.

    Required data: cluster_name
    Optional data and default values: org_name=None, ovdc_name=None

    (data validation handled in broker)

    :return: Dict
    """
    vcd_broker = VcdBroker(op_ctx)
    return vcd_broker.get_cluster_config(data=request_data)
def node_delete(request_data, op_ctx: ctx.OperationContext):
    """Request handler for node delete operation.

    Required data: cluster_name, node_names_list
    Optional data and default values: org_name=None, ovdc_name=None

    (data validation handled in broker)

    :return: Dict
    """
    vcd_broker = VcdBroker(op_ctx)
    return vcd_broker.delete_nodes(data=request_data)
def cluster_resize(request_data, op_ctx: ctx.OperationContext):
    """Request handler for cluster resize operation.

    Required data: cluster_name, num_nodes
    Optional data and default values: org_name=None, ovdc_name=None
    Conditional data and default values:
            network_name, rollback=True

    (data validation handled in broker)

    :return: Dict
    """
    vcd_broker = VcdBroker(op_ctx)
    return vcd_broker.resize_cluster(data=request_data)
def node_create(request_data, op_ctx: ctx.OperationContext):
    """Request handler for node create operation.

    Required data: cluster_name, network_name
    Optional data and default values: org_name=None, ovdc_name=None,
        num_nodes=1, num_cpu=None, mb_memory=None, storage_profile_name=None,
        template_name=default, template_revision=default,
        ssh_key=None, rollback=True, enable_nfs=False,

    (data validation handled in broker)

    :return: Dict
    """
    vcd_broker = VcdBroker(op_ctx)
    return vcd_broker.create_nodes(data=request_data)
Пример #11
0
def cluster_list(request_data, tenant_auth_token):
    """Request handler for cluster list operation.

    All (vCD/PKS) brokers in the org do 'list cluster' operation.
    Post-process the result returned by pks broker.
    Aggregate all the results into a list.

    Optional data and default values: org_name=None, ovdc_name=None

    (data validation handled in brokers)

    :return: List
    """
    vcd_clusters_info = \
        VcdBroker(tenant_auth_token).list_clusters(request_data)

    pks_clusters_info = []
    if utils.is_pks_enabled():
        pks_clusters_info = pks_broker_manager.list_clusters(
            request_data, tenant_auth_token)
    all_cluster_infos = vcd_clusters_info + pks_clusters_info

    common_cluster_properties = [
        'name', 'vdc', 'status', 'org_name', K8S_PROVIDER_KEY
    ]

    result = []
    for cluster_info in all_cluster_infos:
        filtered_cluster_info = \
            {k: cluster_info.get(k) for k in common_cluster_properties}
        result.append(filtered_cluster_info)

    return result
Пример #12
0
def cluster_create(request_data, request_context: ctx.RequestContext):
    """Request handler for cluster create operation.

    Required data: org_name, ovdc_name, cluster_name
    Conditional data and default values:
            network_name, num_nodes=2, num_cpu=None, mb_memory=None,
            storage_profile_name=None, template_name=default,
            template_revision=default, ssh_key=None, enable_nfs=False,
            rollback=True

    (data validation handled in broker)

    :return: Dict
    """
    vcd_broker = VcdBroker(request_context)
    return vcd_broker.create_cluster(data=request_data)
Пример #13
0
    def _get_broker_based_on_ctr_prov_ctx(self, ctr_prov_ctx):
        # If system is equipped with PKS, use the metadata on ovdc to determine
        # the correct broker, otherwise fallback to vCD for cluster deployment.
        # However if the system is enabled for PKS and has no metadata on odvc
        # or isn't enabled for container deployment raise appropriate
        # exception.
        if is_pks_enabled():
            if ctr_prov_ctx:
                if ctr_prov_ctx.get(K8S_PROVIDER_KEY) == K8sProviders.PKS:
                    return PKSBroker(self.tenant_auth_token,
                                     self.req_spec,
                                     pks_ctx=ctr_prov_ctx)
                elif ctr_prov_ctx.get(K8S_PROVIDER_KEY) == K8sProviders.NATIVE:
                    return VcdBroker(self.tenant_auth_token, self.req_spec)

        else:
            return VcdBroker(self.tenant_auth_token, self.req_spec)

        raise CseServerError("Org VDC is not enabled for Kubernetes cluster "
                             "deployment")
Пример #14
0
    def get_broker_based_on_vdc(self):
        """Get the broker based on ovdc.

        :return: broker

        :rtype: container_service_extension.abstract_broker.AbstractBroker
        """
        ovdc_name = self.req_spec.get('vdc') or \
            self.req_qparams.get('vdc')
        org_name = self.req_spec.get('org') or \
            self.req_qparams.get('org') or \
            self.session.get('org')

        LOGGER.debug(f"org_name={org_name};vdc_name=\'{ovdc_name}\'")

        # Get the ovdc metadata using org and ovdc.
        # Create the right broker based on value of 'container_provider'.
        # Fall back to DefaultBroker for missing ovdc or org.
        if ovdc_name and org_name:
            ctr_prov_ctx = \
                self.ovdc_cache.get_ovdc_container_provider_metadata(
                    ovdc_name=ovdc_name, org_name=org_name,
                    credentials_required=True, nsxt_info_required=True)
            LOGGER.debug(
                f"ovdc metadata for {ovdc_name}-{org_name}=>{ctr_prov_ctx}")
            if ctr_prov_ctx.get(CONTAINER_PROVIDER_KEY) == \
                    CtrProvType.PKS.value:
                return PKSBroker(self.req_headers,
                                 self.req_spec,
                                 pks_ctx=ctr_prov_ctx)
            elif ctr_prov_ctx.get(CONTAINER_PROVIDER_KEY) == \
                    CtrProvType.VCD.value:
                return VcdBroker(self.req_headers, self.req_spec)
            else:
                raise CseServerError(f"Vdc '{ovdc_name}' is not enabled for "
                                     "Kubernetes cluster deployment")
        else:
            # TODO() - This call should be based on a boolean flag
            # Specify flag in config file whether to have default
            # handling is required for missing ovdc or org.
            return VcdBroker(self.req_headers, self.req_spec)
def node_info(request_data, tenant_auth_token):
    """Request handler for node info operation.

    Required data: cluster_name, node_name
    Optional data and default values: org_name=None, ovdc_name=None

    (data validation handled in brokers)

    :return: Dict
    """
    # Currently node info is a vCD only operation.
    return VcdBroker(tenant_auth_token).get_node_info(request_data)
    def _get_broker_based_on_ctr_prov_ctx(self, ctr_prov_ctx):

        if ctr_prov_ctx \
                and ctr_prov_ctx.get(K8S_PROVIDER_KEY) == K8sProviders.PKS:
            return PKSBroker(self.req_headers,
                             self.req_spec,
                             pks_ctx=ctr_prov_ctx)
        else:
            # TODO() - This call should be based on a boolean flag
            # Specify flag in config file whether to have default
            # handling is required for missing ovdc or org.
            return VcdBroker(self.req_headers, self.req_spec)
def get_broker_from_k8s_metadata(k8s_metadata, tenant_auth_token):
    """Get broker from ovdc k8s metadata.

    If PKS is not enabled, always return VcdBroker
    If PKS is enabled
        if no ovdc metadata exists or k8s provider is None, raise server error
        else return the broker according to ovdc k8s provider
    """
    if utils.is_pks_enabled():
        if not k8s_metadata or k8s_metadata.get(
                K8S_PROVIDER_KEY) == K8sProvider.NONE:  # noqa: E501
            raise CseServerError("Org VDC is not enabled for Kubernetes "
                                 "cluster deployment")

        if k8s_metadata.get(K8S_PROVIDER_KEY) == K8sProvider.PKS:
            return PksBroker(k8s_metadata, tenant_auth_token)

        if k8s_metadata.get(K8S_PROVIDER_KEY) == K8sProvider.NATIVE:
            return VcdBroker(tenant_auth_token)

    return VcdBroker(tenant_auth_token)
Пример #18
0
    def _list_clusters(self):
        """Logic of the method is as follows.

        If 'ovdc' is present in the body,
            choose the right broker (by identifying the container_provider
            (vcd|pks) defined for that ovdc) to do list_clusters operation.
        Else
            Invoke set of all (vCD/PKS)brokers in the org to do list_clusters.
            Post-process the result returned by each broker.
            Aggregate all the results into one.
        """
        if self.is_ovdc_present_in_request:
            broker = self.get_broker_based_on_vdc()
            return broker.list_clusters()
        else:
            common_cluster_properties = ('name', 'vdc', 'status', 'org_name')
            vcd_broker = VcdBroker(self.req_headers, self.req_spec)
            vcd_clusters = []
            for cluster in vcd_broker.list_clusters():
                vcd_cluster = {
                    k: cluster.get(k, None)
                    for k in common_cluster_properties
                }
                vcd_cluster[K8S_PROVIDER_KEY] = K8sProviders.NATIVE
                vcd_clusters.append(vcd_cluster)

            pks_clusters = []
            pks_ctx_list = self._create_pks_context_for_all_accounts_in_org()
            for pks_ctx in pks_ctx_list:
                pks_broker = PKSBroker(self.req_headers, self.req_spec,
                                       pks_ctx)
                # Get all cluster information to get vdc name from
                # compute-profile-name
                for cluster in pks_broker.list_clusters(is_admin_request=True):
                    pks_cluster = \
                        PKSBroker.generate_cluster_subset_with_given_keys(
                            cluster, common_cluster_properties)
                    pks_cluster[K8S_PROVIDER_KEY] = K8sProviders.PKS
                    pks_clusters.append(pks_cluster)
            return vcd_clusters + pks_clusters
def node_delete(request_data, tenant_auth_token):
    """Request handler for node delete operation.

    Required data: cluster_name, node_names_list
    Optional data and default values: org_name=None, ovdc_name=None

    (data validation handled in brokers)

    :return: Dict
    """
    # Currently node delete is a vCD only operation.
    # TODO remove once resize is able to scale down native clusters
    return VcdBroker(tenant_auth_token).delete_nodes(request_data)
Пример #20
0
def get_cluster_and_broker(request_data, tenant_auth_token, is_jwt_token):
    cluster_name = request_data[RequestKey.CLUSTER_NAME]
    vcd_broker = VcdBroker(tenant_auth_token, is_jwt_token)
    try:
        return vcd_broker.get_cluster_info(request_data), vcd_broker
    except ClusterNotFoundError as err:
        # continue searching using PksBrokers
        LOGGER.debug(f"{err}")
    except CseDuplicateClusterError as err:
        # fail because multiple clusters with same name exist
        # only case is when multiple same-name clusters exist across orgs
        # and sys admin tries to do a cluster operation
        LOGGER.debug(f"{err}")
        raise
    except Exception as err:
        LOGGER.error(f"Unknown error: {err}", exc_info=True)
        raise

    pks_ctx_list = create_pks_context_for_all_accounts_in_org(
        tenant_auth_token, is_jwt_token)
    for pks_ctx in pks_ctx_list:
        debug_msg = f"Get cluster info for cluster '{cluster_name}' " \
                    f"failed on host '{pks_ctx['host']}' with error: "
        pks_broker = PksBroker(pks_ctx, tenant_auth_token, is_jwt_token)
        try:
            return pks_broker.get_cluster_info(request_data), pks_broker
        except (PksClusterNotFoundError, PksServerError) as err:
            # continue searching using other PksBrokers
            LOGGER.debug(f"{debug_msg}{err}")
        except PksDuplicateClusterError as err:
            # fail because multiple clusters with same name exist
            LOGGER.debug(f"{debug_msg}{err}")
            raise
        except Exception as err:
            LOGGER.error(f"Unknown error: {err}", exc_info=True)
            raise

    # only raised if cluster was not found in VcdBroker or PksBrokers
    raise ClusterNotFoundError(f"Cluster '{cluster_name}' not found.")
def cluster_list(request_data, op_ctx: ctx.OperationContext):
    """Request handler for cluster list operation.

    Optional data and default values: org_name=None, ovdc_name=None

    (data validation handled in broker)

    :return: List
    """
    vcd_broker = VcdBroker(op_ctx)
    vcd_clusters_info = vcd_broker.list_clusters(data=request_data)

    common_cluster_properties = [
        'name', 'vdc', 'status', 'org_name', 'k8s_version', K8S_PROVIDER_KEY
    ]

    result = []
    for cluster_info in vcd_clusters_info:
        filtered_cluster_info = \
            {k: cluster_info.get(k) for k in common_cluster_properties}
        result.append(filtered_cluster_info)

    return result
Пример #22
0
    def _list_clusters(self):
        """Logic of the method is as follows.

        If 'ovdc' is present in the body,
            choose the right broker (by identifying the container_provider
            (vcd|pks) defined for that ovdc) to do list_clusters operation.
        Else
            Invoke set of all (vCD/PKS)brokers in the org to do list_clusters.
            Post-process the result returned by each broker.
            Aggregate all the results into one.
        """
        if self.is_ovdc_present_in_request:
            broker = self.get_broker_based_on_vdc()
            return broker.list_clusters()
        else:
            common_cluster_properties = ('name', 'vdc', 'status')
            vcd_broker = VcdBroker(self.req_headers, self.req_spec)
            vcd_clusters = []
            for cluster in vcd_broker.list_clusters():
                vcd_cluster = {
                    k: cluster.get(k, None)
                    for k in common_cluster_properties
                }
                vcd_cluster[CONTAINER_PROVIDER_KEY] = CtrProvType.VCD.value
                vcd_clusters.append(vcd_cluster)

            pks_clusters = []
            pks_ctx_list = self._create_pks_context_for_all_accounts_in_org()
            for pks_ctx in pks_ctx_list:
                pks_broker = PKSBroker(self.req_headers, self.req_spec,
                                       pks_ctx)
                for cluster in pks_broker.list_clusters():
                    pks_cluster = self._get_truncated_cluster_info(
                        cluster, pks_broker, common_cluster_properties)
                    pks_cluster[CONTAINER_PROVIDER_KEY] = CtrProvType.PKS.value
                    pks_clusters.append(pks_cluster)
            return vcd_clusters + pks_clusters
def node_create(request_data, tenant_auth_token):
    """Request handler for node create operation.

    Required data: cluster_name, network_name
    Optional data and default values: org_name=None, ovdc_name=None,
        num_nodes=1, num_cpu=None, mb_memory=None, storage_profile_name=None,
        template_name=default, template_revision=default,
        ssh_key=None, rollback=True, enable_nfs=False,

    (data validation handled in brokers)

    :return: Dict
    """
    # Currently node create is a vCD only operation.
    # Different from resize because this can create nfs nodes
    return VcdBroker(tenant_auth_token).create_nodes(request_data)
Пример #24
0
    def invoke(self, op):
        """Invoke right broker(s) to perform the operation requested.

        Might result in further (pre/post)processing on the request/result(s).


        Depending on the operation requested, this method may do one or more
        of below mentioned points.
        1. Extract and construct the relevant params for the operation.
        2. Choose right broker to perform the operation/method requested.
        3. Scan through available brokers to aggregate (or) filter results.

        :param CseOperation op: Operation to be performed by one of the
            brokers.

        :return result: result of the operation.

        :rtype: dict
        """
        result = {}
        self.is_ovdc_present_in_request = bool(
            self.req_spec.get(RequestKey.OVDC_NAME))  # noqa: E501

        if op == CseOperation.CLUSTER_CONFIG:
            cluster_spec = \
                {'cluster_name': self.req_spec.get(RequestKey.CLUSTER_NAME)}
            result = self._get_cluster_config(**cluster_spec)
        elif op == CseOperation.CLUSTER_CREATE:
            # TODO(ClusterSpec) Create an inner class "ClusterSpec"
            #  in abstract_broker.py and have subclasses define and use it
            #  as instance variable.
            #  Method 'Create_cluster' in VcdBroker and PksBroker should take
            #  ClusterSpec either as a param (or)
            #  read from instance variable (if needed only).
            cluster_spec = {
                'cluster_name':
                self.req_spec.get(RequestKey.CLUSTER_NAME),
                'vdc_name':
                self.req_spec.get(RequestKey.OVDC_NAME),
                'org_name':
                self.req_spec.get(RequestKey.ORG_NAME),
                'node_count':
                self.req_spec.get(RequestKey.NUM_WORKERS),
                'storage_profile':
                self.req_spec.get(
                    RequestKey.STORAGE_PROFILE_NAME),  # noqa: E501
                'network_name':
                self.req_spec.get(RequestKey.NETWORK_NAME),
                'template':
                self.req_spec.get(RequestKey.TEMPLATE_NAME),
            }
            result = self._create_cluster(**cluster_spec)
        elif op == CseOperation.CLUSTER_DELETE:
            cluster_spec = \
                {'cluster_name': self.req_spec.get(RequestKey.CLUSTER_NAME)}
            result = self._delete_cluster(**cluster_spec)
        elif op == CseOperation.CLUSTER_INFO:
            cluster_spec = \
                {'cluster_name': self.req_spec.get(RequestKey.CLUSTER_NAME)}
            result = self._get_cluster_info(**cluster_spec)[0]
        elif op == CseOperation.CLUSTER_LIST:
            result = self._list_clusters()
        elif op == CseOperation.CLUSTER_RESIZE:
            cluster_spec = {
                'cluster_name': self.req_spec.get(RequestKey.CLUSTER_NAME),
                'node_count': self.req_spec.get(RequestKey.NUM_WORKERS)
            }
            result = self._resize_cluster(**cluster_spec)
        elif op == CseOperation.NODE_CREATE:
            # Currently node create is a vCD only operation.
            broker = VcdBroker(self.tenant_auth_token, self.req_spec)
            result = broker.create_nodes()
        elif op == CseOperation.NODE_DELETE:
            # Currently node delete is a vCD only operation.
            broker = VcdBroker(self.tenant_auth_token, self.req_spec)
            result = broker.delete_nodes()
        elif op == CseOperation.NODE_INFO:
            cluster_name = self.req_spec.get(RequestKey.CLUSTER_NAME)
            node_name = self.req_spec.get(RequestKey.NODE_NAME)
            # Currently node info is a vCD only operation.
            broker = VcdBroker(self.tenant_auth_token, self.req_spec)
            result = broker.get_node_info(cluster_name, node_name)

        return result
 def list_clusters(self):
     vcd_broker = VcdBroker(self.tenant_auth_token, self.req_spec)
     vcd_clusters = []
     for cluster in vcd_broker.list_clusters():
         vcd_clusters.append(cluster)
     return vcd_clusters