Exemple #1
0
    def list_clusters(self):
        """Get list of clusters ((TODO)for a given vCD user) in PKS environment.

        :return: a list of cluster-dictionaries

        :rtype: list
        """
        result = {}
        result['body'] = []
        result['status_code'] = OK
        cluster_api = ClusterApi(api_client=self.pks_client)

        LOGGER.debug(f'Sending request to PKS: {self.host} '
                     f'to list all clusters')

        clusters = cluster_api.list_clusters()
        list_of_cluster_dicts = []
        for cluster in clusters:
            cluster_dict = {
                'name': cluster.name,
                'plan-name': cluster.plan_name,
                'uuid': cluster.uuid,
                'status': cluster.last_action_state,
                'last-action': cluster.last_action,
                'k8_master_ips': cluster.kubernetes_master_ips
            }
            list_of_cluster_dicts.append(cluster_dict)

        LOGGER.debug(f'Received response from PKS: {self.host} on the list of '
                     f'clusters: {list_of_cluster_dicts}')

        result['body'] = list_of_cluster_dicts
        return result
    def _get_cluster_info(self, cluster_name):
        """Get the details of a cluster with a given name in PKS environment.

        :param str cluster_name: Name of the cluster
        :return: Details of the cluster.

        :rtype: dict
        """
        cluster_api = ClusterApi(api_client=self.pks_client)

        LOGGER.debug(f"Sending request to PKS: {self.pks_host_uri} to get "
                     f"details of cluster with name: {cluster_name}")
        try:
            cluster = cluster_api.get_cluster(cluster_name=cluster_name)
        except ApiException as err:
            LOGGER.debug(f"Getting cluster info on {cluster_name} failed with "
                         f"error:\n {err}")
            raise PksServerError(err.status, err.body)
        cluster_dict = cluster.to_dict()
        cluster_params_dict = cluster_dict.pop('parameters')
        cluster_dict.update(cluster_params_dict)

        LOGGER.debug(f"Received response from PKS: {self.pks_host_uri} on "
                     f"cluster: {cluster_name} with details: {cluster_dict}")

        return cluster_dict
Exemple #3
0
    def get_cluster_config(self, data):
        """Get the configuration of the cluster with the given name in PKS.

        System administrator gets the given cluster config regardless of
        who is the owner of the cluster. Other users get config only on
        the cluster they own.

        :return: Configuration of the cluster.

        :rtype: str
        """
        cluster_name = data[RequestKey.CLUSTER_NAME]

        if self.tenant_client.is_sysadmin() or \
                is_org_admin(self.client_session):
            cluster_info = self._get_cluster_info(data)
            qualified_cluster_name = cluster_info['pks_cluster_name']
        else:
            qualified_cluster_name = self._append_user_id(cluster_name)

        self._check_cluster_isolation(cluster_name, qualified_cluster_name)

        cluster_api = ClusterApi(api_client=self.client)

        LOGGER.debug(f"Sending request to PKS: {self.pks_host_uri} to get"
                     f" kubectl configuration of cluster with name: "
                     f"{qualified_cluster_name}")
        config = cluster_api.create_user(cluster_name=qualified_cluster_name)
        LOGGER.debug(f"Received response from PKS: {self.pks_host_uri} on "
                     f"cluster: {qualified_cluster_name} with details: "
                     f"{config}")
        cluster_config = yaml.safe_dump(config, default_flow_style=False)

        return self.filter_traces_of_user_context(cluster_config)
    def _resize_cluster(self, cluster_name, node_count, **kwargs):
        """Resize the cluster of a given name to given number of worker nodes.

        :param str cluster_name: Name of the cluster
        :param int node_count: New size of the worker nodes
        """
        result = {}
        cluster_api = ClusterApi(api_client=self.pks_client)
        LOGGER.debug(f"Sending request to PKS:{self.pks_host_uri} to resize "
                     f"the cluster with name: {cluster_name} to "
                     f"{node_count} worker nodes")

        resize_params = UpdateClusterParameters(
            kubernetes_worker_instances=node_count)
        try:
            cluster_api.update_cluster(cluster_name, body=resize_params)
        except ApiException as err:
            LOGGER.debug(f"Resizing cluster {cluster_name} failed with "
                         f"error:\n {err}")
            raise PksServerError(err.status, err.body)

        LOGGER.debug(f"PKS: {self.pks_host_uri} accepted the request to resize"
                     f" the cluster: {cluster_name}")

        result['cluster_name'] = cluster_name
        result['task_status'] = 'in progress'

        return result
Exemple #5
0
    def resize_cluster(self, name, num_worker_nodes):
        """Resize the cluster of a given name to given number of worker nodes.

        :param str name: Name of the cluster
        :param int num_worker_nodes: New size of the worker nodes
        (should be greater than the current number).
        :return: None
        """
        result = {}
        result['body'] = []
        cluster_api = ClusterApi(api_client=self.pks_client)

        LOGGER.debug(f'Sending request to PKS:{self.host} to resize the '
                     f'cluster with name: {name} to '
                     f'{num_worker_nodes} worker nodes')

        resize_params = UpdateClusterParameters(
            kubernetes_worker_instances=num_worker_nodes)
        cluster_api.update_cluster(name, body=resize_params)

        LOGGER.debug(f'PKS: {self.host} accepted the request to resize the '
                     f'cluster: {name}')

        result['status_code'] = ACCEPTED
        return result
Exemple #6
0
    def get_cluster_info(self, name):
        """Get the details of a cluster with a given name in PKS environment.

        :param str name: Name of the cluster
        :return: Details of the cluster.

        :rtype: dict
        """
        result = {}
        result['body'] = []
        result['status_code'] = OK
        cluster_api = ClusterApi(api_client=self.pks_client)

        LOGGER.debug(f'Sending request to PKS: {self.host} to get details'
                     f' of cluster with name: {name}')

        cluster = cluster_api.get_cluster(cluster_name=name)
        cluster_dict = cluster.to_dict()
        cluster_params_dict = cluster_dict.pop('parameters')
        cluster_dict.update(cluster_params_dict)

        LOGGER.debug(f'Received response from PKS: {self.host} on cluster:'
                     f' {name} with details: {cluster_dict}')

        result['body'] = cluster_dict
        return result
    def _list_clusters(self, data):
        """."""
        result = []
        try:
            cluster_api = ClusterApi(api_client=self.pks_client)

            self.pks_wire_logger.debug(
                f"Sending request to PKS: {self.pks_host_uri} "
                "to list all clusters")
            pks_clusters = cluster_api.list_clusters()
            self.pks_wire_logger.debug(
                f"Received response from PKS: {self.pks_host_uri} "
                f"on the list of clusters: {pks_clusters}")

            for pks_cluster in pks_clusters:
                cluster_info = pks_cluster.to_dict()
                cluster_info[K8S_PROVIDER_KEY] = K8sProvider.PKS
                self._restore_original_name(cluster_info)
                # Flatten the nested 'parameters' dict
                cluster_params_dict = cluster_info.pop('parameters')
                cluster_info.update(cluster_params_dict)
                self.update_cluster_with_vcd_info(cluster_info)
                result.append(cluster_info)
        except ApiException as err:
            SERVER_LOGGER.debug(
                f"Listing PKS clusters failed with error:\n {err}"
            )  # noqa: E501
            raise PksServerError(err.status, err.body)

        return self._filter_clusters(result, **data)
    def _delete_cluster(self, cluster_name):
        """Delete the cluster with a given name in PKS environment.

        :param str cluster_name: Name of the cluster
        """
        result = {}

        cluster_api = ClusterApi(api_client=self.pks_client)

        LOGGER.debug(f"Sending request to PKS: {self.pks_host_uri} to delete "
                     f"the cluster with name: {cluster_name}")
        try:
            cluster_api.delete_cluster(cluster_name=cluster_name)
        except ApiException as err:
            LOGGER.debug(f"Deleting cluster {cluster_name} failed with "
                         f"error:\n {err}")
            raise PksServerError(err.status, err.body)

        # TODO() access self.pks_ctx and get hold of nst_info to cleanup dfw
        # rules
        LOGGER.debug(f"PKS: {self.pks_host_uri} accepted the request to delete"
                     f" the cluster: {cluster_name}")

        result = {}
        result['cluster_name'] = cluster_name
        result['task_status'] = 'in progress'
        return result
    def _list_clusters(self):
        """Get list of clusters in PKS environment.

        :return: a list of cluster-dictionaries

        :rtype: list
        """
        cluster_api = ClusterApi(api_client=self.pks_client)

        LOGGER.debug(f"Sending request to PKS: {self.pks_host_uri} "
                     f"to list all clusters")
        try:
            clusters = cluster_api.list_clusters()
        except ApiException as err:
            LOGGER.debug(f"Listing PKS clusters failed with error:\n {err}")
            raise PksServerError(err.status, err.body)

        list_of_cluster_dicts = []
        for cluster in clusters:
            cluster_dict = {
                'name': cluster.name,
                'plan-name': cluster.plan_name,
                'uuid': cluster.uuid,
                'status': cluster.last_action_state,
                'last-action': cluster.last_action,
                'k8_master_ips': cluster.kubernetes_master_ips,
                'compute-profile-name': cluster.compute_profile_name,
                'worker_count': cluster.parameters.kubernetes_worker_instances
            }
            list_of_cluster_dicts.append(cluster_dict)

        LOGGER.debug(f"Received response from PKS: {self.pks_host_uri} on the"
                     f" list of clusters: {list_of_cluster_dicts}")
        return list_of_cluster_dicts
    def _create_cluster(self,
                        cluster_name,
                        node_count,
                        pks_plan,
                        pks_ext_host,
                        compute_profile=None,
                        **kwargs):
        """Create cluster in PKS environment.

        :param str cluster_name: Name of the cluster
        :param str plan: PKS plan. It should be one of the three plans
        that PKS supports.
        :param str external_host_name: User-preferred external hostname
         of the K8 cluster
        :param str compute_profile: Name of the compute profile

        :return: Details of the cluster

        :rtype: dict
        """
        # 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).

        compute_profile = compute_profile \
            if compute_profile else self.compute_profile
        cluster_api = ClusterApi(api_client=self.pks_client)
        cluster_params = \
            ClusterParameters(kubernetes_master_host=pks_ext_host,
                              kubernetes_worker_instances=node_count)
        cluster_request = ClusterRequest(name=cluster_name,
                                         plan_name=pks_plan,
                                         parameters=cluster_params,
                                         compute_profile_name=compute_profile)

        LOGGER.debug(f"Sending request to PKS: {self.pks_host_uri} to create "
                     f"cluster of name: {cluster_name}")
        try:
            cluster = cluster_api.add_cluster(cluster_request)
        except ApiException as err:
            LOGGER.debug(f"Creating cluster {cluster_name} in PKS failed with "
                         f"error:\n {err}")
            raise PksServerError(err.status, err.body)
        cluster_dict = cluster.to_dict()
        # Flattening the dictionary
        cluster_params_dict = cluster_dict.pop('parameters')
        cluster_dict.update(cluster_params_dict)

        LOGGER.debug(f"PKS: {self.pks_host_uri} accepted the request to create"
                     f" cluster: {cluster_name}")
        # TODO() access self.pks_ctx to get hold of nsxt_info and create dfw
        # rules
        return cluster_dict
Exemple #11
0
    def delete_cluster(self, data):
        """Delete the cluster with a given name in PKS environment.

        System administrator can delete the given cluster regardless of
        who is the owner of the cluster. Other users can only delete
        the cluster they own.

        :param str cluster_name: Name of the cluster
        """
        cluster_name = data[RequestKey.CLUSTER_NAME]

        if self.tenant_client.is_sysadmin() \
                or is_org_admin(self.client_session):
            cluster_info = self._get_cluster_info(data)
            qualified_cluster_name = cluster_info['pks_cluster_name']
        else:
            qualified_cluster_name = self._append_user_id(cluster_name)

        result = {}
        cluster_api = ClusterApi(api_client=self.client)

        try:
            LOGGER.debug(
                f"Sending request to PKS: {self.pks_host_uri} to delete "
                f"the cluster with name: {qualified_cluster_name}")
            cluster_api.delete_cluster(cluster_name=qualified_cluster_name)

            LOGGER.debug(
                f"PKS: {self.pks_host_uri} accepted the request to delete"
                f" the cluster: {qualified_cluster_name}")
        except ApiException as err:
            LOGGER.debug(f"Deleting cluster {qualified_cluster_name} failed"
                         f" with error:\n {err}")
            raise PksServerError(err.status, err.body)

        result['name'] = qualified_cluster_name
        result['task_status'] = 'in progress'

        # remove cluster network isolation
        LOGGER.debug("Removing network isolation of cluster "
                     f"{qualified_cluster_name}.")
        try:
            cluster_network_isolater = ClusterNetworkIsolater(self.nsxt_client)
            cluster_network_isolater.remove_cluster_isolation(
                qualified_cluster_name)
        except Exception as err:
            # NSX-T oprations are idempotent so they should not cause erros
            # if say NSGroup is missing. But for any other exception, simply
            # catch them and ignore.
            LOGGER.debug(f"Error {err} occured while deleting cluster "
                         "isolation rules for cluster "
                         f"{qualified_cluster_name}")

        return result
    def resize_cluster(self, **kwargs):
        """Resize the cluster of a given name to given number of worker nodes.

        System administrator can resize the given cluster regardless of
        who is the owner of the cluster. Other users can only resize
        the cluster they own.


        :return: response status

        :rtype: dict

        """
        data = kwargs[KwargKey.DATA]
        cluster_name = data[RequestKey.CLUSTER_NAME]
        num_workers = data[RequestKey.NUM_WORKERS]

        qualified_cluster_name = self._append_user_id(cluster_name)
        if (self.context.client.is_sysadmin()
                or self.context.user.has_org_admin_rights):
            cluster_info = self._get_cluster_info(data)
            qualified_cluster_name = cluster_info['pks_cluster_name']

        self._check_cluster_isolation(cluster_name, qualified_cluster_name)

        result = {}
        cluster_api = ClusterApi(api_client=self.pks_client)
        self.pks_wire_logger.debug(f"Sending request to"
                                   f" PKS:{self.pks_host_uri} to resize"
                                   f" the cluster with name:"
                                   f"{qualified_cluster_name} to"
                                   f" {num_workers} worker nodes")
        resize_params = \
            UpdateClusterParameters(kubernetes_worker_instances=num_workers)
        try:
            cluster_api.update_cluster(qualified_cluster_name,
                                       body=resize_params)
        except ApiException as err:
            SERVER_LOGGER.debug(f"Resizing cluster {qualified_cluster_name}"
                                f" failed with error:\n {err}")
            raise PksServerError(err.status, err.body)
        self.pks_wire_logger.debug(f"PKS: {self.pks_host_uri} accepted the"
                                   f" request to resize the cluster: "
                                   f" {qualified_cluster_name}")

        result['name'] = qualified_cluster_name
        result['task_status'] = 'in progress'
        self._restore_original_name(result)
        if not self.context.client.is_sysadmin():
            self._filter_sensitive_pks_properties(result)
        return result
Exemple #13
0
    def _create_cluster(self, *args, cluster_name, num_workers, pks_plan_name,
                        pks_ext_host):
        """Create cluster in PKS environment.

        Creates Distributed Firewall rules in NSX-T to isolate the cluster
        network from other clusters.

        :param str cluster_name: Name of the cluster
        :param str plan: PKS plan. It should be one of the three plans
        that PKS supports.
        :param str external_host_name: User-preferred external hostname
         of the K8 cluster

        :return: Details of the cluster

        :rtype: dict
        """
        cluster_api = ClusterApi(api_client=self.client)
        cluster_params = \
            ClusterParameters(kubernetes_master_host=pks_ext_host,
                              kubernetes_worker_instances=num_workers)
        cluster_request = \
            ClusterRequest(name=cluster_name,
                           plan_name=pks_plan_name,
                           parameters=cluster_params,
                           compute_profile_name=self.compute_profile)

        try:
            LOGGER.debug(
                f"Sending request to PKS: {self.pks_host_uri} to create "
                f"cluster of name: {cluster_name}")

            cluster = cluster_api.add_cluster(cluster_request)

            LOGGER.debug(
                f"PKS: {self.pks_host_uri} accepted the request to create"
                f" cluster: {cluster_name}")
        except ApiException as err:
            LOGGER.debug(f"Creating cluster {cluster_name} in PKS failed with "
                         f"error:\n {err}")
            raise PksServerError(err.status, err.body)

        cluster_info = cluster.to_dict()
        # Flattening the dictionary
        cluster_params_dict = cluster_info.pop('parameters')
        cluster_info.update(cluster_params_dict)

        return cluster_info
Exemple #14
0
    def create_cluster(self,
                       name,
                       plan,
                       external_host_name='cluster.pks.local',
                       network_profile=None,
                       compute_profile=None):
        """Create cluster in PKS environment.

        :param str name: Name of the cluster
        :param str plan: PKS plan. It should be one of {Plan 1, Plan 2, Plan 3}
        that PKS supports.
        :param str external_host_name: User-preferred external hostname
         of the K8 cluster
        :param str network_profile: Name of the network profile
        :param str compute_profile: Name of the compute profile

        :return: Details of the cluster.

        :rtype: dict
        """
        # TODO() Invalidate cluster names containing '-' character.
        result = {}
        result['body'] = []
        cluster_api = ClusterApi(api_client=self.pks_client)
        cluster_params = ClusterParameters(
            kubernetes_master_host=external_host_name,
            nsxt_network_profile=network_profile,
            compute_profile=compute_profile)
        cluster_request = ClusterRequest(name=name,
                                         plan_name=plan,
                                         parameters=cluster_params)

        LOGGER.debug(f'Sending request to PKS: {self.host} to create cluster'
                     f' of name: {name}')

        cluster = cluster_api.add_cluster(cluster_request)
        cluster_dict = cluster.to_dict()
        cluster_params_dict = cluster_dict.pop('parameters')
        cluster_dict.update(cluster_params_dict)

        LOGGER.debug(f'PKS: {self.host} accepted the request to create'
                     f' cluster: {name}')

        result['body'] = cluster_dict
        result['status_code'] = ACCEPTED
        return result
    def _get_cluster_config(self, cluster_name):
        """Get the configuration of the cluster with the given name in PKS.

        :param str cluster_name: Name of the cluster
        :return: Configuration of the cluster.

        :rtype: str
        """
        cluster_api = ClusterApi(api_client=self.pks_client)

        LOGGER.debug(f"Sending request to PKS: {self.pks_host_uri} to get"
                     f" detailed configuration of cluster with name: "
                     f"{cluster_name}")
        config = cluster_api.create_user(cluster_name=cluster_name)

        LOGGER.debug(f"Received response from PKS: {self.pks_host_uri} on "
                     f"cluster: {cluster_name} with details: {config}")
        cluster_config = yaml.safe_dump(config, default_flow_style=False)
        return cluster_config
Exemple #16
0
    def delete_cluster(self, name):
        """Delete the cluster with a given name in PKS environment.

        :param str name: Name of the cluster
        :return: None
        """
        result = {}
        result['body'] = []
        cluster_api = ClusterApi(api_client=self.pks_client)

        LOGGER.debug(f'Sending request to PKS: {self.host} to delete the '
                     f'cluster with name: {name}')

        cluster_api.delete_cluster(cluster_name=name)

        LOGGER.debug(f'PKS: {self.host} accepted the request to delete the '
                     f'cluster: {name}')

        result['status_code'] = ACCEPTED
        return result
    def get_cluster_config(self, **kwargs):
        """Get the configuration of the cluster with the given name in PKS.

        System administrator gets the given cluster config regardless of
        who is the owner of the cluster. Other users get config only on
        the cluster they own.

        :return: Configuration of the cluster.

        :rtype: str
        """
        data = kwargs[KwargKey.DATA]
        cluster_name = data[RequestKey.CLUSTER_NAME]

        qualified_cluster_name = self._append_user_id(cluster_name)
        if (self.context.client.is_sysadmin()
                or self.context.user.has_org_admin_rights):
            cluster_info = self._get_cluster_info(data)
            qualified_cluster_name = cluster_info['pks_cluster_name']

        self._check_cluster_isolation(cluster_name, qualified_cluster_name)

        cluster_api = ClusterApi(api_client=self.pks_client)

        self.pks_wire_logger.debug(
            f"Sending request to PKS: {self.pks_host_uri} to get"  # noqa: E501
            f" kubectl configuration of cluster with name: "  # noqa: E501
            f"{qualified_cluster_name}")
        config = cluster_api.create_user(cluster_name=qualified_cluster_name)
        self.pks_wire_logger.debug(
            f"Received response from PKS: {self.pks_host_uri} on "  # noqa: E501
            f"cluster: {qualified_cluster_name} with details: "  # noqa: E501
            f"{config}")
        cluster_config = yaml.safe_dump(config, default_flow_style=False)

        return self.filter_traces_of_user_context(cluster_config)