def create_endpoint(parameters: dict, namespace: str, id_token: str): if not tenant_exists(namespace, id_token=id_token): raise TenantDoesNotExistException(tenant_name=namespace) metadata = {"name": parameters['endpointName']} body = {"apiVersion": CRD_API_VERSION, "kind": CRD_KIND, "spec": parameters, "metadata": metadata} api_instance = get_k8s_api_client(id_token) if 'resources' in parameters: validate_quota_compliance(api_instance, namespace=namespace, endpoint_quota=parameters['resources']) parameters['resources'] = transform_quota(parameters['resources']) apps_api_instance = get_k8s_apps_api_client(id_token) verify_endpoint_amount(api_instance, apps_api_instance, namespace) custom_obj_api_instance = get_k8s_api_custom_client(id_token) try: custom_obj_api_instance.create_namespaced_custom_object(CRD_GROUP, CRD_VERSION, namespace, CRD_PLURAL, body) except ApiException as apiException: raise KubernetesCreateException('endpoint', apiException) endpoint_url = create_url_to_service(parameters['endpointName'], namespace) logger.info('Endpoint {} created\n'.format(endpoint_url)) return endpoint_url
def view_endpoint(endpoint_name: str, namespace: str, id_token: str): if not tenant_exists(namespace, id_token=id_token): raise TenantDoesNotExistException(tenant_name=namespace) if not endpoint_exists(endpoint_name, namespace, id_token): raise EndpointDoesNotExistException(endpoint_name=endpoint_name) custom_api_instance = get_k8s_api_custom_client(id_token) api_instance = get_k8s_api_client(id_token) apps_api_instance = get_k8s_apps_api_client(id_token) endpoint_status = get_endpoint_status(api_instance=api_instance, namespace=namespace, endpoint_name=endpoint_name) model_path = create_url_to_service(endpoint_name, namespace) subject_name, resources = get_crd_subject_name_and_resources( custom_api_instance=custom_api_instance, namespace=namespace, endpoint_name=endpoint_name) replicas = get_replicas(apps_api_instance=apps_api_instance, namespace=namespace, endpoint_name=endpoint_name) view_dict = {'Endpoint status': endpoint_status, 'Model path': model_path, 'Subject name': subject_name, 'Resources': resources, 'Replicas': replicas, } message = f"Endpoint {endpoint_name} in {namespace} tenant: {view_dict}\n" logger.info(message) return message
def list_tenants(id_token): tenants = [] api_instance = get_k8s_api_client(id_token) label = f'created_by = {PLATFORM_ADMIN_LABEL}' namespaces = {} try: namespaces = api_instance.list_namespace(label_selector=label) except ApiException as apiException: KubernetesGetException('namespaces', apiException) for item in namespaces.to_dict()['items']: if item['status']['phase'] != TERMINATION_IN_PROGRESS: tenants.append(item['metadata']['name']) return tenants
def is_namespace_available(namespace, id_token): api_instance = get_k8s_api_client(id_token) try: response = api_instance.read_namespace_status(namespace) except ApiException as apiException: if apiException.status == RESOURCE_DOES_NOT_EXIST: return False if apiException.status == K8S_FORBIDDEN: raise KubernetesForbiddenException('forbidden', apiException) raise KubernetesGetException('namespace status', apiException) if response and response.status.phase == TERMINATION_IN_PROGRESS: return False return True
def create_resource_quota(name, quota, id_token): name_object = k8s_client.V1ObjectMeta(name=name) resource_quota_spec = k8s_client.V1ResourceQuotaSpec(hard=quota) body = k8s_client.V1ResourceQuota(spec=resource_quota_spec, metadata=name_object) api_instance = get_k8s_api_client(id_token) try: response = api_instance.create_namespaced_resource_quota(name, body) except ApiException as apiException: raise KubernetesCreateException('resource_quota', apiException) logger.info("Resource quota {} created".format(quota)) return response
def list_servings(id_token): if not is_namespace_available(CRD_NAMESPACE, id_token): raise ResourceIsNotAvailableException('namespace', CRD_NAMESPACE) api_client = get_k8s_api_client(id_token) try: config_maps = api_client.list_namespaced_config_map(CRD_NAMESPACE, pretty='true') except ApiException as apiException: raise KubernetesGetException('config map', apiException) crd_config_maps = [] for item in config_maps.to_dict()['items']: crd_config_maps.append(item['metadata']['name']) return crd_config_maps
def create_secret(name, cert, id_token): cert_secret_metadata = k8s_client.V1ObjectMeta(name=CERT_SECRET_NAME) cert_secret_data = {"ca.crt": cert} cert_secret = k8s_client.V1Secret(api_version="v1", data=cert_secret_data, kind="Secret", metadata=cert_secret_metadata, type="Opaque") api_instance = get_k8s_api_client(id_token) try: response = api_instance.create_namespaced_secret(namespace=name, body=cert_secret) except ApiException as apiException: raise KubernetesCreateException('secret', apiException) logger.info('Secret {} created'.format(CERT_SECRET_NAME)) return response
def create_namespace(name, quota, id_token): annotations = None if 'maxEndpoints' in quota: annotations = {'maxEndpoints': str(quota.pop('maxEndpoints'))} name_object = k8s_client.V1ObjectMeta( name=name, annotations=annotations, labels={'created_by': PLATFORM_ADMIN_LABEL}) namespace = k8s_client.V1Namespace(metadata=name_object) api_instance = get_k8s_api_client(id_token=id_token) try: response = api_instance.create_namespace(namespace) except ApiException as apiException: raise KubernetesCreateException('namespace', apiException) logger.info("Namespace {} created".format(name)) return response
def propagate_secret(source_secret_path, target_namespace, id_token): source_secret_namespace, source_secret_name = source_secret_path.split('/') api_instance = get_k8s_api_client(id_token) try: source_secret = api_instance.read_namespaced_secret( source_secret_name, source_secret_namespace) except ApiException as apiException: raise KubernetesGetException('secret', apiException) source_secret.metadata.namespace = target_namespace source_secret.metadata.resource_version = None try: api_instance.create_namespaced_secret(namespace=target_namespace, body=source_secret) except ApiException as apiException: raise KubernetesCreateException('secret', apiException)
def get_serving(id_token, serving_name): if not is_namespace_available(CRD_NAMESPACE, id_token): raise ResourceIsNotAvailableException('namespace', CRD_NAMESPACE) api_client = get_k8s_api_client(id_token) try: config_map = api_client.read_namespaced_config_map(serving_name, CRD_NAMESPACE, pretty='true') except ApiException as apiException: raise KubernetesGetException('config map', apiException) crd_config_map = dict() try: crd_config_map = config_map.to_dict()['data'] except KeyError: raise ResourceIsNotAvailableException('serving template configuration', serving_name) return crd_config_map
def delete_namespace(name, id_token): body = k8s_client.V1DeleteOptions() response = 'Namespace {} does not exist'.format(name) api_instance = get_k8s_api_client(id_token) existed = True try: response = api_instance.delete_namespace(name, body) except ApiException as apiException: if apiException.status != RESOURCE_DOES_NOT_EXIST and \ apiException.status != NAMESPACE_BEING_DELETED: raise KubernetesDeleteException('namespace', apiException) existed = False if existed: logger.info('Namespace {} deleted'.format(name)) else: logger.info('Namespace {} does not exist'.format(name)) return response
def list_tenants(id_token): tenants = [] api_instance = get_k8s_api_client(id_token) label = f'created_by = {PLATFORM_ADMIN}' namespaces = {} try: namespaces = api_instance.list_namespace(label_selector=label) except ApiException as apiException: KubernetesGetException('namespaces', apiException) for item in namespaces.to_dict()['items']: if item['status']['phase'] != TERMINATION_IN_PROGRESS: tenants.append(item['metadata']['name']) if not tenants: message = "There's no tenants present on platform\n" logger.info(message) return message message = f"Tenants present on platform: {tenants}\n" logger.info(message) return message