def create_ingress(extensions_v1_beta1: ExtensionsV1beta1Api, namespace, body) -> str: """ Create an ingress based on a dict. :param extensions_v1_beta1: ExtensionsV1beta1Api :param namespace: namespace name :param body: a dict :return: str """ print("Create an ingress:") extensions_v1_beta1.create_namespaced_ingress(namespace, body) print(f"Ingress created with name '{body['metadata']['name']}'") return body['metadata']['name']
def create_daemon_set(extensions_v1_beta1: ExtensionsV1beta1Api, namespace, body) -> str: """ Create a daemon-set based on a dict. :param extensions_v1_beta1: ExtensionsV1beta1Api :param namespace: namespace name :param body: dict :return: str """ print("Create a daemon-set:") extensions_v1_beta1.create_namespaced_daemon_set(namespace, body) print(f"Daemon-Set created with name '{body['metadata']['name']}'") return body['metadata']['name']
def delete_ingress(extensions_v1_beta1: ExtensionsV1beta1Api, name, namespace) -> None: """ Delete an ingress. :param extensions_v1_beta1: ExtensionsV1beta1Api :param namespace: namespace :param name: :return: """ print(f"Delete an ingress: {name}") delete_options = client.V1DeleteOptions() extensions_v1_beta1.delete_namespaced_ingress(name, namespace, delete_options) ensure_item_removal(extensions_v1_beta1.read_namespaced_ingress, name, namespace) print(f"Ingress was removed with name '{name}'")
async def k8s_get_ingress(namespace: str, name: str) -> Optional[ExtensionsV1beta1Ingress]: ingresses = ExtensionsV1beta1Api().list_namespaced_ingress( namespace=namespace) ingress = next((i for i in ingresses.items if i.metadata.name == name), None) return ingress
def delete_daemon_set(extensions_v1_beta1: ExtensionsV1beta1Api, name, namespace) -> None: """ Delete a daemon-set. :param extensions_v1_beta1: ExtensionsV1beta1Api :param name: :param namespace: :return: """ print(f"Delete a daemon-set: {name}") delete_options = client.V1DeleteOptions() delete_options.grace_period_seconds = 0 delete_options.propagation_policy = 'Foreground' extensions_v1_beta1.delete_namespaced_daemon_set(name, namespace, delete_options) ensure_item_removal(extensions_v1_beta1.read_namespaced_daemon_set_status, name, namespace) print(f"Daemon-set was removed with name '{name}'")
def replace_ingress(extensions_v1_beta1: ExtensionsV1beta1Api, name, namespace, body) -> str: """ Replace an Ingress based on a dict. :param extensions_v1_beta1: ExtensionsV1beta1Api :param name: :param namespace: namespace :param body: dict :return: str """ print(f"Replace a Ingress: {name}") resp = extensions_v1_beta1.replace_namespaced_ingress(name, namespace, body) print(f"Ingress replaced with name '{name}'") return resp.metadata.name
def test_service_apis(self, k8s: client.ExtensionsV1beta1Api): name = 'test-' + str(uuid.uuid4()) service_manifest = {'apiVersion': 'v1', 'kind': 'Service', 'metadata': {'labels': {'name': name}, 'name': name, 'resourceversion': 'v1'}, 'spec': {'ports': [{'name': 'port', 'port': 80, 'protocol': 'TCP', 'targetPort': 80}], 'selector': {'name': name}}} resp = k8s.create_namespaced_service(body=service_manifest, namespace='default') assert name == resp.metadata.name # assert resp.status == 'Pending' resp = k8s.read_namespaced_service(name=name, namespace='default') assert name == resp.metadata.name # assert resp.status is True # service_manifest['spec']['ports'] = [{'name': 'new', # 'port': 8080, # 'protocol': 'TCP', # 'targetPort': 8080}] # resp = k8s.patch_namespaced_service(body=service_manifest, # name=name, # namespace='default') # assert 2 == len(resp.spec.ports) # assert resp.status is True resp = k8s.delete_namespaced_service(name=name, namespace='default')
def get_user_vnc_pod(uuid, user): extension_api = ExtensionsV1beta1Api(get_kubernetes_api_client()) app_api = AppsV1Api(get_kubernetes_api_client()) core_api = CoreV1Api(get_kubernetes_api_client()) result = {} has_deployment = False user_vnc = None try: setting = TaskSettings.objects.get(uuid=uuid) user_vnc, _ = TaskVNCPod.objects.get_or_create( settings=setting, user=user, defaults={ 'settings': setting, 'user': user, 'pod_name': '', 'url_path': '', 'vnc_password': '', 'expire_time': round(time.time() + USER_SPACE_POD_TIMEOUT) }) _, created = TaskStorage.objects.get_or_create(settings=setting, user=user, defaults={ 'settings': setting, 'user': user, 'pod_name': '' }) if user_vnc.pod_name: try: # check whether deployment is on has_deployment = True _ = app_api.read_namespaced_deployment( name=user_vnc.pod_name, namespace=KUBERNETES_NAMESPACE) except ApiException as ex: if ex.status != 404: LOGGER.exception(ex) else: has_deployment = False selector = "task-{}-user-{}-vnc".format(setting.uuid, user.id) if not has_deployment: # create a new deployment conf = json.loads(setting.container_config) user_dir = "user_{}_task_{}".format(user.id, setting.id) dep_name = "task-vnc-{}-{}".format(setting.uuid, get_short_uuid()) shared_pvc_name = "shared-{}".format(setting.uuid) shared_mount = client.V1VolumeMount( mount_path=conf['persistent_volume']['mount_path'], name=shared_pvc_name, read_only=True) user_storage_name = "user-{}".format(setting.uuid) user_mount = client.V1VolumeMount( mount_path='/cloud_scheduler_userspace', name=user_storage_name, sub_path=user_dir) username = '******'.format(user.username, setting.id) commands = [ 'set +e', 'ln -s /cloud_scheduler_userspace /headless/Desktop/user_space', 'useradd -u {uid} {username}'.format(uid=499 + user.id, username=username), 'usermod -d /headless {}'.format(username), "su -s /bin/bash -c '/dockerstartup/vnc_startup.sh -w' {}". format(username) ] if created: cp_command = 'cp -r {}/* /headless/Desktop/user_space'.format( conf['persistent_volume']['mount_path'] + '/' + conf['task_initial_file_path']) chown = 'chown -R {user}:{user} /headless/Desktop/user_space/*'.format( user=username) commands.insert(4, cp_command) commands.insert(5, chown) vnc_pw = random_password(8) env_vnc_pw = client.V1EnvVar(name="VNC_PW", value=vnc_pw) container = client.V1Container( name='headless-vnc', image=config.USER_VNC_DOCKER_IMAGE, env=[env_vnc_pw], command=['/bin/bash'], args=['-c', ';'.join(commands)], volume_mounts=[shared_mount, user_mount]) persistent_volume_claim = client.V1PersistentVolumeClaimVolumeSource( claim_name=conf['persistent_volume']['name']) user_volume_claim = client.V1PersistentVolumeClaimVolumeSource( claim_name=USERSPACE_NAME) shared_volume = client.V1Volume( name=shared_pvc_name, persistent_volume_claim=persistent_volume_claim) user_volume = client.V1Volume( name=user_storage_name, persistent_volume_claim=user_volume_claim) template = client.V1PodTemplateSpec( metadata=client.V1ObjectMeta(labels={'app': selector}), spec=client.V1PodSpec(containers=[container], volumes=[shared_volume, user_volume])) spec = client.V1DeploymentSpec( replicas=1, template=template, selector={'matchLabels': { 'app': selector }}) deployment = client.V1Deployment( kind='Deployment', metadata=client.V1ObjectMeta( name=dep_name, namespace=KUBERNETES_NAMESPACE, labels={'app': selector}), spec=spec) app_api.create_namespaced_deployment( body=deployment, namespace=KUBERNETES_NAMESPACE) user_vnc.pod_name = dep_name user_vnc.vnc_password = vnc_pw if not user_vnc.url_path: # create service spec = client.V1ServiceSpec( external_name=selector, ports=[ client.V1ServicePort(name='websocket-port', port=config.USER_VNC_PORT, target_port=config.USER_VNC_PORT) ], selector={'app': selector}, type='ClusterIP', ) service = client.V1Service(spec=spec, metadata=client.V1ObjectMeta( labels={'app': selector}, name=selector, namespace=KUBERNETES_NAMESPACE)) try: core_api.create_namespaced_service( namespace=KUBERNETES_NAMESPACE, body=service) except ApiException as ex: if ex.status != 409: # ignore conflict (duplicate) LOGGER.exception(ex) raise ApiException # create ingress url_path = str(get_uuid()) spec = client.ExtensionsV1beta1IngressSpec( rules=[ client.ExtensionsV1beta1IngressRule( host=config.USER_VNC_HOST, http=client.ExtensionsV1beta1HTTPIngressRuleValue( paths=[ client.ExtensionsV1beta1HTTPIngressPath( client.ExtensionsV1beta1IngressBackend( service_name=selector, service_port=config.USER_VNC_PORT), path='/' + url_path) ])) ], tls=[ client.ExtensionsV1beta1IngressTLS( hosts=[config.USER_VNC_HOST], secret_name=config.USER_VNC_TLS_SECRET) ], ) ingress = client.ExtensionsV1beta1Ingress(metadata={ 'name': selector, 'annotations': { 'kubernetes.io/ingress.class': 'nginx', 'nginx.ingress.kubernetes.io/proxy-read-timeout': '86400', 'nginx.ingress.kubernetes.io/proxy-send-timeout': '86400', } }, spec=spec) need_patch = False try: extension_api.create_namespaced_ingress( KUBERNETES_NAMESPACE, ingress) except ApiException as ex: if ex.status != 409: # ignore conflict (duplicate) LOGGER.exception(ex) raise ApiException else: need_patch = True if need_patch: extension_api.patch_namespaced_ingress( selector, KUBERNETES_NAMESPACE, ingress) user_vnc.url_path = url_path user_vnc.expire_time = round(time.time() + USER_SPACE_POD_TIMEOUT) result['url_path'] = user_vnc.url_path result['vnc_password'] = user_vnc.vnc_password result['deployment_name'] = user_vnc.pod_name result['vnc_host'] = config.USER_VNC_HOST result['vnc_port'] = config.USER_VNC_WS_PORT user_vnc.save(force_update=True) except ApiException as ex: LOGGER.exception(ex) except Exception as ex: LOGGER.exception(ex) finally: if user_vnc: user_vnc.save(force_update=True) return result