예제 #1
0
def ensure_userdata_configmap_exists(username, labels):
    configmap_namespace = config.get_resource_namespace(username)
    configmap_name = config.get_resource_name(username, "user-data")

    init_user_data = {"apps": [], "specs": []}

    # Ensure empty account resources have been created
    try:
        return kube.create_configmap(
            configmap_name=configmap_name,
            namespace=configmap_namespace,
            labels=labels,

            # "config.json": '{"command":"/usr/bin/mysqld_safe"}',
            # "frontend.cnf": "[mysqld]\nbind-address = 10.0.0.3\n",
            configmap_data={
                "userdata.json": json.dumps(init_user_data),
            })
    except ApiException as err:
        # Ignore if already exists
        if err.status != 409:
            logger.error(
                "ApiException: Failed to create userdata configmap: " +
                str(err))
    except ApiValueError as err:
        logger.error("ApiValueError: Failed to create userdata configmap: " +
                     str(err))
예제 #2
0
def list_stacks(user, token_info):
    logger.debug("Token Info: " + str(token_info))
    logger.debug("OG User: "******"New User: "******"ApiValueError: Failed to list custom userapp resources: " +
            str(err))
    except ApiException as err:
        logger.error(
            "ApiException: Failed to list custom userapp resources: " +
            str(err))

    # TODO: handle filter params
    #if catalog is not None and catalog != '':
    #    docs = list(db[APP_SPECS_COLLECTION_NAME].find({ 'catalog': catalog }))
    #    logger.debug(docs)
    #    return docs, 200

    #mongo_client = get_mongo_client()
    #with mongo_client:
    #    db = mongo_client['workbench']
    #    cursor = db[USER_APPS_COLLECTION_NAME].find({})
    #    docs = list(cursor)
    #    return parse_json(docs), 200
    return {'error': 'An unknown error has occurred'}, 500
예제 #3
0
def ensure_user_ready(username):
    # Apply a set of identifiers to trace back to this specific Workbench instance
    labels = {'manager': 'workbench', 'user': username}

    namespace_name = config.get_resource_namespace(username)

    if namespace_name == username:
        ensure_namespace_exists(username, labels=labels)

    ensure_resource_quota_exists(username, labels=labels)
    #ensure_userdata_configmap_exists(username, labels=labels)
    ensure_home_data_pvc_exists(username, labels=labels)
예제 #4
0
def ensure_namespace_exists(username, labels):
    namespace_name = config.get_resource_namespace(username)
    # resource_prefix = config.get_resource_name(username)

    try:
        return kube.create_namespace(namespace_name, labels=labels)
    except ApiException as err:
        # Ignore if already exists
        if err.status != 409:
            logger.error(
                "ApiException: Failed to create user namespace (%s): %s" %
                (namespace_name, err))
    except ApiValueError as err:
        logger.error(
            "ApiValueError: Failed to create user namespace (%s): %s" %
            (namespace_name, err))
예제 #5
0
def ensure_home_data_pvc_exists(username, labels):
    pvc_namespace = config.get_resource_namespace(username)
    pvc_name = config.get_resource_name(username, "home-data")

    logger.debug("Creating PVC: " + pvc_name)

    try:
        return kube.create_persistent_volume_claim(
            pvc_name=pvc_name,
            namespace=pvc_namespace,
            storage_class=config.KUBE_PVC_STORAGECLASS,
        )
    except ApiException as err:
        # Ignore if already exists
        if err.status != 409:
            logger.error(
                "ApiException: Failed to create userdata configmap: " +
                str(err))
    except ApiValueError as err:
        logger.error("ApiValueError: Failed to create userdata configmap: " +
                     str(err))
예제 #6
0
def stop_stack(user, token_info, stack_id):
    username = token_info['preferred_username']
    namespace = config.get_resource_namespace(username)

    name = config.get_resource_name(username, stack_id)

    try:
        return kube.patch_scale_deployment(name, namespace, 0), 200
    except ApiValueError as err:
        logger.error(
            "ApiValueError: Failed to stop custom userapp resource: " +
            str(err))
    except ApiException as err:
        logger.error("ApiException: Failed to stop custom userapp resource: " +
                     str(err))

    #mongo_client = get_mongo_client()
    #with mongo_client:
    #    db = mongo_client['workbench']
    #    selector = { '_id': ObjectId(stack_id), 'status': 'stopped' }
    #    db[USER_APPS_COLLECTION_NAME].replace_one(selector, stack)
    #    return parse_json(stack), 200
    return {'error': 'An unknown error has occurred'}, 500
예제 #7
0
def ensure_resource_quota_exists(username, labels):
    namespace_name = config.get_resource_namespace(username)

    # Always create resource quote
    try:
        quota_name = config.get_resource_name(username, "medium")
        return kube.create_resource_quota(
            quota_name=quota_name,
            namespace=namespace_name,
            labels=labels,
            hard_quotas={
                # Limit container resources
                'requests.storage': '10Gi',
                'requests.cpu': '2',
                'requests.memory': '4Gi',

                # Limit to 12 possible connections
                'count/services': 12,

                # Limit to 10 inactive apps
                'count/deployments.apps': 10,

                # Limit to 5 active pods
                'count/pods': 5,

                # NOTE: Loadbalancers are not supported at this time
                'count/services.loadbalancers': 0
            })
    except ApiException as err:
        # Ignore if already exists
        if err.status != 409:
            logger.error(
                "ApiException: Failed to create user resource quotas: " +
                str(err))
    except ApiValueError as err:
        logger.error("ApiValueError: Failed to create user resource quotas: " +
                     str(err))
예제 #8
0
def delete_stack(user, token_info, stack_id):
    username = token_info['preferred_username']
    namespace = config.get_resource_namespace(username)

    name = config.get_resource_name(username, stack_id)

    try:
        return kube.delete_custom_user_app(name, namespace), 200
    except ApiValueError as err:
        logger.error(
            "ApiValueError: Failed to delete custom userapp resource: " +
            str(err))
    except ApiException as err:
        logger.error(
            "ApiException: Failed to delete custom userapp resource: " +
            str(err))

    #mongo_client = get_mongo_client()
    #with mongo_client:
    #    db = mongo_client['workbench']
    #    selector = { '_id': ObjectId(stack_id) }
    #    db[USER_APPS_COLLECTION_NAME].remove(selector)
    #    return 204
    return {'error': 'An unknown error has occurred'}, 500
예제 #9
0
def create_stack(user, token_info, stack):
    # generate "unique" id
    sid = stack['id'] = str(uuid.uuid1())

    # TODO: Build up full request parameters
    username = token_info['preferred_username']
    namespace = config.get_resource_namespace(username)

    app_name = config.get_resource_name(username, sid)

    service_ports = {'http': 80, 'https': 443}
    labels = {'manager': 'workbench', 'workbench-app': sid}

    # Create cluster resources
    service = kube.create_service(service_name=app_name,
                                  service_ports=service_ports,
                                  namespace=namespace,
                                  labels=labels)

    logger.debug("Service created: " + str(service))
    for port in service_ports:
        ingress_name = config.get_resource_name(username, app_name, port)
        ingress = kube.create_ingress(ingress_name=ingress_name,
                                      host='%s.%s' %
                                      (ingress_name, config.DOMAIN),
                                      path='/',
                                      pathType='Prefix',
                                      namespace=namespace,
                                      service_name=service.metadata.name,
                                      service_port=port)
    configmap = kube.create_configmap(
        configmap_name=app_name,
        labels=labels,
        namespace=namespace,
        configmap_data={
            # TODO: insert per-app env here
        })

    #   "busybox" -> { name, configmap, image, lifecycle, ports, command }
    containers = []
    for svc in stack['services']:
        appspec_key = svc['service']
        try:
            logger.debug("Fetching app spec: %s" % appspec_key)
            appspec = kube.retrieve_custom_app_spec(appspec_key)
        except ApiException as err:
            logger.error("Failed to lookup AppSpec resource: " + str(err))
            return {
                'error': 'AppSpec resource was not found: ' + appspec_key
            }, 400
        container = {
            "name":
            appspec_key,
            "configmap":
            configmap.metadata.name,
            "image":
            svc['imageTag'] if svc['imageTag'] else appspec['image']['name'],
            "ports":
            svc['ports'] if 'ports' in svc else {},
            "lifecycle":
            None,
            "command":
            svc['command'] if 'command' in svc else appspec['command']
        }
        containers.append(container)
    deployment = kube.create_deployment(deployment_name=app_name,
                                        replicas=0,
                                        namespace=namespace,
                                        labels=labels,
                                        containers=containers)

    # Add accounting info to userdata configmap
    logger.debug("Creating custom userapp: " + str(stack))
    try:
        return kube.create_custom_user_app(stack, namespace), 200
    except ApiValueError as err:
        logger.error(
            "ApiValueError: Failed to create custom userapp resource: " +
            str(err))
    except ApiException as err:
        logger.error(
            "ApiException: Failed to create custom userapp resource: " +
            str(err))

    # mongo_client = get_mongo_client()
    # with mongo_client:
    #    db = mongo_client['workbench']
    #    record = db[USER_APPS_COLLECTION_NAME].insert_one(stack)
    #    stack['_id'] = str(record.inserted_id)
    #    return parse_json(stack), 201
    return {'error': 'An unknown error has occurred'}, 500