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))
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))
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
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))
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
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