def test_missing_blob(self): """Fake a package with NULL supplier JSON blob to test bug 1342306""" con = session.get_session().connection() con.execute("INSERT INTO package(id, fully_qualified_name, " "owner_id, name, description, created, updated, type, " "supplier) " "VALUES (1, 'blob.test', 1, 'blob test', 'Desc', " "'2014-07-15 00:00:00', '2014-07-15 00:00:00', " "'Application', NULL)") loaded_e = session.get_session().query(models.Package).get(1) self.assertEqual(None, loaded_e.supplier)
def create(environment_params, tenant_id): #tagging environment by tenant_id for later checks """ Creates environment with specified params, in particular - name :param environment_params: Dict, e.g. {'name': 'env-name'} :param tenant_id: Tenant Id :return: Created Environment """ objects = {'?': { 'id': uuidutils.generate_uuid(), }} objects.update(environment_params) objects.update( EnvironmentServices.generate_default_networks(objects['name'])) objects['?']['type'] = 'io.murano.Environment' environment_params['tenant_id'] = tenant_id data = { 'Objects': objects, 'Attributes': [] } environment = models.Environment() environment.update(environment_params) unit = db_session.get_session() with unit.begin(): unit.add(environment) #saving environment as Json to itself environment.update({'description': data}) environment.save(unit) return environment
def create(environment_params, context): # tagging environment by tenant_id for later checks """Creates environment with specified params, in particular - name :param environment_params: Dict, e.g. {'name': 'env-name'} :param context: request context to get the tenant id and the token :return: Created Environment """ objects = {"?": {"id": uuidutils.generate_uuid()}} network_driver = EnvironmentServices.get_network_driver(context) objects.update(environment_params) if not objects.get("defaultNetworks"): objects["defaultNetworks"] = EnvironmentServices.generate_default_networks(objects["name"], network_driver) objects["?"]["type"] = "io.murano.Environment" environment_params["tenant_id"] = context.tenant data = {"Objects": objects, "Attributes": []} environment = models.Environment() environment.update(environment_params) unit = db_session.get_session() with unit.begin(): unit.add(environment) # saving environment as Json to itself environment.update({"description": data}) environment.save(unit) return environment
def get_environment_description(environment_id, session_id=None, inner=True): """Returns environment description for specified environment. If session is specified and not in deploying state function returns modified environment description, otherwise returns actual environment desc. :param environment_id: Environment Id :param session_id: Session Id :param inner: return contents of environment rather than whole Object Model structure :return: Environment Description Object """ unit = db_session.get_session() if session_id: session = unit.query(models.Session).get(session_id) if sessions.SessionServices.validate(session): if session.state != states.SessionState.DEPLOYED: env_description = session.description else: env = unit.query(models.Environment).get(session.environment_id) env_description = env.description else: env = unit.query(models.Environment).get(session.environment_id) env_description = env.description else: env = unit.query(models.Environment).get(environment_id) env_description = env.description if not inner: return env_description else: return env_description["Objects"]
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 category_get_names(): session = db_session.get_session() categories = [] for row in session.query(models.Category.name).all(): for name in row: categories.append(name) return categories
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 create(env_template_params, tenant_id): """Creates environment-template with specified params, in particular - name. :param env_template_params: Dict, e.g. {'name': 'temp-name'} :param tenant_id: Tenant Id :return: Created Template """ env_template_params['id'] = uuidutils.generate_uuid() env_template_params['tenant_id'] = tenant_id env_template = models.EnvironmentTemplate() env_template.update(env_template_params) unit = db_session.get_session() with unit.begin(): try: unit.add(env_template) except db_exc.DBDuplicateEntry: msg = 'Environment template specified name already exists' LOG.exception(msg) raise db_exc.DBDuplicateEntry(explanation=msg) env_template.update({'description': env_template_params}) env_template.save(unit) return env_template
def track_instance(instance_id, environment_id, instance_type, type_name, type_title=None, unit_count=None): unit = db_session.get_session() try: with unit.begin(): env = unit.query(models.Environment).get(environment_id) instance = models.Instance() instance.instance_id = instance_id instance.environment_id = environment_id instance.tenant_id = env.tenant_id instance.instance_type = instance_type instance.created = timeutils.utcnow_ts() instance.destroyed = None instance.type_name = type_name instance.type_title = type_title instance.unit_count = unit_count unit.add(instance) except exception.DBDuplicateEntry: unit.execute( sqlalchemy.update(models.Instance).where( models.Instance.instance_id == instance_id and models.Instance.environment_id == environment_id).values( unit_count=unit_count))
def __inner(self, request, *args, **kwargs): if hasattr(request, 'context') and not request.context.session: msg = _('X-Configuration-Session header which indicates' ' to the session is missed') LOG.error(msg) raise exc.HTTPBadRequest(explanation=msg) session_id = request.context.session unit = db_session.get_session() session = unit.query(models.Session).get(session_id) if session is None: msg = _('Session <SessionId {0}> is not found').format(session_id) LOG.error(msg) raise exc.HTTPNotFound(explanation=msg) if not sessions.SessionServices.validate(session): msg = _('Session <SessionId {0}> ' 'is invalid: environment has been updated or ' 'updating right now with other session').format(session_id) LOG.error(msg) raise exc.HTTPForbidden(explanation=msg) if session.state == states.SessionState.DEPLOYING: msg = _('Session <SessionId {0}> is already in deployment state' ).format(session_id) raise exc.HTTPForbidden(explanation=msg) return func(self, request, *args, **kwargs)
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 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 _get_tags(tag_names, session=None): """Return existing tags object or create new ones :param tag_names: name of tags to associate with package, list :returns: list of Tag objects to associate with package, list """ if session is None: session = db_session.get_session() tags = [] # This function can be called inside a transaction and outside it. # In the former case this line is no-op, in the latter # starts a transaction we need to be inside a transaction, to correctly # handle DBDuplicateEntry errors without failing the whole transaction. # For more take a look at SQLAlchemy docs. with session.begin(subtransactions=True): for tag_name in tag_names: tag_obj = _existing_tag(tag_name, session) if not tag_obj: try: # Start a new SAVEPOINT transaction. If it fails only # only the savepoint will be roll backed, not the # whole transaction. with session.begin(nested=True): tag_obj = models.Tag(name=tag_name) session.add(tag_obj) session.flush(objects=[tag_obj]) except db_exceptions.DBDuplicateEntry: # new session is needed here to get access to the tag tag_obj = _existing_tag(tag_name) tags.append(tag_obj) return tags
def configure(self, request, environment_id): LOG.debug('Session:Configure <EnvId: {0}>'.format(environment_id)) unit = db_session.get_session() environment = unit.query(models.Environment).get(environment_id) if environment is None: msg = _('Environment <EnvId {0}>' ' is not found').format(environment_id) LOG.error(msg) raise exc.HTTPNotFound(explanation=msg) if environment.tenant_id != request.context.tenant: msg = _('User is not authorized to access ' 'this tenant resources.') LOG.error(msg) raise exc.HTTPUnauthorized(explanation=msg) # 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): msg = _('Could not open session for environment <EnvId: {0}>,' 'environment has deploying status.').format(environment_id) LOG.error(msg) raise exc.HTTPForbidden(explanation=msg) user_id = request.context.user session = sessions.SessionServices.create(environment_id, user_id) return session.to_dict()
def package_update(pkg_id_or_name, changes, context): """Update package information :param changes: parameters to update :returns: detailed information about new package, dict """ operation_methods = {'add': _do_add, 'replace': _do_replace, 'remove': _do_remove} session = db_session.get_session() with session.begin(): pkg = _package_get(pkg_id_or_name, session) was_private = not pkg.is_public if not context.is_admin: _authorize_package(pkg, context) for change in changes: pkg = operation_methods[change['op']](pkg, change) became_public = pkg.is_public class_names = [clazz.name for clazz in pkg.class_definitions] if was_private and became_public: with db_session.get_lock("public_packages", session): _check_for_public_packages_with_fqn(session, pkg.fully_qualified_name, pkg.id) _check_for_existing_classes(session, class_names, None, check_public=True, ignore_package_with_id=pkg.id) session.add(pkg) return pkg
def create(environment_id, user_id): """ Creates session object for specific environment for specified user. :param environment_id: Environment Id :param user_id: User Id :return: Created session """ unit = db_session.get_session() environment = unit.query(models.Environment).get(environment_id) session = models.Session() session.environment_id = environment.id session.user_id = user_id session.state = SessionState.open # used for checking if other sessions was deployed before this one session.version = environment.version # all changes to environment is stored here, and translated to # environment only after deployment completed session.description = environment.description with unit.begin(): unit.add(session) return session
def validate(session): """ Session is valid only if no other session for same environment was already deployed on in deploying state, :param session: Session for validation """ #if other session is deploying now current session is invalid unit = db_session.get_session() #if environment version is higher then version on which current session #is created then other session was already deployed current_env = unit.query(models.Environment).\ get(session.environment_id) if current_env.version > session.version: return False #if other session is deploying now current session is invalid other_is_deploying = unit.query(models.Session).filter_by( environment_id=session.environment_id, state=SessionState.deploying ).count() > 0 if session.state == SessionState.open and other_is_deploying: return False return True
def __inner(self, request, *args, **kwargs): if hasattr(request, 'context') and not request.context.session: LOG.info(_LI('Session is required for this call')) raise exc.HTTPForbidden() session_id = request.context.session unit = db_session.get_session() session = unit.query(models.Session).get(session_id) if session is None: LOG.info(_LI('Session <SessionId {0}> ' 'is not found').format(session_id)) raise exc.HTTPForbidden() if not sessions.SessionServices.validate(session): LOG.info(_LI('Session <SessionId {0}> ' 'is invalid').format(session_id)) raise exc.HTTPForbidden() if session.state == states.SessionState.DEPLOYING: LOG.info(_LI('Session <SessionId {0}> is already in ' 'deployment state').format(session_id)) raise exc.HTTPForbidden() return func(self, request, *args, **kwargs)
def clone(env_template_id, tenant_id, env_template_name, is_public): """Clones environment-template with specified params, in particular - name. :param env_template_params: Dict, e.g. {'name': 'temp-name'} :param tenant_id: Tenant Id :return: Created Template """ template = EnvTemplateServices.get_env_template(env_template_id) env_template_params = template.to_dict() env_template_params['id'] = uuidutils.generate_uuid() env_template_params['tenant_id'] = tenant_id env_template_params['name'] = env_template_name env_template_params['is_public'] = is_public env_temp_desc = EnvTemplateServices.get_description(env_template_id) if "services" in env_temp_desc: env_template_params['services'] = env_temp_desc['services'] env_template = models.EnvironmentTemplate() env_template.update(env_template_params) unit = db_session.get_session() with unit.begin(): unit.add(env_template) env_template.update({'description': env_template_params}) env_template.save(unit) return env_template
def destroy_instance(instance_id, environment_id): unit = db_session.get_session() instance = unit.query(models.Instance).get( (environment_id, instance_id)) if instance and not instance.destroyed: instance.destroyed = timeutils.utcnow_ts() instance.save(unit)
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 show(self, request, environment_id, session_id): LOG.debug('Session:Show <SessionId: {id}>'.format(id=session_id)) unit = db_session.get_session() session = unit.query(models.Session).get(session_id) check_session(request, environment_id, session, session_id) user_id = request.context.user if session.user_id != user_id: msg = _('User <UserId {usr_id}> is not authorized to access' 'session <SessionId {s_id}>.').format(usr_id=user_id, s_id=session_id) LOG.error(msg) raise exc.HTTPUnauthorized(explanation=msg) if not sessions.SessionServices.validate(session): msg = _('Session <SessionId {0}> is invalid: environment has been' ' updated or updating right now with other session' ).format(session_id) LOG.error(msg) raise exc.HTTPForbidden(explanation=msg) return session.to_dict()
def show(self, request, environment_id, session_id): LOG.debug("Session:Show <SessionId: {0}>".format(session_id)) unit = db_session.get_session() session = unit.query(models.Session).get(session_id) if session is None: LOG.error(_("Session <SessionId {0}> " "is not found").format(session_id)) raise exc.HTTPNotFound() if session.environment_id != environment_id: LOG.error( _("Session <SessionId {0}> is not tied with Environment " "<EnvId {1}>").format( session_id, environment_id ) ) raise exc.HTTPNotFound() user_id = request.context.user if session.user_id != user_id: LOG.error( _("User <UserId {0}> is not authorized to access session" "<SessionId {1}>.").format( user_id, session_id ) ) raise exc.HTTPUnauthorized() if not sessions.SessionServices.validate(session): LOG.error(_("Session <SessionId {0}> " "is invalid").format(session_id)) raise exc.HTTPForbidden() return session.to_dict()
def configure(self, request, environment_id): LOG.debug("Session:Configure <EnvId: {0}>".format(environment_id)) unit = db_session.get_session() environment = unit.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 # no new session can be opened if environment has deploying status env_status = envs.EnvironmentServices.get_status(environment_id) if env_status == envs.EnvironmentStatus.deploying: LOG.info( _("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) return session.to_dict()
def get_env_template(env_template_id): """It obtains the environment template information from the database. :param env_template_id: The template ID """ session = db_session.get_session() return session.query(models.EnvironmentTemplate).get(env_template_id)
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 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 delete(self, request, environment_id, session_id): LOG.debug('Session:Delete <SessionId: {0}>'.format(session_id)) unit = db_session.get_session() session = unit.query(models.Session).get(session_id) self._check_session(request, environment_id, session, session_id) user_id = request.context.user if session.user_id != user_id: msg = _('User <UserId {0}> is not authorized to access session' '<SessionId {1}>.').format(user_id, session_id) LOG.error(msg) raise exc.HTTPUnauthorized(explanation=msg) if session.state == states.SessionState.DEPLOYING: msg = _('Session <SessionId: {0}> is in deploying state and ' 'could not be deleted').format(session_id) LOG.error(msg) raise exc.HTTPForbidden(explanation=msg) with unit.begin(): unit.delete(session) return None
def deploy(self, request, environment_id, session_id): LOG.debug("Session:Deploy <SessionId: {0}>".format(session_id)) unit = db_session.get_session() session = unit.query(models.Session).get(session_id) if session is None: LOG.error(_("Session <SessionId {0}> " "is not found").format(session_id)) raise exc.HTTPNotFound() if session.environment_id != environment_id: LOG.error( _("Session <SessionId {0}> is not tied with Environment " "<EnvId {1}>").format( session_id, environment_id ) ) raise exc.HTTPNotFound() if not sessions.SessionServices.validate(session): LOG.error(_("Session <SessionId {0}> " "is invalid").format(session_id)) raise exc.HTTPForbidden() if session.state != sessions.SessionState.open: LOG.error( _("Session <SessionId {0}> is already deployed or " "deployment is in progress").format(session_id) ) raise exc.HTTPForbidden() sessions.SessionServices.deploy(session, unit, request.context.auth_token)
def package_delete(package_id_or_name, context): """Delete a package by name or by ID""" session = db_session.get_session() with session.begin(): package = _package_get(package_id_or_name, session) _authorize_package(package, context) session.delete(package)
def check_env(request, environment_id): unit = db_session.get_session() environment = unit.query(models.Environment).get(environment_id) if environment is None: msg = _('Environment with id {0}' ' not found').format(environment_id) LOG.warning(msg) raise exc.HTTPNotFound(explanation=msg) if hasattr(request, 'context'): if environment.tenant_id != request.context.tenant: msg = _('User is not authorized to access' ' these tenant resources') LOG.warning(msg) raise exc.HTTPForbidden(explanation=msg) return environment
def __inner(self, request, environment_id, *args, **kwargs): unit = db_session.get_session() environment = unit.query(models.Environment).get(environment_id) if environment is None: LOG.info(_("Environment with id '{0}'" " not found").format(environment_id)) raise exc.HTTPNotFound() if hasattr(request, 'context'): if environment.tenant_id != request.context.tenant: LOG.info(_('User is not authorized to access' ' this tenant resources')) raise exc.HTTPUnauthorized() return func(self, request, environment_id, *args, **kwargs)
def _create_stats(self, which_kwargs): stats = models.ApiStats() for key, val in which_kwargs.items(): setattr(stats, key, val) stats.requests_per_second = 1.2 stats.errors_per_second = 2.3 unit = db_session.get_session() with unit.begin(): unit.add(stats) self.assertIsNotNone(stats) self.stats_list.append(stats) return stats
def create(host, request_count, error_count, average_response_time, request_per_tenant, cpu_count, cpu_percent): stats = m.ApiStats() stats.host = host stats.request_count = request_count stats.error_count = error_count stats.average_response_time = average_response_time stats.request_per_tenant = request_per_tenant stats.request_per_second = 0.0 stats.errors_per_second = 0.0 stats.cpu_count = cpu_count stats.cpu_percent = cpu_percent db = db_session.get_session() stats.save(db)
def report_notification(report): LOG.debug('Got report from orchestration ' 'engine:\n{0}'.format(report)) report['entity_id'] = report['id'] del report['id'] status = models.Status() status.update(report) unit = session.get_session() #connect with deployment with unit.begin(): running_deployment = get_last_deployment(unit, status.environment_id) status.task_id = running_deployment.id unit.add(status)
def set_instance_for_service(instance_id, service_id, environment_id, tenant): """Store env-space link to db""" unit = db_session.get_session() try: with unit.begin(): connection = models.CFServiceInstance() connection.id = instance_id connection.service_id = service_id connection.environment_id = environment_id connection.tenant = tenant unit.add(connection) except exception.DBDuplicateEntry: unit.execute(sqlalchemy.update(models.CFServiceInstance).where( models.CFServiceInstance.id == instance_id).values( environment_id=environment_id))
def _check_environment(self, request, environment_id): unit = db_session.get_session() environment = unit.query(models.Environment).get(environment_id) if environment is None: msg = _('Environment <EnvId {0}>' ' is not found').format(environment_id) LOG.error(msg) raise exc.HTTPNotFound(explanation=msg) if environment.tenant_id != request.context.tenant: msg = _('User is not authorized to access ' 'this tenant resources.') LOG.error(msg) raise exc.HTTPUnauthorized(explanation=msg)
def _get_tags(tag_names, session=None): """Return existing tags object or create new ones :param tag_names: name of tags to associate with package, list :returns: list of Tag objects to associate with package, list """ if session is None: session = db_session.get_session() tags = [] for tag_name in tag_names: tag_obj = session.query(models.Tag).filter_by(name=tag_name).first() if tag_obj: tags.append(tag_obj) else: tag_record = models.Tag(name=tag_name) tags.append(tag_record) return tags
def category_get(category_id, session=None, packages=False): """Return category details :param category_id: ID of a category, string :returns: detailed information about category, dict """ if not session: session = db_session.get_session() category = session.query(models.Category).get(category_id) if not category: msg = _("Category id '{id}' not found").format(id=category_id) LOG.error(msg) raise exc.HTTPNotFound(msg) if packages: category.packages = _get_packages_for_category(session, category_id) return category
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}
def get_result(self, request, environment_id, task_id): policy.check("execute_action", request.context, {}) LOG.debug('Action:GetResult <TaskId: {id}>'.format(id=task_id)) unit = db_session.get_session() result = actions.ActionServices.get_result(environment_id, task_id, unit) if result is not None: return result msg = ('Result for task with environment_id: {env_id} and task_id: ' '{task_id} was not found.'.format(env_id=environment_id, task_id=task_id)) LOG.error(msg) raise exc.HTTPNotFound(msg)
def package_upload(values, tenant_id): """Upload a package with new application :param values: parameters describing the new package :returns: detailed information about new package, dict """ session = db_session.get_session() package = models.Package() composite_attr_to_func = { 'categories': _get_categories, 'tags': _get_tags, 'class_definitions': _get_class_definitions } is_public = values.get('is_public', False) if is_public: public_lock = db_session.get_lock("public_packages", session) else: public_lock = None tenant_lock = db_session.get_lock("classes_of_" + tenant_id, session) try: _check_for_existing_classes(session, values.get('class_definitions'), tenant_id, check_public=is_public) if is_public: _check_for_public_packages_with_fqn( session, values.get('fully_qualified_name')) for attr, func in six.iteritems(composite_attr_to_func): if values.get(attr): result = func(values[attr], session) setattr(package, attr, result) del values[attr] package.update(values) package.owner_id = tenant_id package.save(session) tenant_lock.commit() if public_lock is not None: public_lock.commit() except Exception: tenant_lock.rollback() if public_lock is not None: public_lock.rollback() raise return package
def get_result(self, request, environment_id, task_id): policy.check("execute_action", request.context, {}) LOG.debug('Action:GetResult <TaskId: {0}>'.format(task_id)) unit = db_session.get_session() self._validate_environment(unit, request, environment_id) result = actions.ActionServices.get_result(environment_id, task_id, unit) if result is not None: return result msg = (_('Result for task with environment_id: {} and ' 'task_id: {} was not found.').format(environment_id, task_id)) LOG.error(msg) raise exc.HTTPNotFound(msg)
def __inner(self, request, env_template_id, *args, **kwargs): unit = db_session.get_session() template = unit.query(models.EnvironmentTemplate).get(env_template_id) if template is None: msg = _('Environment Template with id {id} not found').format( id=env_template_id) LOG.error(msg) raise exc.HTTPNotFound(explanation=msg) if hasattr(request, 'context'): if template.tenant_id != request.context.tenant: msg = _('User is not authorized to access' ' this tenant resources') LOG.error(msg) raise exc.HTTPForbidden(explanation=msg) return func(self, request, env_template_id, *args, **kwargs)
def save_environment_description(session_id, environment, inner=True): """Saves environment description to specified session. :param session_id: Session Id :param environment: Environment Description :param inner: save modifications to only content of environment rather than whole Object Model structure """ unit = db_session.get_session() session = unit.query(models.Session).get(session_id) if inner: data = session.description.copy() data['Objects'] = environment session.description = data else: session.description = environment session.save(unit)
def get_aggregated_stats(environment_id): unit = db_session.get_session() now = timeutils.utcnow_ts() query = unit.query( models.Instance.instance_type, func.sum( func.coalesce(models.Instance.destroyed, now) - models.Instance.created), func.count()).filter( models.Instance.environment_id == environment_id) res = query.group_by(models.Instance.instance_type).all() return [{ 'type': int(record[0]), 'duration': int(record[1]), 'count': int(record[2]) } for record in res]
def __inner(self, request, env_template_id, *args, **kwargs): unit = db_session.get_session() template = unit.query(models.EnvironmentTemplate).get(env_template_id) if template is None: LOG.error( _LE("Environment Template with id '{id}' not found").format( id=env_template_id)) raise exc.HTTPNotFound() if hasattr(request, 'context'): if template.tenant_id != request.context.tenant: LOG.error( _LE('User is not authorized to access ' 'this tenant resources')) raise exc.HTTPUnauthorized() return func(self, request, env_template_id, *args, **kwargs)
def report_notification(report): LOG.debug('Got report from orchestration ' 'engine:\n{report}'.format(report=report)) report['entity_id'] = report.pop('id') status = models.Status() if 'timestamp' in report: dt = timeutils.parse_isotime(report.pop('timestamp')) report['created'] = dt.astimezone(pytz.utc).replace(tzinfo=None) status.update(report) unit = session.get_session() # connect with deployment with unit.begin(): running_deployment = get_last_deployment(unit, status.environment_id) status.task_id = running_deployment.id unit.add(status)
def package_update(pkg_id_or_name, changes, context): """Update package information :param changes: parameters to update :returns: detailed information about new package, dict """ operation_methods = {'add': _do_add, 'replace': _do_replace, 'remove': _do_remove} session = db_session.get_session() with session.begin(): pkg = _package_get(pkg_id_or_name, session) _authorize_package(pkg, context) for change in changes: pkg = operation_methods[change['op']](pkg, change) session.add(pkg) return pkg
def test_environment_ready_if_last_session_deployed_after_failed(self): """Test environment ready status If last session was deployed successfully and other session was failed - environment must have status "ready". Bug: #1413260 """ OLD_VERSION = 0 LATEST_VERSION = 1 session = db_session.get_session() environment = models.Environment( name='test_environment', tenant_id='test_tenant_id', version=LATEST_VERSION ) session.add(environment) now = timeutils.utcnow() session_1 = models.Session( environment=environment, user_id='test_user_id_1', version=OLD_VERSION, state=states.SessionState.DEPLOY_FAILURE, updated=now, description={} ) session_2 = models.Session( environment=environment, user_id='test_user_id_2', version=LATEST_VERSION, state=states.SessionState.DEPLOYED, updated=now + dt.timedelta(minutes=1), description={} ) session.add_all([session_1, session_2]) session.flush() expected_status = states.EnvironmentStatus.READY actual_status = environments.EnvironmentServices.get_status( environment.id ) self.assertEqual(expected_status, actual_status)
def create(environment_params, context): # tagging environment by tenant_id for later checks """Creates environment with specified params, in particular - name :param environment_params: Dict, e.g. {'name': 'env-name'} :param context: request context to get the tenant id and the token :return: Created Environment """ objects = { '?': { 'id': uuidutils.generate_uuid(), } } network_driver = EnvironmentServices.get_network_driver(context) objects.update(environment_params) if not objects.get('defaultNetworks'): objects['defaultNetworks'] = \ EnvironmentServices.generate_default_networks(objects['name'], network_driver) objects['?']['type'] = 'io.murano.Environment' objects['?']['metadata'] = {} data = { 'Objects': objects, 'Attributes': [], 'project_id': context.tenant, 'user_id': context.user } environment_params['tenant_id'] = context.tenant environment = models.Environment() environment.update(environment_params) unit = db_session.get_session() with unit.begin(): unit.add(environment) # saving environment as Json to itself environment.update({'description': data}) environment.save(unit) return environment
def get_raw_environment_stats(environment_id, instance_id=None): unit = db_session.get_session() now = timeutils.utcnow_ts() query = unit.query(models.Instance).filter( models.Instance.environment_id == environment_id) if instance_id: query = query.filter(models.Instance.instance_id == instance_id) res = query.all() return [{ 'type': record.instance_type, 'duration': (record.destroyed or now) - record.created, 'type_name': record.type_name, 'unit_count': record.unit_count, 'instance_id': record.instance_id, 'type_title': record.type_title, 'active': True if not record.destroyed else False } for record in res]
def last(self, request, environment_id): session_id = None if hasattr(request, 'context') and request.context.session: session_id = request.context.session services = core_services.CoreServices.get_data(environment_id, '/services', session_id) session = db_session.get_session() result = {} for service in services or []: service_id = service['?']['id'] entity_ids = utils.build_entity_map(service).keys() last_status = session.query(models.Status). \ filter(models.Status.entity_id.in_(entity_ids)). \ order_by(desc(models.Status.created)). \ first() if last_status: result[service_id] = last_status.to_dict() else: result[service_id] = None return {'lastStatuses': result}
def test_get_status(self): session = db_session.get_session() session.add(self.environment) now = timeutils.utcnow() session_1 = models.Session(environment=self.environment, user_id='test_user_id_1', version=OLD_VERSION, state=states.SessionState.DEPLOY_FAILURE, updated=now, description={}) session.add(session_1) session.flush() expected_status = states.EnvironmentStatus.DEPLOY_FAILURE self.assertEqual(expected_status, self.env_services.get_status(self.environment.id))
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() environment = unit.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 # 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( _('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( _('Session <SessionId {0}> ' 'is invalid').format(session.id)) raise exc.HTTPForbidden() actions.ActionServices.execute(action_id, session, unit, request.context.auth_token, body or {})
def show(self, request, environment_id, session_id): LOG.debug('Session:Show <SessionId: {0}>'.format(session_id)) unit = db_session.get_session() session = unit.query(models.Session).get(session_id) self._check_session(environment_id, session, session_id) user_id = request.context.user msg = _('User <UserId {0}> is not authorized to access session' '<SessionId {1}>.').format(user_id, session_id) if session.user_id != user_id: LOG.error(msg) raise exc.HTTPUnauthorized(explanation=msg) if not sessions.SessionServices.validate(session): msg = _('Session <SessionId {0}> is invalid').format(session_id) LOG.error(msg) raise exc.HTTPForbidden(explanation=msg) return session.to_dict()
def _get_categories(category_names, session=None): """Return existing category objects or raise an exception. :param category_names: name of categories to associate with package, list :returns: list of Category objects to associate with package, list """ if session is None: session = db_session.get_session() categories = [] for ctg_name in category_names: ctg_obj = session.query(models.Category).filter_by( name=ctg_name).first() if not ctg_obj: msg = _("Category '{name}' doesn't exist").format(name=ctg_name) LOG.error(msg) # it's not allowed to specify non-existent categories raise exc.HTTPBadRequest(explanation=msg) categories.append(ctg_obj) return categories
def deploy(self, request, environment_id, session_id): LOG.debug('Session:Deploy <SessionId: {0}>'.format(session_id)) unit = db_session.get_session() session = unit.query(models.Session).get(session_id) self._check_session(environment_id, session, session_id) if not sessions.SessionServices.validate(session): msg = _('Session <SessionId {0}> is invalid').format(session_id) LOG.error(msg) raise exc.HTTPForbidden(explanation=msg) if session.state != sessions.SessionState.OPENED: msg = _('Session <SessionId {0}> is already deployed or ' 'deployment is in progress').format(session_id) LOG.error(msg) raise exc.HTTPForbidden(explanation=msg) envs.EnvironmentServices.deploy(session, unit, request.context.auth_token)
def test_update(self): """Note: this test expects to test update functionality. However, the current implementation of Statistics.update() does not actually update the host of the statistics object passed in. It just saves the object that is passed in, which appears to contradict its intended use case. """ stats = models.ApiStats() for key, val in self.stats_kwargs.items(): setattr(stats, key, val) statistics.Statistics.update('test_host', stats) unit = db_session.get_session() retrieved_stats = None with unit.begin(): retrieved_stats = unit.query(models.ApiStats)\ .order_by(models.ApiStats.id.desc()).first() self.assertIsNotNone(retrieved_stats) self.assertTrue( self._are_stats_equal(stats, retrieved_stats, check_type=True))
def get_service_status(environment_id, session_id, service): status = 'draft' unit = db_session.get_session() session_state = unit.query(models.Session).get(session_id).state entities = [u['id'] for u in service['units']] reports_count = unit.query(models.Status).filter( models.Status.environment_id == environment_id and models.Status.session_id == session_id and models.Status.entity_id.in_(entities)).count() if session_state == 'deployed': status = 'finished' if session_state == 'deploying' and reports_count == 0: status = 'pending' if session_state == 'deploying' and reports_count > 0: status = 'inprogress' return status