def clone(self, request, env_template_id, body): """Clones env template from another tenant It clones the env template from another env template from other tenant. :param request: the operation request. :param env_template_id: the env template ID. :param body: the request body. :return: the description of the created template. """ LOG.debug('EnvTemplates:Clone <Env Template {1} for body {0}>'.format( body, env_template_id)) policy.check('clone_env_template', request.context) old_env_template = self._validate_exists(env_template_id) if not old_env_template.get('is_public'): msg = _('User has no access to these resources.') LOG.error(msg) raise exc.HTTPForbidden(explanation=msg) self._validate_body_name(body) LOG.debug('ENV TEMP NAME: {0}'.format(body['name'])) try: is_public = body.get('is_public', False) template = env_temps.EnvTemplateServices.clone( env_template_id, request.context.tenant, body['name'], is_public) except db_exc.DBDuplicateEntry: msg = _('Env template with specified name already exists') LOG.error(msg) raise exc.HTTPConflict(explanation=msg) return template.to_dict()
def update(self, request, env_template_id, body): """It updates the description template :param request: the operation request. :param env_template_id: the env template ID. :param body: the description to be updated :return: the updated template description. """ LOG.debug('Templates:Update <Id: {templ_id}, ' 'Body: {body}>'.format(templ_id=env_template_id, body=body)) target = {"env_template_id": env_template_id} policy.check('update_env_template', request.context, target) self._validate_request(request, env_template_id) try: LOG.debug( 'ENV TEMP NAME: {temp_name}>'.format(temp_name=body['name'])) if not str(body['name']).strip(): msg = _('Environment Template must contain at least one ' 'non-white space symbol') LOG.exception(msg) raise exc.HTTPBadRequest(msg) except Exception: msg = _('EnvTemplate body is incorrect') LOG.exception(msg) raise exc.HTTPBadRequest(msg) template = env_temps.EnvTemplateServices.update(env_template_id, body) return template.to_dict()
def create(self, request, body): LOG.debug('Environments:Create <Body {body}>'.format(body=body)) policy.check('create_environment', request.context) if not body.get('name'): msg = _('Please, specify a name of the environment to create') LOG.exception(msg) raise exc.HTTPBadRequest(explanation=msg) name = unicode(body['name']) if len(name) > 255: msg = _('Environment name should be 255 characters maximum') LOG.exception(msg) raise exc.HTTPBadRequest(explanation=msg) if VALID_NAME_REGEX.match(name): try: environment = envs.EnvironmentServices.create( body.copy(), request.context) except db_exc.DBDuplicateEntry: msg = _('Environment with specified name already exists') LOG.exception(msg) raise exc.HTTPConflict(explanation=msg) else: msg = _('Environment name must contain only alphanumericor "_-." ' 'characters, must start with alpha') LOG.exception(msg) raise exc.HTTPClientError(explanation=msg) return environment.to_dict()
def update(self, request, env_template_id, body): """It updates the description template. :param request: the operation request. :param env_template_id: the env template ID. :param body: the description to be updated :return: the updated template description. """ LOG.debug('Templates:Update <Id: {templ_id}, ' 'Body: {body}>'.format(templ_id=env_template_id, body=body)) target = {"env_template_id": env_template_id} policy.check('update_env_template', request.context, target) self._validate_request(request, env_template_id) try: LOG.debug('ENV TEMP NAME: {temp_name}>'.format( temp_name=body['name'])) if not envs_api.VALID_NAME_REGEX.match(str(body['name'])): msg = _('Env Template must contain only alphanumeric ' 'or "_-." characters, must start with alpha') LOG.exception(msg) raise exc.HTTPBadRequest(msg) except Exception: msg = _('EnvTemplate body is incorrect') LOG.exception(msg) raise exc.HTTPBadRequest(msg) template = env_temps.EnvTemplateServices.update(env_template_id, body) return template.to_dict()
def statuses(self, request, environment_id, deployment_id): target = { "environment_id": environment_id, "deployment_id": deployment_id } policy.check("statuses_deployments", request.context, target) unit = db_session.get_session() query = unit.query(models.Status) \ .filter_by(task_id=deployment_id) \ .order_by(models.Status.created) deployment = verify_and_get_deployment(unit, environment_id, deployment_id) if 'service_id' in request.GET: service_id_set = set(request.GET.getall('service_id')) environment = deployment.description entity_ids = [] for service in environment.get('services', []): if service['?']['id'] in service_id_set: id_map = utils.build_entity_map(service) entity_ids = entity_ids + id_map.keys() if entity_ids: query = query.filter(models.Status.entity_id.in_(entity_ids)) else: return {'reports': []} result = query.all() return {'reports': [status.to_dict() for status in result]}
def create(self, request, body): """It creates the env template from the payload obtaining. This payload can contain just the template name, or include also service information. :param request: the operation request. :param body: the env template description :return: the description of the created template. """ LOG.debug('EnvTemplates:Create <Body {body}>'.format(body=body)) policy.check('create_env_template', request.context) try: LOG.debug('ENV TEMP NAME: {templ_name}>'.format( templ_name=body['name'])) if not envs_api.VALID_NAME_REGEX.match(str(body['name'])): msg = _('Environment Template must contain only alphanumeric ' 'or "_-." characters, must start with alpha') LOG.error(msg) raise exc.HTTPBadRequest(msg) except Exception: msg = _('Env template body is incorrect') LOG.exception(msg) raise exc.HTTPClientError(msg) if len(body['name']) > 255: msg = _('Environment Template name should be 255 characters ' 'maximum') LOG.exception(msg) raise exc.HTTPBadRequest(explanation=msg) try: template = env_temps.EnvTemplateServices.create( body.copy(), request.context.tenant) return template.to_dict() except db_exc.DBDuplicateEntry: msg = _('Env Template with specified name already exists') LOG.exception(msg) raise exc.HTTPConflict(msg)
def index(self, request): """Lists the env templates associated to an tenant-id It lists the env templates associated to an tenant-id. :param request: The operation request. :return: the env template description list. """ LOG.debug('EnvTemplates:List') policy.check('list_env_templates', request.context) tenant_id = request.context.tenant filters = {} if request.GET.get('is_public'): is_public = request.GET.get('is_public', 'false').lower() == 'true' if not is_public: filters['is_public'] = False filters['tenant_id'] = tenant_id elif is_public: filters['is_public'] = True list_templates = env_temps.EnvTemplateServices.\ get_env_templates_by(filters) else: filters = (models.EnvironmentTemplate.is_public, models.EnvironmentTemplate.tenant_id == tenant_id) list_templates = env_temps.EnvTemplateServices.\ get_env_templates_or_by(filters) list_templates = [temp.to_dict() for temp in list_templates] return {"templates": list_templates}
def update(self, request, environment_id, body): LOG.debug('Environments:Update <Id: {0}, ' 'Body: {1}>'.format(environment_id, body)) target = {"environment_id": environment_id} policy.check('update_environment', request.context, target) session = db_session.get_session() environment = session.query(models.Environment).get(environment_id) if environment is None: LOG.info(_('Environment <EnvId {0}> is not ' 'found').format(environment_id)) raise exc.HTTPNotFound if environment.tenant_id != request.context.tenant: LOG.info(_('User is not authorized to access ' 'this tenant resources.')) raise exc.HTTPUnauthorized LOG.debug('ENV NAME: {0}>'.format(body['name'])) if VALID_NAME_REGEX.match(str(body['name'])): environment.update(body) environment.save(session) else: msg = _('Environment name must contain only alphanumeric ' 'or "_-." characters, must start with alpha') LOG.exception(msg) raise exc.HTTPClientError(msg) return environment.to_dict()
def execute(self, request, environment_id, action_id, body): policy.check("execute_action", request.context, {}) LOG.debug('Action:Execute <ActionId: {0}>'.format(action_id)) unit = db_session.get_session() # no new session can be opened if environment has deploying status env_status = envs.EnvironmentServices.get_status(environment_id) if env_status in (states.EnvironmentStatus.DEPLOYING, states.EnvironmentStatus.DELETING): LOG.info(_LI('Could not open session for environment <EnvId: {0}>,' 'environment has deploying ' 'status.').format(environment_id)) raise exc.HTTPForbidden() user_id = request.context.user session = sessions.SessionServices.create(environment_id, user_id) if not sessions.SessionServices.validate(session): LOG.error(_LE('Session <SessionId {0}> ' 'is invalid').format(session.id)) raise exc.HTTPForbidden() task_id = actions.ActionServices.execute( action_id, session, unit, request.context.auth_token, body or {}) return {'task_id': task_id}
def update_model(self, request, environment_id, body=None): if not body: msg = _('Request body is empty: please, provide ' 'environment object model patch') LOG.error(msg) raise exc.HTTPBadRequest(msg) LOG.debug('Environments:UpdateModel <Id: %(env_id)s, Body: %(body)s>', { 'env_id': environment_id, 'body': body }) target = {"environment_id": environment_id} policy.check('update_environment', request.context, target) session_id = None if hasattr(request, 'context') and request.context.session: session_id = request.context.session get_description = envs.EnvironmentServices.get_environment_description env_model = get_description(environment_id, session_id) for change in body: change['path'] = '/' + '/'.join(change['path']) patch = jsonpatch.JsonPatch(body) try: patch.apply(env_model, in_place=True) except jsonpatch.JsonPatchException as e: raise exc.HTTPNotFound(str(e)) save_description = envs.EnvironmentServices. \ save_environment_description save_description(session_id, env_model) return env_model
def show(self, request, environment_id): LOG.debug('Environments:Show <Id: {0}>'.format(environment_id)) target = {"environment_id": environment_id} policy.check('show_environment', request.context, target) session = db_session.get_session() environment = session.query(models.Environment).get(environment_id) if environment is None: LOG.info( _('Environment <EnvId {0}> is not found').format( environment_id)) raise exc.HTTPNotFound if environment.tenant_id != request.context.tenant: LOG.info( _('User is not authorized to access ' 'this tenant resources.')) raise exc.HTTPUnauthorized env = environment.to_dict() env['status'] = envs.EnvironmentServices.get_status(env['id']) session_id = None if hasattr(request, 'context') and request.context.session: session_id = request.context.session #add services to env get_data = core_services.CoreServices.get_data env['services'] = get_data(environment_id, '/services', session_id) return env
def upload(self, req, body=None): """Upload new file archive for the new package together with package metadata. """ policy.check("upload_package", req.context) _check_content_type(req, 'multipart/form-data') file_obj, package_meta = _validate_body(body) if package_meta: try: jsonschema.validate(package_meta, schemas.PKG_UPLOAD_SCHEMA) except jsonschema.ValidationError as e: msg = _("Package schema is not valid: {reason}").format( reason=e) LOG.exception(msg) raise exc.HTTPBadRequest(explanation=msg) else: package_meta = {} if package_meta.get('is_public'): policy.check('publicize_package', req.context) with tempfile.NamedTemporaryFile(delete=False) as tempf: LOG.debug("Storing package archive in a temporary file") content = file_obj.file.read() if not content: msg = _("Uploading file can't be empty") LOG.error(msg) raise exc.HTTPBadRequest(explanation=msg) tempf.write(content) package_meta['archive'] = content try: with load_utils.load_from_file( tempf.name, target_dir=None, drop_dir=True) as pkg_to_upload: # extend dictionary for update db for k, v in six.iteritems(PKG_PARAMS_MAP): if hasattr(pkg_to_upload, k): package_meta[v] = getattr(pkg_to_upload, k) if len(package_meta['name']) > 80: msg = _('Package name should be 80 characters maximum') LOG.error(msg) raise exc.HTTPBadRequest(explanation=msg) try: package = db_api.package_upload( package_meta, req.context.tenant) except db_exc.DBDuplicateEntry: msg = _('Package with specified full ' 'name is already registered') LOG.exception(msg) raise exc.HTTPConflict(msg) return package.to_dict() except pkg_exc.PackageLoadError as e: msg = _("Couldn't load package from file: {reason}").format( reason=e) LOG.exception(msg) raise exc.HTTPBadRequest(explanation=msg) finally: LOG.debug("Deleting package archive temporary file") os.remove(tempf.name)
def create(self, request, body): """It creates the env template from the payload obtaining. This payload can contain just the template name, or include also service information. :param request: the operation request. :param body: the env template description :return: the description of the created template. """ LOG.debug('EnvTemplates:Create <Body {body}>'.format(body=body)) policy.check('create_env_template', request.context) try: LOG.debug( 'ENV TEMP NAME: {templ_name}>'.format(templ_name=body['name'])) if not envs_api.VALID_NAME_REGEX.match(str(body['name'])): msg = _('Environment Template must contain only alphanumeric ' 'or "_-." characters, must start with alpha') LOG.error(msg) raise exc.HTTPBadRequest(msg) except Exception: msg = _('Env template body is incorrect') LOG.exception(msg) raise exc.HTTPClientError(msg) if len(body['name']) > 255: msg = _('Environment Template name should be 255 characters ' 'maximum') LOG.exception(msg) raise exc.HTTPBadRequest(explanation=msg) try: template = env_temps.EnvTemplateServices.create( body.copy(), request.context.tenant) return template.to_dict() except db_exc.DBDuplicateEntry: msg = _('Env Template with specified name already exists') LOG.exception(msg) raise exc.HTTPConflict(msg)
def put(self, request, env_template_id, path, body): """It updates a service into a template. :param request: The operation request. :param env_template_id: the env template ID where the service belongs to. :param path: The path :param body: the information about the service :return: the service description updated. """ policy.check('update_service_env_template', request.context) LOG.debug('Applications:Put <EnvTempId: {templ_id}, Path: {path}, ' 'Body: {body}>'.format(templ_id=env_template_id, body=body, path=path)) put_data = core_services.CoreServices.put_application_data try: result = put_data(env_template_id, body, path) except (KeyError, ValueError): msg = _('The template does not exist {templ_id}').format( templ_id=env_template_id) LOG.exception(msg) raise exc.HTTPNotFound(msg) return result
def show(self, request, environment_id): LOG.debug('Environments:Show <Id: {id}>'.format(id=environment_id)) target = {"environment_id": environment_id} policy.check('show_environment', request.context, target) session = db_session.get_session() environment = session.query(models.Environment).get(environment_id) env = environment.to_dict() env['status'] = envs.EnvironmentServices.get_status(env['id']) # if env is currently being deployed we can provide information about # the session right away env['acquired_by'] = None if env['status'] == states.EnvironmentStatus.DEPLOYING: session_list = session_services.SessionServices.get_sessions( environment_id, state=states.SessionState.DEPLOYING) if session_list: env['acquired_by'] = session_list[0].id session_id = None if hasattr(request, 'context') and request.context.session: session_id = request.context.session if session_id: env_session = session.query(models.Session).get(session_id) check_session(request, environment_id, env_session, session_id) # add services to env get_data = core_services.CoreServices.get_data env['services'] = get_data(environment_id, '/services', session_id) return env
def upload(self, req, body=None): """Upload new file archive for the new package together with package metadata. """ policy.check("upload_package", req.context) _check_content_type(req, 'multipart/form-data') file_obj, package_meta = _validate_body(body) if package_meta: try: jsonschema.validate(package_meta, schemas.PKG_UPLOAD_SCHEMA) except jsonschema.ValidationError as e: msg = _("Package schema is not valid: {reason}").format( reason=e) LOG.exception(msg) raise exc.HTTPBadRequest(explanation=msg) else: package_meta = {} if package_meta.get('is_public'): policy.check('publicize_package', req.context) with tempfile.NamedTemporaryFile(delete=False) as tempf: LOG.debug("Storing package archive in a temporary file") content = file_obj.file.read() if not content: msg = _("Uploading file can't be empty") LOG.error(msg) raise exc.HTTPBadRequest(explanation=msg) tempf.write(content) package_meta['archive'] = content try: with load_utils.load_from_file(tempf.name, target_dir=None, drop_dir=True) as pkg_to_upload: # extend dictionary for update db for k, v in six.iteritems(PKG_PARAMS_MAP): if hasattr(pkg_to_upload, k): package_meta[v] = getattr(pkg_to_upload, k) if len(package_meta['name']) > 80: msg = _('Package name should be 80 characters maximum') LOG.error(msg) raise exc.HTTPBadRequest(explanation=msg) try: package = db_api.package_upload(package_meta, req.context.tenant) except db_exc.DBDuplicateEntry: msg = _('Package with specified full ' 'name is already registered') LOG.exception(msg) raise exc.HTTPConflict(msg) return package.to_dict() except pkg_exc.PackageLoadError as e: msg = _("Couldn't load package from file: {reason}").format( reason=e) LOG.exception(msg) raise exc.HTTPBadRequest(explanation=msg) finally: LOG.debug("Deleting package archive temporary file") os.remove(tempf.name)
def search(self, req): policy.check("get_package", req.context) manage_public = True try: policy.check("manage_public_package", req.context) except exc.HTTPForbidden: manage_public = False filters = _get_filters(req.GET.items()) limit = self._validate_limit(filters.get('limit')) if limit is None: limit = CONF.murano.limit_param_default limit = min(CONF.murano.api_limit_max, limit) result = {} catalog = req.GET.pop('catalog', '').lower() == 'true' packages = db_api.package_search(filters, req.context, manage_public, limit, catalog=catalog) if len(packages) == limit: result['next_marker'] = packages[-1].id result['packages'] = [package.to_dict() for package in packages] return result
def search(self, req): def _validate_limit(value): if value is None: return try: value = int(value) except ValueError: msg = _("limit param must be an integer") LOG.error(msg) raise exc.HTTPBadRequest(explanation=msg) if value <= 0: msg = _("limit param must be positive") LOG.error(msg) raise exc.HTTPBadRequest(explanation=msg) return value policy.check("search_packages", req.context) filters = _get_filters(req.GET.items()) limit = _validate_limit(filters.get('limit')) if limit is None: limit = CONF.packages_opts.limit_param_default limit = min(CONF.packages_opts.api_limit_max, limit) result = {} packages = db_api.package_search(filters, req.context, limit) if len(packages) == limit: result['next_marker'] = packages[-1].id result['packages'] = [package.to_dict() for package in packages] return result
def update(self, request, environment_id, body): LOG.debug('Environments:Update <Id: {id}, ' 'Body: {body}>'.format(id=environment_id, body=body)) target = {"environment_id": environment_id} policy.check('update_environment', request.context, target) session = db_session.get_session() environment = session.query(models.Environment).get(environment_id) new_name = six.text_type(body['name']) if new_name.strip(): if len(new_name) > 255: msg = _('Environment name should be 255 characters maximum') LOG.error(msg) raise exc.HTTPBadRequest(explanation=msg) try: environment.update(body) environment.save(session) except db_exc.DBDuplicateEntry: msg = _('Environment with specified name already exists') LOG.error(msg) raise exc.HTTPConflict(explanation=msg) else: msg = _('Environment name must contain at least one ' 'non-white space symbol') LOG.error(msg) raise exc.HTTPClientError(explanation=msg) return environment.to_dict()
def execute(self, request, environment_id, action_id, body): policy.check("execute_action", request.context, {}) LOG.debug("Action:Execute <ActionId: {0}>".format(action_id)) unit = db_session.get_session() # no new session can be opened if environment has deploying status env_status = envs.EnvironmentServices.get_status(environment_id) if env_status in (states.EnvironmentStatus.DEPLOYING, states.EnvironmentStatus.DELETING): LOG.info( _LI( "Could not open session for environment <EnvId: {0}>," "environment has deploying " "status." ).format(environment_id) ) raise exc.HTTPForbidden() user_id = request.context.user session = sessions.SessionServices.create(environment_id, user_id) if not sessions.SessionServices.validate(session): LOG.error(_LE("Session <SessionId {0}> " "is invalid").format(session.id)) raise exc.HTTPForbidden() task_id = actions.ActionServices.execute(action_id, session, unit, request.context.auth_token, body or {}) return {"task_id": task_id}
def show(self, request, environment_id): LOG.debug('Environments:Show <Id: {0}>'.format(environment_id)) target = {"environment_id": environment_id} policy.check('show_environment', request.context, target) session = db_session.get_session() environment = session.query(models.Environment).get(environment_id) if environment is None: LOG.info(_('Environment <EnvId {0}> is not found').format( environment_id)) raise exc.HTTPNotFound if environment.tenant_id != request.context.tenant: LOG.info(_('User is not authorized to access ' 'this tenant resources.')) raise exc.HTTPUnauthorized env = environment.to_dict() env['status'] = envs.EnvironmentServices.get_status(env['id']) session_id = None if hasattr(request, 'context') and request.context.session: session_id = request.context.session #add services to env get_data = core_services.CoreServices.get_data env['services'] = get_data(environment_id, '/services', session_id) return env
def statuses(self, request, environment_id, deployment_id): target = {"environment_id": environment_id, "deployment_id": deployment_id} policy.check("statuses_deployments", request.context, target) unit = db_session.get_session() query = unit.query(models.Status) \ .filter_by(task_id=deployment_id) \ .order_by(models.Status.created) deployment = verify_and_get_deployment(unit, environment_id, deployment_id) if 'service_id' in request.GET: service_id_set = set(request.GET.getall('service_id')) environment = deployment.description entity_ids = [] for service in environment.get('services', []): if service['?']['id'] in service_id_set: id_map = utils.build_entity_map(service) entity_ids = entity_ids + id_map.keys() if entity_ids: query = query.filter(models.Status.entity_id.in_(entity_ids)) else: return {'reports': []} result = query.all() return {'reports': [status.to_dict() for status in result]}
def create(self, request, body): LOG.debug("Environments:Create <Body {body}>".format(body=body)) policy.check("create_environment", request.context) if not body.get("name"): msg = _("Please, specify a name of the environment to create") LOG.exception(msg) raise exc.HTTPBadRequest(explanation=msg) name = unicode(body["name"]) if len(name) > 255: msg = _("Environment name should be 255 characters maximum") LOG.exception(msg) raise exc.HTTPBadRequest(explanation=msg) if VALID_NAME_REGEX.match(name): try: environment = envs.EnvironmentServices.create(body.copy(), request.context) except db_exc.DBDuplicateEntry: msg = _("Environment with specified name already exists") LOG.exception(msg) raise exc.HTTPConflict(explanation=msg) else: msg = _('Environment name must contain only alphanumeric or "_-." ' "characters, must start with alpha") LOG.exception(msg) raise exc.HTTPClientError(explanation=msg) return environment.to_dict()
def update(self, request, env_template_id, body): """It updates the description template :param request: the operation request. :param env_template_id: the env template ID. :param body: the description to be updated :return: the updated template description. """ LOG.debug('Templates:Update <Id: {templ_id}, ' 'Body: {body}>'.format(templ_id=env_template_id, body=body)) target = {"env_template_id": env_template_id} policy.check('update_env_template', request.context, target) self._validate_request(request, env_template_id) try: LOG.debug('ENV TEMP NAME: {temp_name}>'.format( temp_name=body['name'])) if not str(body['name']).strip(): msg = _('Environment Template must contain at least one ' 'non-white space symbol') LOG.exception(msg) raise exc.HTTPBadRequest(msg) except Exception: msg = _('EnvTemplate body is incorrect') LOG.exception(msg) raise exc.HTTPBadRequest(msg) template = env_temps.EnvTemplateServices.update(env_template_id, body) return template.to_dict()
def update(self, request, env_template_id, body): """It updates the description template. :param request: the operation request. :param env_template_id: the env template ID. :param body: the description to be updated :return: the updated template description. """ LOG.debug('Templates:Update <Id: {templ_id}, ' 'Body: {body}>'.format(templ_id=env_template_id, body=body)) target = {"env_template_id": env_template_id} policy.check('update_env_template', request.context, target) self._validate_request(request, env_template_id) try: LOG.debug( 'ENV TEMP NAME: {temp_name}>'.format(temp_name=body['name'])) if not envs_api.VALID_NAME_REGEX.match(str(body['name'])): msg = _('Env Template must contain only alphanumeric ' 'or "_-." characters, must start with alpha') LOG.exception(msg) raise exc.HTTPBadRequest(msg) except Exception: msg = _('EnvTemplate body is incorrect') LOG.exception(msg) raise exc.HTTPBadRequest(msg) template = env_temps.EnvTemplateServices.update(env_template_id, body) return template.to_dict()
def execute(self, request, environment_id, action_id, body): policy.check("execute_action", request.context, {}) LOG.debug('Action:Execute <ActionId: {0}>'.format(action_id)) unit = db_session.get_session() # no new session can be opened if environment has deploying status env_status = envs.EnvironmentServices.get_status(environment_id) if env_status in (states.EnvironmentStatus.DEPLOYING, states.EnvironmentStatus.DELETING): LOG.warning('Could not open session for environment ' '<EnvId: {id}>, environment has deploying ' 'or deleting status.'.format(id=environment_id)) raise exc.HTTPForbidden() user_id = request.context.user session = sessions.SessionServices.create(environment_id, user_id) if not sessions.SessionServices.validate(session): LOG.error('Session <SessionId {id}> ' 'is invalid'.format(id=session.id)) raise exc.HTTPForbidden() task_id = actions.ActionServices.execute( action_id, session, unit, request.context, body or {}) return {'task_id': task_id}
def update(self, request, environment_id, body): LOG.debug('Environments:Update <Id: {0}, ' 'Body: {1}>'.format(environment_id, body)) target = {"environment_id": environment_id} policy.check('update_environment', request.context, target) session = db_session.get_session() environment = session.query(models.Environment).get(environment_id) if environment is None: LOG.info( _('Environment <EnvId {0}> is not ' 'found').format(environment_id)) raise exc.HTTPNotFound if environment.tenant_id != request.context.tenant: LOG.info( _('User is not authorized to access ' 'this tenant resources.')) raise exc.HTTPUnauthorized LOG.debug('ENV NAME: {0}>'.format(body['name'])) if VALID_NAME_REGEX.match(str(body['name'])): environment.update(body) environment.save(session) else: msg = _('Environment name must contain only alphanumeric ' 'or "_-." characters, must start with alpha') LOG.exception(msg) raise exc.HTTPClientError(msg) return environment.to_dict()
def update(self, request, environment_id, body): """"Rename an environment.""" LOG.debug('Environments:Update <Id: {id}, ' 'Body: {body}>'.format(id=environment_id, body=body)) target = {"environment_id": environment_id} policy.check('update_environment', request.context, target) session = db_session.get_session() environment = session.query(models.Environment).get(environment_id) new_name = six.text_type(body['name']) if new_name.strip(): if len(new_name) > 255: msg = _('Environment name should be 255 characters maximum') LOG.error(msg) raise exc.HTTPBadRequest(explanation=msg) try: environment.update({'name': new_name}) environment.save(session) except db_exc.DBDuplicateEntry: msg = _('Environment with specified name already exists') LOG.error(msg) raise exc.HTTPConflict(explanation=msg) else: msg = _('Environment name must contain at least one ' 'non-white space symbol') LOG.error(msg) raise exc.HTTPClientError(explanation=msg) return environment.to_dict()
def index(self, request): """Lists the env templates associated to an tenant-id It lists the env templates associated to an tenant-id. :param request: The operation request. :return: the env template description list. """ LOG.debug('EnvTemplates:List') policy.check('list_env_templates', request.context) tenant_id = request.context.tenant filters = {} if request.GET.get('is_public'): is_public = request.GET.get('is_public', 'false').lower() == 'true' if not is_public: filters['is_public'] = False filters['tenant_id'] = tenant_id elif is_public: filters['is_public'] = True list_templates = env_temps.EnvTemplateServices.\ get_env_templates_by(filters) else: filters = (EnvironmentTemplate.is_public, EnvironmentTemplate.tenant_id == tenant_id) list_templates = env_temps.EnvTemplateServices.\ get_env_templates_or_by(filters) list_templates = [temp.to_dict() for temp in list_templates] return {"templates": list_templates}
def clone(self, request, env_template_id, body): """Clones env template from another tenant It clones the env template from another env template from other tenant. :param request: the operation request. :param env_template_id: the env template ID. :param body: the request body. :return: the description of the created template. """ LOG.debug('EnvTemplates:Clone <Env Template {0} for body {1}>'. format(body, env_template_id)) policy.check('clone_env_template', request.context) old_env_template = self._validate_exists(env_template_id) if not old_env_template.get('is_public'): msg = _LE('User has no access to these resources.') LOG.error(msg) raise exc.HTTPForbidden(explanation=msg) self._validate_body_name(body) LOG.debug('ENV TEMP NAME: {0}'.format(body['name'])) try: is_public = body.get('is_public', False) template = env_temps.EnvTemplateServices.clone( env_template_id, request.context.tenant, body['name'], is_public) except db_exc.DBDuplicateEntry: msg = _('Environment with specified name already exists') LOG.error(msg) raise exc.HTTPConflict(explanation=msg) return template.to_dict()
def delete(self, req, package_id): target = {'package_id': package_id} policy.check("delete_package", req.context, target) package = db_api.package_get(package_id, req.context) if package.is_public: policy.check("manage_public_package", req.context, target) db_api.package_delete(package_id, req.context)
def delete(self, request, environment_id): LOG.debug('Environments:Delete <Id: {0}>'.format(environment_id)) target = {"environment_id": environment_id} policy.check('delete_environment', request.context, target) sessions_controller = sessions.Controller() session = sessions_controller.configure(request, environment_id) session_id = session['id'] envs.EnvironmentServices.delete(environment_id, session_id) sessions_controller.deploy(request, environment_id, session_id)
def index(self, request, environment_id): target = {"environment_id": environment_id} policy.check("list_deployments", request.context, target) unit = db_session.get_session() query = unit.query(models.Task).filter_by(environment_id=environment_id).order_by(desc(models.Task.created)) result = query.all() deployments = [set_dep_state(deployment, unit).to_dict() for deployment in result] return {"deployments": deployments}
def delete_category(self, req, category_id): target = {'category_id': category_id} policy.check("delete_category", req.context, target) category = db_api.category_get(category_id, packages=True) if category.packages: msg = _("It's impossible to delete categories assigned" " to the package, uploaded to the catalog") raise exc.HTTPForbidden(explanation=msg) db_api.category_delete(category_id)
def delete_category(self, req, category_id): target = {'category_id': category_id} policy.check("delete_category", req.context, target) category = db_api.category_get(category_id, packages=True) if category.packages: msg = _("It's impossible to delete categories assigned " "to the package, uploaded to the catalog") raise exc.HTTPForbidden(explanation=msg) db_api.category_delete(category_id)
def get_for_environment(self, request, environment_id): LOG.debug('EnvironmentStatistics:GetForEnvironment') target = {"environment_id": environment_id} policy.check("get_statistics", request.context, target) # TODO(stanlagun): Check that caller is authorized to access # tenant's statistics return instances.InstanceStatsServices.get_raw_environment_stats( environment_id)
def index(self, request): LOG.debug('Environments:List') policy.check('list_environments', request.context) #Only environments from same tenant as user should be returned filters = {'tenant_id': request.context.tenant} environments = envs.EnvironmentServices.get_environments_by(filters) environments = [env.to_dict() for env in environments] return {"environments": environments}
def get_for_environment(self, request, environment_id): LOG.debug('EnvironmentStatistics:GetForEnvironment') target = {"environment_id": environment_id} policy.check("get_statistics", request.context, target) # TODO (stanlagun): Check that caller is authorized to access # tenant's statistics return instances.InstanceStatsServices.get_raw_environment_stats( environment_id)
def list_categories(self, req): """List all categories List all categories with pagination and sorting Acceptable filter params: :param sort_keys: an array of fields used to sort the list :param sort_dir: the direction of the sort ('asc' or 'desc') :param limit: the number of categories to list :param marker: the ID of the last item in the previous page """ def _get_category_filters(req): query_params = {} valid_query_params = ['sort_keys', 'sort_dir', 'limit', 'marker'] for key, value in req.GET.items(): if key not in valid_query_params: raise exc.HTTPBadRequest( _('Bad value passed to filter. ' 'Got {key}, expected:{valid}').format( key=key, valid=', '.join(valid_query_params))) if key == 'sort_keys': available_sort_keys = [ 'name', 'created', 'updated', 'package_count', 'id' ] value = [v.strip() for v in value.split(',')] for sort_key in value: if sort_key not in available_sort_keys: raise exc.HTTPBadRequest(explanation=_( 'Invalid sort key: {sort_key}. ' 'Must be one of the following: ' '{available}').format( sort_key=sort_key, available=', '.join(available_sort_keys))) if key == 'sort_dir': if value not in ['asc', 'desc']: msg = _('Invalid sort direction: {0}').format(value) raise exc.HTTPBadRequest(explanation=msg) query_params[key] = value return query_params policy.check("get_category", req.context) filters = _get_category_filters(req) marker = filters.get('marker') limit = self._validate_limit(filters.get('limit')) result = {} categories = db_api.categories_list(filters, limit=limit, marker=marker) if len(categories) == limit: result['next_marker'] = categories[-1].id result['categories'] = [category.to_dict() for category in categories] return result
def list_categories(self, req): """List all categories List all categories with pagination and sorting Acceptable filter params: :param sort_keys: an array of fields used to sort the list :param sort_dir: the direction of the sort ('asc' or 'desc') :param limit: the number of categories to list :param marker: the ID of the last item in the previous page """ def _get_category_filters(req): query_params = {} valid_query_params = ['sort_keys', 'sort_dir', 'limit', 'marker'] for key, value in req.GET.items(): if key not in valid_query_params: raise exc.HTTPBadRequest( _('Bad value passed to filter. ' 'Got {key}, exected:{valid}').format( key=key, valid=', '.join(valid_query_params))) if key == 'sort_keys': available_sort_keys = ['name', 'created', 'updated', 'package_count', 'id'] value = [v.strip() for v in value.split(',')] for sort_key in value: if sort_key not in available_sort_keys: raise exc.HTTPBadRequest( explanation=_('Invalid sort key: {sort_key}. ' 'Must be one of the following: ' '{available}').format( sort_key=sort_key, available=', '.join(available_sort_keys))) if key == 'sort_dir': if value not in ['asc', 'desc']: msg = _('Invalid sort direction: {0}').format(value) raise exc.HTTPBadRequest(explanation=msg) query_params[key] = value return query_params policy.check("get_category", req.context) filters = _get_category_filters(req) marker = filters.get('marker') limit = self._validate_limit(filters.get('limit')) result = {} categories = db_api.categories_list(filters, limit=limit, marker=marker) if len(categories) == limit: result['next_marker'] = categories[-1].id result['categories'] = [category.to_dict() for category in categories] return result
def delete(self, request, env_template_id): """It deletes the env template. :param request: the operation request. :param env_template_id: the template ID. """ LOG.debug('EnvTemplates:Delete <Id: {0}>'.format(env_template_id)) target = {"env_template_id": env_template_id} policy.check('delete_env_template', request.context, target) self._validate_request(request, env_template_id) env_temps.EnvTemplateServices.delete(env_template_id) env_temps.EnvTemplateServices.remove(env_template_id) return
def upload(self, req, body=None): """Upload new file archive for the new package together with package metadata. """ policy.check("upload_package", req.context) _check_content_type(req, 'multipart/form-data') file_obj, package_meta = _validate_body(body) if package_meta: try: jsonschema.validate(package_meta, schemas.PKG_UPLOAD_SCHEMA) except jsonschema.ValidationError as e: LOG.exception(e) raise exc.HTTPBadRequest(explanation=e.message) else: package_meta = {} with tempfile.NamedTemporaryFile(delete=False) as tempf: LOG.debug("Storing package archive in a temporary file") content = file_obj.file.read() if not content: msg = _("Uploading file can't be empty") LOG.error(msg) raise exc.HTTPBadRequest(msg) tempf.write(content) package_meta['archive'] = content try: pkg_to_upload = load_utils.load_from_file(tempf.name, target_dir=None, drop_dir=True) except pkg_exc.PackageLoadError as e: LOG.exception(e) raise exc.HTTPBadRequest(e) finally: LOG.debug("Deleting package archive temporary file") os.remove(tempf.name) # extend dictionary for update db for k, v in PKG_PARAMS_MAP.iteritems(): if hasattr(pkg_to_upload, k): package_meta[v] = getattr(pkg_to_upload, k) if req.params.get('is_public', '').lower() == 'true': policy.check('publicize_image', req.context) package_meta['is_public'] = True try: package = db_api.package_upload(package_meta, req.context.tenant) except db_exc.DBDuplicateEntry: msg = _('Package with specified full name is already registered') LOG.exception(msg) raise exc.HTTPServerError(msg) return package.to_dict()
def index(self, request, environment_id): target = {"environment_id": environment_id} policy.check("list_deployments", request.context, target) unit = db_session.get_session() query = unit.query(models.Task) \ .filter_by(environment_id=environment_id) \ .order_by(desc(models.Task.created)) result = query.all() deployments = [set_dep_state(deployment, unit).to_dict() for deployment in result] return {'deployments': deployments}
def upload(self, req, body=None): """Upload new file archive for the new package together with package metadata. """ policy.check("upload_package", req.context) _check_content_type(req, 'multipart/form-data') file_obj, package_meta = _validate_body(body) if package_meta: try: jsonschema.validate(package_meta, schemas.PKG_UPLOAD_SCHEMA) except jsonschema.ValidationError as e: LOG.exception(e) raise exc.HTTPBadRequest(explanation=e.message) else: package_meta = {} with tempfile.NamedTemporaryFile(delete=False) as tempf: LOG.debug("Storing package archive in a temporary file") content = file_obj.file.read() if not content: msg = _("Uploading file can't be empty") LOG.error(msg) raise exc.HTTPBadRequest(msg) tempf.write(content) package_meta['archive'] = content try: pkg_to_upload = load_utils.load_from_file( tempf.name, target_dir=None, drop_dir=True) except pkg_exc.PackageLoadError as e: LOG.exception(e) raise exc.HTTPBadRequest(e) finally: LOG.debug("Deleting package archive temporary file") os.remove(tempf.name) # extend dictionary for update db for k, v in PKG_PARAMS_MAP.iteritems(): if hasattr(pkg_to_upload, k): package_meta[v] = getattr(pkg_to_upload, k) if req.params.get('is_public', '').lower() == 'true': policy.check('publicize_image', req.context) package_meta['is_public'] = True try: package = db_api.package_upload(package_meta, req.context.tenant) except db_exc.DBDuplicateEntry: msg = _('Package with specified full name is already registered') LOG.exception(msg) raise exc.HTTPServerError(msg) return package.to_dict()
def index(self, request): """It lists the env templates associated to an tenant-id. :param request: The operation request. :return: the env template description list. """ LOG.debug("EnvTemplates:List") policy.check("list_env_templates", request.context) filters = {"tenant_id": request.context.tenant} list_templates = env_temps.EnvTemplateServices.get_env_templates_by(filters) list_templates = [temp.to_dict() for temp in list_templates] return {"templates": list_templates}
def create(self, request, body): LOG.debug('Environments:Create <Body {0}>'.format(body)) policy.check('create_environment', request.context) try: environment = envs.EnvironmentServices.create( body.copy(), request.context.tenant) except db_exc.DBDuplicateEntry: msg = _('Environment with specified name already exists') LOG.exception(msg) raise exc.HTTPConflict(msg) return environment.to_dict()
def delete(self, request, environment_id): target = {"environment_id": environment_id} policy.check('delete_environment', request.context, target) if request.GET.get('abandon', '').lower() == 'true': LOG.debug('Environments:Abandon <Id: {0}>'.format(environment_id)) envs.EnvironmentServices.remove(environment_id) else: LOG.debug('Environments:Delete <Id: {0}>'.format(environment_id)) sessions_controller = sessions.Controller() session = sessions_controller.configure(request, environment_id) session_id = session['id'] envs.EnvironmentServices.delete(environment_id, session_id) sessions_controller.deploy(request, environment_id, session_id)
def add_category(self, req, body=None): policy.check("add_category", req.context) if not body.get('name'): raise exc.HTTPBadRequest( explanation='Please, specify a name of the category to create') try: category = db_api.category_add(body['name']) except db_exc.DBDuplicateEntry: msg = _('Category with specified name is already exist') LOG.error(msg) raise exc.HTTPConflict(explanation=msg) return category.to_dict()
def delete(self, request, environment_id): target = {"environment_id": environment_id} policy.check("delete_environment", request.context, target) if request.GET.get("abandon", "").lower() == "true": check_env(request, environment_id) LOG.debug("Environments:Abandon <Id: {0}>".format(environment_id)) envs.EnvironmentServices.remove(environment_id) else: LOG.debug("Environments:Delete <Id: {0}>".format(environment_id)) sessions_controller = sessions.Controller() session = sessions_controller.configure(request, environment_id) session_id = session["id"] envs.EnvironmentServices.delete(environment_id, session_id) sessions_controller.deploy(request, environment_id, session_id)
def delete(self, request, environment_id): target = {"environment_id": environment_id} policy.check('delete_environment', request.context, target) if request.GET.get('abandon', '').lower() == 'true': check_env(request, environment_id) LOG.debug('Environments:Abandon <Id: {0}>'.format(environment_id)) envs.EnvironmentServices.remove(environment_id) else: LOG.debug('Environments:Delete <Id: {0}>'.format(environment_id)) sessions_controller = sessions.Controller() session = sessions_controller.configure(request, environment_id) session_id = session['id'] envs.EnvironmentServices.delete(environment_id, session_id) sessions_controller.deploy(request, environment_id, session_id)
def index(self, request): """It lists the env templates associated to an tenant-id. :param request: The operation request. :return: the env template description list. """ LOG.debug('EnvTemplates:List') policy.check('list_env_templates', request.context) filters = {'tenant_id': request.context.tenant} list_templates = env_temps.EnvTemplateServices.\ get_env_templates_by(filters) list_templates = [temp.to_dict() for temp in list_templates] return {"templates": list_templates}
def create_environment(self, request, env_template_id, body): """Creates environment and session from template. :param request: operation request :param env_template_id: environment template ID :param body: the environment name :return: session_id and environment_id """ LOG.debug('Templates:Create environment <Id: {templ_id}>'. format(templ_id=env_template_id)) target = {"env_template_id": env_template_id} policy.check('create_environment', request.context, target) self._validate_request(request, env_template_id) template = env_temps.EnvTemplateServices.\ get_env_template(env_template_id) if ('name' not in body or not envs_api.VALID_NAME_REGEX.match(str(body['name']))): msg = _('Environment must contain only alphanumeric ' 'or "_-." characters, must start with alpha') LOG.error(msg) raise exc.HTTPBadRequest(explanation=msg) LOG.debug('ENVIRONMENT NAME: {env_name}>'.format( env_name=body['name'])) try: environment = envs.EnvironmentServices.create( body.copy(), request.context) except db_exc.DBDuplicateEntry: msg = _('Environment with specified name already exists') LOG.exception(msg) raise exc.HTTPConflict(explanation=msg) user_id = request.context.user session = sessions.SessionServices.create(environment.id, user_id) if self.has_services(template): services_node = utils.TraverseHelper.get("services", template.description) utils.TraverseHelper.update("/Objects/services", services_node, environment.description) envs.EnvironmentServices.save_environment_description( session.id, environment.description, inner=False ) return {"session_id": session.id, "environment_id": environment.id}
def create_environment(self, request, env_template_id, body): """Creates environment and session from template. :param request: operation request :param env_template_id: environment template ID :param body: the environment name :return: session_id and environment_id """ LOG.debug('Templates:Create environment <Id: {0}>'. format(env_template_id)) target = {"env_template_id": env_template_id} policy.check('create_environment', request.context, target) self._validate_request(request, env_template_id) template = env_temps.EnvTemplateServices.\ get_env_template(env_template_id) if ('name' not in body or not envs_api.VALID_NAME_REGEX.match(str(body['name']))): msg = _('Environment must contain only alphanumeric ' 'or "_-." characters, must start with alpha') LOG.error(msg) raise exc.HTTPBadRequest(explanation=msg) LOG.debug('ENVIRONMENT NAME: {0}>'.format(body['name'])) try: environment = envs.EnvironmentServices.create( body.copy(), request.context) except db_exc.DBDuplicateEntry: msg = _('Environment with specified name already exists') LOG.exception(msg) raise exc.HTTPConflict(explanation=msg) user_id = request.context.user session = sessions.SessionServices.create(environment.id, user_id) if self.has_services(template): services_node = utils.TraverseHelper.get("services", template.description) utils.TraverseHelper.update("/Objects/services", services_node, environment.description) envs.EnvironmentServices.save_environment_description( session.id, environment.description, inner=False ) return {"session_id": session.id, "environment_id": environment.id}
def index(self, request, environment_id): target = {"environment_id": environment_id} policy.check("list_deployments", request.context, target) unit = db_session.get_session() verify_and_get_env(unit, environment_id, request) query = unit.query(models.Task) \ .filter_by(environment_id=environment_id) \ .order_by(desc(models.Task.created)) result = query.all() # show only tasks with 'deploy' action result = [task for task in result if (task.action or {}).get('method', 'deploy') == 'deploy'] deployments = [set_dep_state(deployment, unit).to_dict() for deployment in result] return {'deployments': deployments}