def _check_cluster_isolation(self, cluster_name, qualified_cluster_name): cluster_network_isolater = ClusterNetworkIsolater(self.nsxt_client) if not cluster_network_isolater.is_cluster_isolated( qualified_cluster_name): raise ClusterNetworkIsolationError( f"Cluster '{cluster_name}' is in an unusable state. Please " "delete it and redeploy.")
def delete_cluster(self, cluster_name): """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 """ if self.tenant_client.is_sysadmin() \ or is_org_admin(self.client_session): cluster_info = self.get_cluster_info(cluster_name) qualified_cluster_name = cluster_info['pks_cluster_name'] else: qualified_cluster_name = self._append_user_id(cluster_name) result = self._delete_cluster(qualified_cluster_name) # remove cluster network isolation LOGGER.debug(f"Removing network isolation of cluster {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 " f"isolation rules for cluster {cluster_name}") self._restore_original_name(result) self._filter_pks_properties(result) return result
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 _isolate_cluster(self, cluster_name, qualified_cluster_name, cluster_id): if not cluster_id: raise ValueError( f"Invalid cluster_id for cluster : '{cluster_name}'") LOGGER.debug(f"Isolating network of cluster {cluster_name}.") try: cluster_network_isolater = ClusterNetworkIsolater(self.nsxt_client) cluster_network_isolater.isolate_cluster(qualified_cluster_name, cluster_id) except Exception as err: raise ClusterNetworkIsolationError( f"Cluster : '{cluster_name}' is in an unusable state. Failed " "to isolate cluster network") from err
def _delete_cluster(self, cluster_name): """Delete the cluster with a given name in PKS environment. Also deletes associated NSX-T Distributed Firewall rules that kept the cluster network isolated from other clusters. :param str cluster_name: Name of the cluster """ result = {} cluster_api = ClusterApiV1(api_client=self.client_v1) 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 v1Exception as err: LOGGER.debug(f"Deleting 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 delete" f" the cluster: {cluster_name}") # remove cluster network isolation try: LOGGER.debug("Removing network isolation of cluster " f"{cluster_name}.") cluster_network_isolater = ClusterNetworkIsolater(self.nsxt_client) cluster_network_isolater.remove_cluster_isolation(cluster_name) except Exception: # NSX-T oprations are idempotent so they should not cause erros # if say NSGroup is missing. But for any other exception, simply # them and ignore. pass result['cluster_name'] = cluster_name result['task_status'] = 'in progress' return result
def _create_cluster(self, cluster_name, node_count, pks_plan, pks_ext_host, compute_profile=None, **kwargs): """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 :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). if not self.nsxt_server: raise CseServerError( "NSX-T server details not found for PKS server selected for " f"cluster : {cluster_name}. Aborting creation of cluster.") compute_profile = compute_profile \ if compute_profile else self.compute_profile cluster_api = ClusterApiV1Beta(api_client=self.client_v1beta) 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 v1BetaException 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() : Rollback cluster if any error is encountered in this section # isolate cluster via NSX-T DFW try: cluster_id = cluster_dict.get('uuid') if cluster_id: LOGGER.debug(f"Isolating network of cluster {cluster_name}.") cluster_network_isolater = ClusterNetworkIsolater( self.nsxt_client) cluster_network_isolater.isolate_cluster( cluster_name, cluster_id) else: raise CseServerError("Failed to isolate network of cluster " f"{cluster_name}. Cluster ID not found.") except Exception as err: raise CseServerError("Failed to isolate network of cluster " f"{cluster_name} : Aborting creation of " "cluster.") from err return cluster_dict