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 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}'")
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}'")
Example #7
0
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 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
Example #11
0
    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')
Example #12
0
    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