コード例 #1
0
    def post(self, audit_p):
        """Create a new audit.

        :param audit_p: an audit within the request body.
        """
        context = pecan.request.context
        policy.enforce(context, 'audit:create', action='audit:create')
        audit = audit_p.as_audit(context)

        if self.from_audits:
            raise exception.OperationNotPermitted

        if not audit._goal_uuid:
            raise exception.Invalid(
                message=_('A valid goal_id or audit_template_id '
                          'must be provided'))

        strategy_uuid = audit.strategy_uuid
        no_schema = True
        if strategy_uuid is not None:
            # validate parameter when predefined strategy in audit template
            strategy = objects.Strategy.get(pecan.request.context,
                                            strategy_uuid)
            schema = strategy.parameters_spec
            if schema:
                # validate input parameter with default value feedback
                no_schema = False
                utils.StrictDefaultValidatingDraft4Validator(schema).validate(
                    audit.parameters)

        if no_schema and audit.parameters:
            raise exception.Invalid(
                _('Specify parameters but no predefined '
                  'strategy for audit, or no '
                  'parameter spec in predefined strategy'))

        audit_dict = audit.as_dict()
        # convert local time to UTC time
        start_time_value = audit_dict.get('start_time')
        end_time_value = audit_dict.get('end_time')
        if start_time_value:
            audit_dict['start_time'] = start_time_value.replace(
                tzinfo=tz.tzlocal()).astimezone(
                    tz.tzutc()).replace(tzinfo=None)
        if end_time_value:
            audit_dict['end_time'] = end_time_value.replace(
                tzinfo=tz.tzlocal()).astimezone(
                    tz.tzutc()).replace(tzinfo=None)

        new_audit = objects.Audit(context, **audit_dict)
        new_audit.create()

        # Set the HTTP Location Header
        pecan.response.location = link.build_url('audits', new_audit.uuid)

        # trigger decision-engine to run the audit
        if new_audit.audit_type == objects.audit.AuditType.ONESHOT.value:
            self.dc_client.trigger_audit(context, new_audit.uuid)

        return Audit.convert_with_links(new_audit)
コード例 #2
0
ファイル: keystone_helper.py プロジェクト: sjamgade/watcher
 def get_user(self, name_or_id):
     try:
         user = self.keystone.users.get(name_or_id)
         return user
     except ks_exceptions.NotFound:
         users = self.keystone.users.list(name=name_or_id)
         if len(users) == 0:
             raise exception.Invalid(message=(_("User not Found: %s") %
                                              name_or_id))
         if len(users) > 1:
             raise exception.Invalid(
                 message=(_("User name seems ambiguous: %s") % name_or_id))
         return users[0]
コード例 #3
0
    def _cold_migrate(self, volume, dest_node, dest_type):
        if not self.cinder_util.can_cold(volume, dest_node):
            raise exception.Invalid(
                message=(_("Invalid state for cold migration")))

        if dest_node:
            return self.cinder_util.migrate(volume, dest_node)
        elif dest_type:
            return self.cinder_util.retype(volume, dest_type)
        else:
            raise exception.Invalid(
                message=(_("destination host or destination type is "
                           "required when migration type is cold")))
コード例 #4
0
ファイル: keystone_helper.py プロジェクト: sjamgade/watcher
 def get_role(self, name_or_id):
     try:
         role = self.keystone.roles.get(name_or_id)
         return role
     except ks_exceptions.NotFound:
         roles = self.keystone.roles.list(name=name_or_id)
         if len(roles) == 0:
             raise exception.Invalid(message=(_("Role not Found: %s") %
                                              name_or_id))
         if len(roles) > 1:
             raise exception.Invalid(
                 message=(_("Role name seems ambiguous: %s") % name_or_id))
     return roles[0]
コード例 #5
0
ファイル: keystone_helper.py プロジェクト: sjamgade/watcher
 def get_domain(self, name_or_id):
     try:
         domain = self.keystone.domains.get(name_or_id)
         return domain
     except ks_exceptions.NotFound:
         domains = self.keystone.domains.list(name=name_or_id)
         if len(domains) == 0:
             raise exception.Invalid(message=(_("Domain not Found: %s") %
                                              name_or_id))
         if len(domains) > 1:
             raise exception.Invalid(
                 message=(_("Domain name seems ambiguous: %s") %
                          name_or_id))
         return domains[0]
コード例 #6
0
ファイル: keystone_helper.py プロジェクト: sjamgade/watcher
 def get_project(self, name_or_id):
     try:
         project = self.keystone.projects.get(name_or_id)
         return project
     except ks_exceptions.NotFound:
         projects = self.keystone.projects.list(name=name_or_id)
         if len(projects) == 0:
             raise exception.Invalid(message=(_("Project not Found: %s") %
                                              name_or_id))
         if len(projects) > 1:
             raise exception.Invalid(
                 messsage=(_("Project name seems ambiguous: %s") %
                           name_or_id))
         return projects[0]
コード例 #7
0
ファイル: audit.py プロジェクト: Jean-Emile/watcher
    def post(self, audit):
        """Create a new audit.

        :param audit: a audit within the request body.
        """
        if self.from_audits:
            raise exception.OperationNotPermitted

        if not audit._audit_template_uuid:
            raise exception.Invalid(
                message=_('The audit template UUID or name specified is '
                          'invalid'))

        audit_dict = audit.as_dict()
        context = pecan.request.context
        new_audit = objects.Audit(context, **audit_dict)
        new_audit.create(context)

        # Set the HTTP Location Header
        pecan.response.location = link.build_url('audits', new_audit.uuid)

        # trigger decision-engine to run the audit

        dc_client = rpcapi.DecisionEngineAPI()
        dc_client.trigger_audit(context, new_audit.uuid)

        return Audit.convert_with_links(new_audit)
コード例 #8
0
    def _migrate(self, volume_id, dest_node, dest_type):

        try:
            volume = self.cinder_util.get_volume(volume_id)
            if self.migration_type == self.SWAP:
                if dest_node:
                    LOG.warning("dest_node is ignored")
                return self._swap_volume(volume, dest_type)
            elif self.migration_type == self.RETYPE:
                return self.cinder_util.retype(volume, dest_type)
            elif self.migration_type == self.MIGRATE:
                return self.cinder_util.migrate(volume, dest_node)
            else:
                raise exception.Invalid(
                    message=(_("Migration of type '%(migration_type)s' is not "
                               "supported.") % {
                                   'migration_type': self.migration_type
                               }))
        except exception.Invalid as ei:
            LOG.exception(ei)
            return False
        except Exception as e:
            LOG.critical("Unexpected exception occurred.")
            LOG.exception(e)
            return False
コード例 #9
0
ファイル: api.py プロジェクト: icclab/watcher
    def update_action_plan(self, action_plan_id, values):
        if 'uuid' in values:
            raise exception.Invalid(
                message=_("Cannot overwrite UUID for an existing "
                          "Action Plan."))

        return self._do_update_action_plan(action_plan_id, values)
コード例 #10
0
ファイル: types.py プロジェクト: akinsWin/watcher
 def validate(value):
     try:
         jsonutils.dumps(value, default=None)
     except TypeError:
         raise exception.Invalid(_('%s is not JSON serializable') % value)
     else:
         return value
コード例 #11
0
ファイル: api.py プロジェクト: crowdy/watcher
    def update_action(self, action_id, values):
        # NOTE(dtantsur): this can lead to very strange errors
        if 'uuid' in values:
            raise exception.Invalid(
                message=_("Cannot overwrite UUID for an existing Action."))

        return self._do_update_action(action_id, values)
コード例 #12
0
    def validate(audit_template):
        available_goals = objects.Goal.list(AuditTemplatePostType._ctx)
        available_goal_uuids_map = {g.uuid: g for g in available_goals}
        available_goal_names_map = {g.name: g for g in available_goals}
        if audit_template.goal in available_goal_uuids_map:
            goal = available_goal_uuids_map[audit_template.goal]
        elif audit_template.goal in available_goal_names_map:
            goal = available_goal_names_map[audit_template.goal]
        else:
            raise exception.InvalidGoal(goal=audit_template.goal)

        common_utils.Draft4Validator(
            default.DefaultScope.DEFAULT_SCHEMA).validate(audit_template.scope)

        include_host_aggregates = False
        exclude_host_aggregates = False
        for rule in audit_template.scope:
            if 'host_aggregates' in rule:
                include_host_aggregates = True
            elif 'exclude' in rule:
                for resource in rule['exclude']:
                    if 'host_aggregates' in resource:
                        exclude_host_aggregates = True
        if include_host_aggregates and exclude_host_aggregates:
            raise exception.Invalid(
                message=_("host_aggregates can't be "
                          "included and excluded together"))

        if audit_template.strategy:
            available_strategies = objects.Strategy.list(
                AuditTemplatePostType._ctx)
            available_strategies_map = {
                s.uuid: s
                for s in available_strategies
            }
            if audit_template.strategy not in available_strategies_map:
                raise exception.InvalidStrategy(
                    strategy=audit_template.strategy)

            strategy = available_strategies_map[audit_template.strategy]
            # Check that the strategy we indicate is actually related to the
            # specified goal
            if strategy.goal_id != goal.id:
                choices = [
                    "'%s' (%s)" % (s.uuid, s.name)
                    for s in available_strategies
                ]
                raise exception.InvalidStrategy(
                    message=_("'%(strategy)s' strategy does relate to the "
                              "'%(goal)s' goal. Possible choices: %(choices)s")
                    % dict(strategy=strategy.name,
                           goal=goal.name,
                           choices=", ".join(choices)))
            audit_template.strategy = strategy.uuid

        # We force the UUID so that we do not need to query the DB with the
        # name afterwards
        audit_template.goal = goal.uuid

        return audit_template
コード例 #13
0
ファイル: api.py プロジェクト: icclab/watcher
    def update_audit(self, audit_id, values):
        if 'uuid' in values:
            raise exception.Invalid(
                message=_("Cannot overwrite UUID for an existing "
                          "Audit."))

        return self._do_update_audit(audit_id, values)
コード例 #14
0
ファイル: api.py プロジェクト: crowdy/watcher
    def update_goal(self, goal_id, values):
        if 'uuid' in values:
            raise exception.Invalid(
                message=_("Cannot overwrite UUID for an existing Goal."))

        try:
            return self._update(models.Goal, goal_id, values)
        except exception.ResourceNotFound:
            raise exception.GoalNotFound(goal=goal_id)
コード例 #15
0
ファイル: api.py プロジェクト: crowdy/watcher
    def update_strategy(self, strategy_id, values):
        if 'uuid' in values:
            raise exception.Invalid(
                message=_("Cannot overwrite UUID for an existing Strategy."))

        try:
            return self._update(models.Strategy, strategy_id, values)
        except exception.ResourceNotFound:
            raise exception.StrategyNotFound(strategy=strategy_id)
コード例 #16
0
ファイル: api.py プロジェクト: crowdy/watcher
    def update_audit(self, audit_id, values):
        if 'uuid' in values:
            raise exception.Invalid(
                message=_("Cannot overwrite UUID for an existing "
                          "Audit."))

        try:
            return self._update(models.Audit, audit_id, values)
        except exception.ResourceNotFound:
            raise exception.AuditNotFound(audit=audit_id)
コード例 #17
0
ファイル: api.py プロジェクト: crowdy/watcher
    def update_efficacy_indicator(self, efficacy_indicator_id, values):
        if 'uuid' in values:
            raise exception.Invalid(
                message=_("Cannot overwrite UUID for an existing "
                          "efficacy indicator."))

        try:
            return self._update(
                models.EfficacyIndicator, efficacy_indicator_id, values)
        except exception.ResourceNotFound:
            raise exception.EfficacyIndicatorNotFound(
                efficacy_indicator=efficacy_indicator_id)
コード例 #18
0
ファイル: api.py プロジェクト: crowdy/watcher
    def update_scoring_engine(self, scoring_engine_id, values):
        if 'uuid' in values:
            raise exception.Invalid(
                message=_("Cannot overwrite UUID for an existing "
                          "Scoring Engine."))

        try:
            return self._update(
                models.ScoringEngine, scoring_engine_id, values)
        except exception.ResourceNotFound:
            raise exception.ScoringEngineNotFound(
                scoring_engine=scoring_engine_id)
コード例 #19
0
ファイル: cinder_helper.py プロジェクト: sjamgade/watcher
    def retype(self, volume, dest_type):
        """Retype volume to dest_type with on-demand option"""
        volume = self.get_volume(volume)
        if volume.volume_type == dest_type:
            raise exception.Invalid(
                message=(_("Volume type must be different for retyping")))

        source_node = getattr(volume, 'os-vol-host-attr:host')
        LOG.debug("Volume %s found on host '%s'.", (volume.id, source_node))

        self.cinder.volumes.retype(volume, dest_type, "on-demand")

        return self.check_migrated(volume)
コード例 #20
0
    def as_audit(self, context):
        audit_type_values = [val.value for val in objects.audit.AuditType]
        if self.audit_type not in audit_type_values:
            raise exception.AuditTypeNotFound(audit_type=self.audit_type)

        if (self.audit_type == objects.audit.AuditType.ONESHOT.value
                and self.interval not in (wtypes.Unset, None)):
            raise exception.AuditIntervalNotAllowed(audit_type=self.audit_type)

        if (self.audit_type == objects.audit.AuditType.CONTINUOUS.value
                and self.interval in (wtypes.Unset, None)):
            raise exception.AuditIntervalNotSpecified(
                audit_type=self.audit_type)

        # If audit_template_uuid was provided, we will provide any
        # variables not included in the request, but not override
        # those variables that were included.
        if self.audit_template_uuid:
            try:
                audit_template = objects.AuditTemplate.get(
                    context, self.audit_template_uuid)
            except exception.AuditTemplateNotFound:
                raise exception.Invalid(
                    message=_('The audit template UUID or name specified is '
                              'invalid'))
            at2a = {
                'goal': 'goal_id',
                'strategy': 'strategy_id',
                'scope': 'scope',
            }
            to_string_fields = set(['goal', 'strategy'])
            for k in at2a:
                if not getattr(self, k):
                    try:
                        at_attr = getattr(audit_template, at2a[k])
                        if at_attr and (k in to_string_fields):
                            at_attr = str(at_attr)
                        setattr(self, k, at_attr)
                    except AttributeError:
                        pass
        return Audit(
            audit_type=self.audit_type,
            deadline=self.deadline,
            parameters=self.parameters,
            goal_id=self.goal,
            strategy_id=self.strategy,
            interval=self.interval,
            scope=self.scope,
        )
コード例 #21
0
ファイル: cinder_helper.py プロジェクト: sjamgade/watcher
    def migrate(self, volume, dest_node):
        """Migrate volume to dest_node"""
        volume = self.get_volume(volume)
        dest_backend = self.backendname_from_poolname(dest_node)
        dest_type = self.get_volume_type_by_backendname(dest_backend)
        if volume.volume_type not in dest_type:
            raise exception.Invalid(
                message=(_("Volume type must be same for migrating")))

        source_node = getattr(volume, 'os-vol-host-attr:host')
        LOG.debug("Volume %s found on host '%s'.", (volume.id, source_node))

        self.cinder.volumes.migrate_volume(volume, dest_node, False, True)

        return self.check_migrated(volume)
コード例 #22
0
    def _swap_volume(self, volume, dest_type):
        """Swap volume to dest_type

           Limitation note: only for compute libvirt driver
        """
        if not dest_type:
            raise exception.Invalid(
                message=(_("destination type is required when "
                           "migration type is swap")))

        if not self._can_swap(volume):
            raise exception.Invalid(
                message=(_("Invalid state for swapping volume")))

        user_info = {
            'name': self.temp_username,
            'password': self.temp_password
        }
        user = self._create_user(volume, user_info)
        keystone_util = keystone_helper.KeystoneHelper(osc=self.osc)
        try:
            session = keystone_util.create_session(user.id, self.temp_password)
            temp_cinder = self._get_cinder_client(session)

            # swap volume
            new_volume = self.cinder_util.create_volume(
                temp_cinder, volume, dest_type)
            self.nova_util.swap_volume(volume, new_volume)

            # delete old volume
            self.cinder_util.delete_volume(volume)

        finally:
            keystone_util.delete_user(user)

        return True
コード例 #23
0
 def migrate(self, destination):
     nova = nova_helper.NovaHelper(osc=self.osc)
     LOG.debug("Migrate instance %s to %s", self.instance_uuid, destination)
     instance = nova.find_instance(self.instance_uuid)
     if instance:
         if self.migration_type == 'live':
             return nova.live_migrate_instance(
                 instance_id=self.instance_uuid, dest_hostname=destination)
         else:
             raise exception.Invalid(
                 message=(_('Migration of type %(migration_type)s is not '
                            'supported.') % {
                                'migration_type': self.migration_type
                            }))
     else:
         raise exception.InstanceNotFound(name=self.instance_uuid)
コード例 #24
0
ファイル: migration.py プロジェクト: sanfern/watcher
 def migrate(self, destination):
     nova = nova_helper.NovaHelper(osc=self.osc)
     LOG.debug("Migrate instance %s to %s", self.instance_uuid, destination)
     instance = nova.find_instance(self.instance_uuid)
     if instance:
         if self.migration_type == self.LIVE_MIGRATION:
             return self._live_migrate_instance(nova, destination)
         elif self.migration_type == self.COLD_MIGRATION:
             return self._cold_migrate_instance(nova, destination)
         else:
             raise exception.Invalid(
                 message=(_("Migration of type '%(migration_type)s' is not "
                            "supported.") % {
                                'migration_type': self.migration_type
                            }))
     else:
         raise exception.InstanceNotFound(name=self.instance_uuid)
コード例 #25
0
    def _timestamps(self, start_time, end_time):
        def _format_timestamp(_time):
            if _time:
                if isinstance(_time, datetime.datetime):
                    return _time.isoformat()
                return _time
            return None

        start_timestamp = _format_timestamp(start_time)
        end_timestamp = _format_timestamp(end_time)

        if ((start_timestamp is not None) and (end_timestamp is not None)
                and (timeutils.parse_isotime(start_timestamp) >
                     timeutils.parse_isotime(end_timestamp))):
            raise exception.Invalid(
                _("Invalid query: %(start_time)s > %(end_time)s") %
                dict(start_time=start_timestamp, end_time=end_timestamp))
        return start_timestamp, end_timestamp
コード例 #26
0
    def build_query(self, user_id=None, tenant_id=None, resource_id=None,
                    user_ids=None, tenant_ids=None, resource_ids=None,
                    start_time=None, end_time=None):
        """Returns query built from given parameters.

        This query can be then used for querying resources, meters and
        statistics.
        :param user_id: user_id, has a priority over list of ids
        :param tenant_id: tenant_id, has a priority over list of ids
        :param resource_id: resource_id, has a priority over list of ids
        :param user_ids: list of user_ids
        :param tenant_ids: list of tenant_ids
        :param resource_ids: list of resource_ids
        :param start_time: datetime from which measurements should be collected
        :param end_time: datetime until which measurements should be collected
        """

        user_ids = user_ids or []
        tenant_ids = tenant_ids or []
        resource_ids = resource_ids or []

        query = []
        if user_id:
            user_ids = [user_id]
        for u_id in user_ids:
            query.append({"field": "user_id", "op": "eq", "value": u_id})

        if tenant_id:
            tenant_ids = [tenant_id]
        for t_id in tenant_ids:
            query.append({"field": "project_id", "op": "eq", "value": t_id})

        if resource_id:
            resource_ids = [resource_id]
        for r_id in resource_ids:
            query.append({"field": "resource_id", "op": "eq", "value": r_id})

        start_timestamp = None
        end_timestamp = None

        if start_time:
            start_timestamp = start_time
            if isinstance(start_time, datetime.datetime):
                start_timestamp = start_time.isoformat()

        if end_time:
            end_timestamp = end_time
            if isinstance(end_time, datetime.datetime):
                end_timestamp = end_time.isoformat()

        if (start_timestamp and end_timestamp and
                timeutils.parse_isotime(start_timestamp) >
                timeutils.parse_isotime(end_timestamp)):
            raise exception.Invalid(
                _("Invalid query: %(start_time)s > %(end_time)s") % dict(
                    start_time=start_timestamp, end_time=end_timestamp))

        if start_timestamp:
            query.append({"field": "timestamp", "op": "ge",
                          "value": start_timestamp})
        if end_timestamp:
            query.append({"field": "timestamp", "op": "le",
                          "value": end_timestamp})
        return query
コード例 #27
0
ファイル: types.py プロジェクト: akinsWin/watcher
 def validate(value):
     try:
         return strutils.bool_from_string(value, strict=True)
     except ValueError as e:
         # raise Invalid to return 400 (BadRequest) in the API
         raise exception.Invalid(e)
コード例 #28
0
    def as_audit(self, context):
        audit_type_values = [val.value for val in objects.audit.AuditType]
        if self.audit_type not in audit_type_values:
            raise exception.AuditTypeNotFound(audit_type=self.audit_type)

        if (self.audit_type == objects.audit.AuditType.ONESHOT.value
                and self.interval not in (wtypes.Unset, None)):
            raise exception.AuditIntervalNotAllowed(audit_type=self.audit_type)

        if (self.audit_type == objects.audit.AuditType.CONTINUOUS.value
                and self.interval in (wtypes.Unset, None)):
            raise exception.AuditIntervalNotSpecified(
                audit_type=self.audit_type)

        # If audit_template_uuid was provided, we will provide any
        # variables not included in the request, but not override
        # those variables that were included.
        if self.audit_template_uuid:
            try:
                audit_template = objects.AuditTemplate.get(
                    context, self.audit_template_uuid)
            except exception.AuditTemplateNotFound:
                raise exception.Invalid(
                    message=_('The audit template UUID or name specified is '
                              'invalid'))
            at2a = {
                'goal': 'goal_id',
                'strategy': 'strategy_id',
                'scope': 'scope',
            }
            to_string_fields = set(['goal', 'strategy'])
            for k in at2a:
                if not getattr(self, k):
                    try:
                        at_attr = getattr(audit_template, at2a[k])
                        if at_attr and (k in to_string_fields):
                            at_attr = str(at_attr)
                        setattr(self, k, at_attr)
                    except AttributeError:
                        pass

        # Note: If audit name was not provided, used a default name
        if not self.name:
            if self.strategy:
                strategy = objects.Strategy.get(context, self.strategy)
                self.name = "%s-%s" % (strategy.name,
                                       datetime.datetime.utcnow().isoformat())
            elif self.audit_template_uuid:
                audit_template = objects.AuditTemplate.get(
                    context, self.audit_template_uuid)
                self.name = "%s-%s" % (audit_template.name,
                                       datetime.datetime.utcnow().isoformat())
            else:
                goal = objects.Goal.get(context, self.goal)
                self.name = "%s-%s" % (goal.name,
                                       datetime.datetime.utcnow().isoformat())

        return Audit(name=self.name,
                     audit_type=self.audit_type,
                     parameters=self.parameters,
                     goal_id=self.goal,
                     strategy_id=self.strategy,
                     interval=self.interval,
                     scope=self.scope,
                     auto_trigger=self.auto_trigger)
コード例 #29
0
    def as_audit(self, context):
        audit_type_values = [val.value for val in objects.audit.AuditType]
        if self.audit_type not in audit_type_values:
            raise exception.AuditTypeNotFound(audit_type=self.audit_type)

        if (self.audit_type == objects.audit.AuditType.ONESHOT.value
                and self.interval not in (wtypes.Unset, None)):
            raise exception.AuditIntervalNotAllowed(audit_type=self.audit_type)

        if (self.audit_type == objects.audit.AuditType.CONTINUOUS.value
                and self.interval in (wtypes.Unset, None)):
            raise exception.AuditIntervalNotSpecified(
                audit_type=self.audit_type)

        if self.audit_template_uuid and self.goal:
            raise exception.Invalid('Either audit_template_uuid '
                                    'or goal should be provided.')

        if (self.audit_type == objects.audit.AuditType.ONESHOT.value
                and (self.start_time not in (wtypes.Unset, None)
                     or self.end_time not in (wtypes.Unset, None))):
            raise exception.AuditStartEndTimeNotAllowed(
                audit_type=self.audit_type)

        if not api_utils.allow_start_end_audit_time():
            for field in ('start_time', 'end_time'):
                if getattr(self, field) not in (wsme.Unset, None):
                    raise exception.NotAcceptable()

        # If audit_template_uuid was provided, we will provide any
        # variables not included in the request, but not override
        # those variables that were included.
        if self.audit_template_uuid:
            try:
                audit_template = objects.AuditTemplate.get(
                    context, self.audit_template_uuid)
            except exception.AuditTemplateNotFound:
                raise exception.Invalid(
                    message=_('The audit template UUID or name specified is '
                              'invalid'))
            at2a = {
                'goal': 'goal_id',
                'strategy': 'strategy_id',
                'scope': 'scope',
            }
            to_string_fields = set(['goal', 'strategy'])
            for k in at2a:
                if not getattr(self, k):
                    try:
                        at_attr = getattr(audit_template, at2a[k])
                        if at_attr and (k in to_string_fields):
                            at_attr = str(at_attr)
                        setattr(self, k, at_attr)
                    except AttributeError:
                        pass

        # Note: If audit name was not provided, used a default name
        if not self.name:
            if self.strategy:
                strategy = _get_object_by_value(context, objects.Strategy,
                                                self.strategy)
                self.name = "%s-%s" % (strategy.name,
                                       datetime.datetime.utcnow().isoformat())
            elif self.audit_template_uuid:
                audit_template = objects.AuditTemplate.get(
                    context, self.audit_template_uuid)
                self.name = "%s-%s" % (audit_template.name,
                                       datetime.datetime.utcnow().isoformat())
            else:
                goal = _get_object_by_value(context, objects.Goal, self.goal)
                self.name = "%s-%s" % (goal.name,
                                       datetime.datetime.utcnow().isoformat())
        # No more than 63 characters
        if len(self.name) > 63:
            LOG.warning("Audit: %s length exceeds 63 characters", self.name)
            self.name = self.name[0:63]

        return Audit(name=self.name,
                     audit_type=self.audit_type,
                     parameters=self.parameters,
                     goal_id=self.goal,
                     strategy_id=self.strategy,
                     interval=self.interval,
                     scope=self.scope,
                     auto_trigger=self.auto_trigger,
                     start_time=self.start_time,
                     end_time=self.end_time)