def execute_action(self, params, context=None, request=None): """Execute the action.""" body = json.loads(request.body) # e.g. name = 'nova:disconnectNetwork' items = re.split(':', body.get('name')) if len(items) != 2: (num, desc) = error_codes.get('service_action_syntax') raise webservice.DataModelException(num, desc) service = items[0].strip() action = items[1].strip() action_args = body.get('args', {}) if (not isinstance(action_args, dict)): (num, desc) = error_codes.get('execute_action_args_syntax') raise webservice.DataModelException(num, desc) try: args = {'service_name': service, 'action': action, 'action_args': action_args} # Note(thread-safety): blocking call self.invoke_rpc(base.ENGINE_SERVICE_ID, 'execute_action', args) except exception.PolicyException as e: (num, desc) = error_codes.get('execute_error') raise webservice.DataModelException(num, desc + "::" + str(e)) return {}
def execute_action(self, params, context=None, request=None): """Execute the action.""" body = json.loads(request.body) # e.g. name = 'nova:disconnectNetwork' items = re.split(':', body.get('name')) if len(items) != 2: (num, desc) = error_codes.get('service_action_syntax') raise webservice.DataModelException(num, desc) service = items[0].strip() action = items[1].strip() action_args = body.get('args', {}) if (not isinstance(action_args, dict)): (num, desc) = error_codes.get('execute_action_args_syntax') raise webservice.DataModelException(num, desc) try: args = {'service_name': service, 'action': action, 'action_args': action_args} # Note(thread-safety): blocking call self.invoke_rpc(base.ENGINE_SERVICE_ID, 'execute_action', args, timeout=self.action_retry_timeout) except exception.PolicyException as e: (num, desc) = error_codes.get('execute_error') raise webservice.DataModelException(num, desc + "::" + str(e)) return {}
def execute_action(self, params, context=None, request=None): "Execute the action." service = context.get('ds_id') body = json.loads(request.body) action = body.get('name') action_args = body.get('args', {}) if (not isinstance(action_args, dict)): (num, desc) = error_codes.get('execute_action_args_syntax') raise webservice.DataModelException(num, desc) try: args = { 'service_name': service, 'action': action, 'action_args': action_args } # TODO(ekcs): perhaps keep execution synchronous when explicitly # called via API # Note(thread-safety): blocking call self.invoke_rpc(base.ENGINE_SERVICE_ID, 'execute_action', args) except exception.PolicyException as e: (num, desc) = error_codes.get('execute_error') raise webservice.DataModelException(num, desc + "::" + str(e)) return {}
def add_item(self, item, params, id_=None, context=None): """Add item to model. Args: item: The item to add to the model params: A dict-like object containing parameters from the request query string and body. id_: The ID of the item, or None if an ID should be generated context: Key-values providing frame of reference of request Returns: Tuple of (ID, newly_created_item) Raises: KeyError: ID already exists. """ if id_ is not None: raise webservice.DataModelException( *error_codes.get('add_item_id')) str_rule = item['rule'] try: rule = self.engine.parse(str_rule) if len(rule) == 1: rule = rule[0] else: (num, desc) = error_codes.get('multiple_rules') raise webservice.DataModelException( num, desc + ":: Received multiple rules: " + "; ".join(str(x) for x in rule)) changes = self.change_rule(rule, context) except PolicyException as e: LOG.debug("add_item error: invalid rule syntax") (num, desc) = error_codes.get('rule_syntax') raise webservice.DataModelException(num, desc + "::" + str(e)) for change in changes: if change.formula == rule: d = {'rule': rule.pretty_str(), 'id': str(uuid.uuid4()), 'comment': None, 'name': item.get('name')} policy_name = self.policy_name(context) try: db_policy_rules.add_policy_rule( d['id'], policy_name, str_rule, d['comment'], rule_name=d['name']) return (d['id'], d) except Exception as db_exception: try: self.change_rule(rule, context, insert=False) except Exception as change_exception: raise Exception( "Error thrown during recovery from DB error. " "Inconsistent state. DB error: %s. " "New error: %s.", str(db_exception), str(change_exception)) num, desc = error_codes.get('rule_already_exists') raise webservice.DataModelException( num, desc, http_status_code=httplib.CONFLICT)
def simulate_action(self, params, context=None, request=None): """Simulate the effects of executing a sequence of updates. :returns: the result of a query. """ # grab string arguments theory = context.get('policy_id') or params.get('policy') if theory is None: (num, desc) = error_codes.get('simulate_without_policy') raise webservice.DataModelException(num, desc) body = json.loads(request.body) query = body.get('query') sequence = body.get('sequence') actions = body.get('action_policy') delta = self._get_boolean_param('delta', params) trace = self._get_boolean_param('trace', params) if query is None or sequence is None or actions is None: (num, desc) = error_codes.get('incomplete_simulate_args') raise webservice.DataModelException(num, desc) try: result = self.rpc( 'simulate', query, theory, sequence, actions, delta=delta, trace=trace, as_list=True) except exception.PolicyException as e: (num, desc) = error_codes.get('simulate_error') raise webservice.DataModelException(num, desc + "::" + str(e)) # always return dict if trace: return {'result': result[0], 'trace': result[1]} return {'result': result}
def simulate_action(self, params, context=None, request=None): """Simulate the effects of executing a sequence of updates and return the result of a query. """ # grab string arguments theory = context.get('policy_id') or params.get('policy') if theory is None: (num, desc) = error_codes.get('simulate_without_policy') raise webservice.DataModelException(num, desc) query = params.get('query') sequence = params.get('sequence') actions = params.get('action_policy') delta = self._get_boolean_param('delta', params) trace = self._get_boolean_param('trace', params) if query is None or sequence is None or actions is None: (num, desc) = error_codes.get('incomplete_simulate_args') raise webservice.DataModelException(num, desc) # parse arguments so that result of simulate is an object query = self._parse_rule(query) sequence = self._parse_rules(sequence) try: result = self.engine.simulate( query, theory, sequence, actions, delta, trace) except compile.CongressException as e: (num, desc) = error_codes.get('simulate_error') raise webservice.DataModelException(num, desc + "::" + str(e)) # always return dict if trace: return {'result': [str(x) for x in result[0]], 'trace': result[1]} return {'result': [str(x) for x in result]}
def add_item(self, item, params, id_=None, context=None): """Add item to model. Args: item: The item to add to the model params: A dict-like object containing parameters from the request query string and body. id_: The ID of the item, or None if an ID should be generated context: Key-values providing frame of reference of request Returns: Tuple of (ID, newly_created_item) Raises: KeyError: ID already exists. DataModelException: Addition cannot be performed. """ # validation if id_ is None: id_ = str(uuidutils.generate_uuid()) else: (num, desc) = error_codes.get('policy_id_must_not_be_provided') raise webservice.DataModelException(num, desc) if 'name' not in item: (num, desc) = error_codes.get('policy_name_must_be_provided') raise webservice.DataModelException(num, desc) name = item['name'] try: self.engine.parse("%s() :- true()" % name) except PolicyException: (num, desc) = error_codes.get('policy_name_must_be_id') raise webservice.DataModelException(num, desc + ": " + str(name)) # create policy in policy engine try: policy_obj = self.engine.create_policy( name, abbr=item.get('abbreviation'), kind=item.get('kind')) except PolicyException as e: (num, desc) = error_codes.get('failed_to_create_policy') raise webservice.DataModelException(num, desc + ": " + str(e)) # save policy to database desc = item.get('description', '') if desc is None: desc = '' obj = { 'id': id_, 'name': name, 'owner_id': 'user', 'description': desc, 'abbreviation': policy_obj.abbr, 'kind': self.engine.policy_type(name) } # TODO(thinrichs): add rollback of policy engine if this fails db_policy_rules.add_policy(obj['id'], obj['name'], obj['abbreviation'], obj['description'], obj['owner_id'], obj['kind']) return (id_, obj)
def add_item(self, item, params, id_=None, context=None): """Add item to model. Args: item: The item to add to the model params: A dict-like object containing parameters from the request query string and body. id_: The ID of the item, or None if an ID should be generated context: Key-values providing frame of reference of request Returns: Tuple of (ID, newly_created_item) Raises: KeyError: ID already exists. """ if id_ is not None: LOG.debug("add_item error: should not be given ID") raise webservice.DataModelException( *error_codes.get('add_item_id')) str_rule = item['rule'] try: rule = self.engine.parse(str_rule) if len(rule) == 1: rule = rule[0] else: LOG.debug("add_item error: given too many rules") (num, desc) = error_codes.get('multiple_rules') raise webservice.DataModelException( num, desc + ":: Received multiple rules: " + "; ".join(str(x) for x in rule)) changes = self.change_rule(rule, context) except compile.CongressException as e: LOG.debug("add_item error: invalid rule syntax") (num, desc) = error_codes.get('rule_syntax') raise webservice.DataModelException(num, desc + "::" + str(e)) for change in changes: if change.formula == rule: d = { 'rule': rule.pretty_str(), 'id': str(uuid.uuid4()), 'comment': None, 'name': item.get('name') } policy_name = self.policy_name(context) db_policy_rules.add_policy_rule(d['id'], policy_name, str_rule, d['comment'], rule_name=d['name']) return (d['id'], d) num, desc = error_codes.get('rule_already_exists') raise webservice.DataModelException(num, desc, http_status_code=httplib.CONFLICT)
def _check_create_policy_item(self, item): if 'name' not in item: (num, desc) = error_codes.get('policy_name_must_be_provided') raise webservice.DataModelException(num, desc) abbr = item.get('abbreviation') if abbr: # the length of abbreviation column is 5 chars in policy DB table, # check it in API layer and raise exception if it's too long. if not isinstance(abbr, six.string_types) or len(abbr) > 5: (num, desc) = error_codes.get('policy_abbreviation_error') raise webservice.DataModelException(num, desc)
def add_item(self, item, params, id_=None, context=None): """Add item to model. Args: item: The item to add to the model params: A dict-like object containing parameters from the request query string and body. id_: The ID of the item, or None if an ID should be generated context: Key-values providing frame of reference of request Returns: Tuple of (ID, newly_created_item) Raises: KeyError: ID already exists. """ # TODO(thinrichs): add comment property to rule if id_ is not None: raise webservice.DataModelException( **error_codes.get('add_item_id')) str_rule = item['rule'] try: rule = compile.parse(str_rule) if len(rule) == 1: rule = rule[0] else: (num, desc) = error_codes.get('add_item_multiple_rules') raise webservice.DataModelException( num, desc + ":: Received multiple rules: " + "; ".join(str(x) for x in rule)) changes = self.change_rule(rule, context) except compile.CongressException as e: (num, desc) = error_codes.get('rule_syntax') raise webservice.DataModelException(num, desc + "::" + str(e)) for change in changes: if change.formula == rule: d = {'rule': str(rule), 'id': rule.id, 'comment': None} return (rule.id, d) # rule already existed policy_name = self.policy_name(context) for p in self.engine.theory[policy_name].policy(): if p == rule: d = {'rule': str(rule), 'id': rule.id, 'comment': 'None'} return (rule.id, d) raise Exception("add_item added a rule but then could not find it.")
def add_item(self, item, params, id_=None, context=None): """Add item to model. Args: item: The item to add to the model params: A dict-like object containing parameters from the request query string and body. id_: The ID of the item, or None if an ID should be generated context: Key-values providing frame of reference of request Returns: Tuple of (ID, newly_created_item) Raises: KeyError: ID already exists. """ if id_ is not None: LOG.debug("add_item error: should not be given ID") raise webservice.DataModelException( *error_codes.get('add_item_id')) str_rule = item['rule'] try: rule = compile.parse(str_rule, self.engine.module_schemas) if len(rule) == 1: rule = rule[0] else: LOG.debug("add_item error: given too many rules") (num, desc) = error_codes.get('multiple_rules') raise webservice.DataModelException( num, desc + ":: Received multiple rules: " + "; ".join(str(x) for x in rule)) changes = self.change_rule(rule, context) except compile.CongressException as e: LOG.debug("add_item error: invalid rule syntax") (num, desc) = error_codes.get('rule_syntax') raise webservice.DataModelException(num, desc + "::" + str(e)) for change in changes: if change.formula == rule: d = {'rule': rule.pretty_str(), 'id': rule.id, 'comment': None} policy_name = self.policy_name(context) db_policy_rules.add_policy_rule(d['id'], policy_name, str_rule, d['comment']) return (rule.id, d) num, desc = error_codes.get('rule_already_exists') raise webservice.DataModelException( num, desc, http_status_code=httplib.CONFLICT)
def add_item(self, item, params, id_=None, context=None): """Add item to model. Args: item: The item to add to the model params: A dict-like object containing parameters from the request query string and body. id_: The ID of the item, or None if an ID should be generated context: Key-values providing frame of reference of request Returns: Tuple of (ID, newly_created_item) Raises: KeyError: ID already exists. """ if id_ is not None: raise webservice.DataModelException(*error_codes.get("add_item_id")) try: args = { "policy_name": self.policy_name(context), "str_rule": item.get("rule"), "rule_name": item.get("name"), "comment": item.get("comment"), } return self.invoke_rpc(self.engine, "persistent_insert_rule", args) except exception.CongressException as e: raise webservice.DataModelException.create(e)
def add_item(self, item, params, id_=None, context=None): """Add item to model. Args: item: The item to add to the model params: A dict-like object containing parameters from the request query string and body. id_: The ID of the item, or None if an ID should be generated context: Key-values providing frame of reference of request Returns: Tuple of (ID, newly_created_item) Raises: KeyError: ID already exists. DataModelException: Addition cannot be performed. """ self._check_create_policy(id_, item) name = item['name'] try: policy_metadata = self.rpc( 'persistent_create_policy', name, abbr=item.get('abbreviation'), kind=item.get('kind'), desc=item.get('description')) except exception.CongressException as e: (num, desc) = error_codes.get('failed_to_create_policy') raise webservice.DataModelException( num, desc + ": " + str(e)) return (policy_metadata['id'], policy_metadata)
def add_item(self, item, params, id_=None, context=None): """Add item to model. :param: item: The item to add to the model :param: params: A dict-like object containing parameters from the request query string and body. :param: id\_: The ID of the item, or None if an ID should be generated :param: context: Key-values providing frame of reference of request :returns: Tuple of (ID, newly_created_item) :raises KeyError: ID already exists. """ if id_ is not None: raise webservice.DataModelException( *error_codes.get('add_item_id')) try: args = { 'policy_name': self.policy_name(context), 'str_rule': item.get('rule'), 'rule_name': item.get('name'), 'comment': item.get('comment') } # Note(thread-safety): blocking call return self.invoke_rpc(base.ENGINE_SERVICE_ID, 'persistent_insert_rule', args, timeout=self.dse_long_timeout) except exception.CongressException as e: raise webservice.DataModelException.create(e)
def add_item(self, item, params, id_=None, context=None): """Add item to model. :param: item: The item to add to the model :param: params: A dict-like object containing parameters from the request query string and body. :param: id\_: The unique name of the item :param: context: Key-values providing frame of reference of request :returns: Tuple of (ID, newly_created_item) :raises KeyError: ID already exists. :raises DataModelException: Addition cannot be performed. """ if id_ is not None: (num, desc) = error_codes.get('policy_id_must_not_be_provided') raise webservice.DataModelException(num, desc) try: # Note(thread-safety): blocking call policy_metadata = self.invoke_rpc( base.LIBRARY_SERVICE_ID, 'create_policy', {'policy_dict': item}) except exception.CongressException as e: raise webservice.DataModelException.create(e) return (policy_metadata['id'], policy_metadata)
def add_item(self, item, params, id_=None, context=None): """Add item to model. :param: item: The item to add to the model :param: params: A dict-like object containing parameters from the request query string and body. :param: id\_: The ID of the item, or None if an ID should be generated :param: context: Key-values providing frame of reference of request :returns: Tuple of (ID, newly_created_item) :raises KeyError: ID already exists. """ if id_ is not None: raise webservice.DataModelException( *error_codes.get('add_item_id')) try: args = {'policy_name': self.policy_name(context), 'str_rule': item.get('rule'), 'rule_name': item.get('name'), 'comment': item.get('comment')} # Note(thread-safety): blocking call return self.invoke_rpc(base.ENGINE_SERVICE_ID, 'persistent_insert_rule', args, timeout=self.dse_long_timeout) except exception.CongressException as e: raise webservice.DataModelException.create(e)
def add_item(self, item, params, id_=None, context=None): """Add item to model. Args: item: The item to add to the model params: A dict-like object containing parameters from the request query string and body. id_: The unique name of the item context: Key-values providing frame of reference of request Returns: Tuple of (ID, newly_created_item) Raises: KeyError: ID already exists. DataModelException: Addition cannot be performed. """ if id_ is not None: (num, desc) = error_codes.get('policy_id_must_not_be_provided') raise webservice.DataModelException(num, desc) try: # Note(thread-safety): blocking call policy_metadata = self.invoke_rpc(base.LIBRARY_SERVICE_ID, 'create_policy', {'policy_dict': item}) except exception.CongressException as e: raise webservice.DataModelException.create(e) return (policy_metadata['id'], policy_metadata)
def execute_action(self, params, context=None, request=None): "Execute the action." service = context.get('ds_id') body = json.loads(request.body) action = body.get('name') action_args = body.get('args', {}) if (not isinstance(action_args, dict)): (num, desc) = error_codes.get('execute_action_args_syntax') raise webservice.DataModelException(num, desc) try: self.engine.execute_action(service, action, action_args) except exception.PolicyException as e: (num, desc) = error_codes.get('execute_error') raise webservice.DataModelException(num, desc + "::" + str(e)) return {}
def execute_action(self, params, context=None, request=None): "Execute the action." service = context.get("ds_id") body = json.loads(request.body) action = body.get("name") action_args = body.get("args", {}) if not isinstance(action_args, dict): (num, desc) = error_codes.get("execute_action_args_syntax") raise webservice.DataModelException(num, desc) try: args = {"service_name": service, "action": action, "action_args": action_args} self.invoke_rpc(self.engine, "execute_action", args) except exception.PolicyException as e: (num, desc) = error_codes.get("execute_error") raise webservice.DataModelException(num, desc + "::" + str(e)) return {}
def simulate_action(self, params, context=None, request=None): """Simulate the effects of executing a sequence of updates. :returns: the result of a query. """ # grab string arguments theory = context.get('policy_id') or params.get('policy') if theory is None: (num, desc) = error_codes.get('simulate_without_policy') raise webservice.DataModelException(num, desc) body = json.loads(request.body) query = body.get('query') sequence = body.get('sequence') actions = body.get('action_policy') delta = self._get_boolean_param('delta', params) trace = self._get_boolean_param('trace', params) if query is None or sequence is None or actions is None: (num, desc) = error_codes.get('incomplete_simulate_args') raise webservice.DataModelException(num, desc) try: args = { 'query': query, 'theory': theory, 'sequence': sequence, 'action_theory': actions, 'delta': delta, 'trace': trace, 'as_list': True } # Note(thread-safety): blocking call result = self.invoke_rpc(base.ENGINE_SERVICE_ID, 'simulate', args, timeout=self.dse_long_timeout) except exception.PolicyException as e: (num, desc) = error_codes.get('simulate_error') raise webservice.DataModelException(num, desc + "::" + str(e)) # always return dict if trace: return {'result': result[0], 'trace': result[1]} return {'result': result}
def _parse_rules(self, string, errmsg=''): if errmsg: errmsg = errmsg + ":: " # basic parsing try: return self.engine.parse(string) except PolicyException as e: (num, desc) = error_codes.get('rule_syntax') raise webservice.DataModelException(num, desc + ":: " + errmsg + str(e))
def _parse_rule(self, string, errmsg=''): rules = self._parse_rules(string, errmsg) if len(rules) == 1: return rules[0] if errmsg: errmsg = errmsg + ":: " (num, desc) = error_codes.get('multiple_rules') raise webservice.DataModelException( num, desc + ":: " + errmsg + string + " parses to " + "; ".join(str(x) for x in rules))
def _parse_rules(self, string, errmsg=''): if errmsg: errmsg = errmsg + ":: " # basic parsing try: return self.engine.parse(string) except PolicyException as e: (num, desc) = error_codes.get('rule_syntax') raise webservice.DataModelException( num, desc + ":: " + errmsg + str(e))
def execute_action(self, params, context=None, request=None): """Execute the action.""" body = json.loads(request.body) # e.g. name = 'nova:disconnectNetwork' items = re.split(':', body.get('name')) if len(items) != 2: (num, desc) = error_codes.get('service_action_syntax') raise webservice.DataModelException(num, desc) service = items[0].strip() action = items[1].strip() action_args = body.get('args') if (not isinstance(action_args, dict)): (num, desc) = error_codes.get('execute_action_args_syntax') raise webservice.DataModelException(num, desc) try: self.engine.execute_action(service, action, action_args) except PolicyException as e: (num, desc) = error_codes.get('execute_error') raise webservice.DataModelException(num, desc + "::" + str(e)) return {}
def execute_action(self, params, context=None, request=None): "Execute the action." service = context.get('ds_id') body = json.loads(request.body) action = body.get('name') action_args = body.get('args', {}) if (not isinstance(action_args, dict)): (num, desc) = error_codes.get('execute_action_args_syntax') raise webservice.DataModelException(num, desc) try: args = {'service_name': service, 'action': action, 'action_args': action_args} # TODO(ekcs): perhaps keep execution synchronous when explicitly # called via API # Note(thread-safety): blocking call self.invoke_rpc(base.ENGINE_SERVICE_ID, 'execute_action', args) except exception.PolicyException as e: (num, desc) = error_codes.get('execute_error') raise webservice.DataModelException(num, desc + "::" + str(e)) return {}
def execute_action(self, params, context=None, request=None): """Execute the action.""" body = json.loads(request.body) # e.g. name = 'nova:disconnectNetwork' items = re.split(':', body.get('name')) if len(items) != 2: (num, desc) = error_codes.get('service_action_syntax') raise webservice.DataModelException(num, desc) service = items[0].strip() action = items[1].strip() action_args = body.get('args', {}) if (not isinstance(action_args, dict)): (num, desc) = error_codes.get('execute_action_args_syntax') raise webservice.DataModelException(num, desc) try: self.engine.execute_action(service, action, action_args) except PolicyException as e: (num, desc) = error_codes.get('execute_error') raise webservice.DataModelException(num, desc + "::" + str(e)) return {}
def simulate_action(self, params, context=None, request=None): """Simulate the effects of executing a sequence of updates. :returns: the result of a query. """ # grab string arguments theory = context.get('policy_id') or params.get('policy') if theory is None: (num, desc) = error_codes.get('simulate_without_policy') raise webservice.DataModelException(num, desc) body = json.loads(request.body) query = body.get('query') sequence = body.get('sequence') actions = body.get('action_policy') delta = self._get_boolean_param('delta', params) trace = self._get_boolean_param('trace', params) if query is None or sequence is None or actions is None: (num, desc) = error_codes.get('incomplete_simulate_args') raise webservice.DataModelException(num, desc) try: args = {'query': query, 'theory': theory, 'sequence': sequence, 'action_theory': actions, 'delta': delta, 'trace': trace, 'as_list': True} # Note(thread-safety): blocking call result = self.invoke_rpc(base.ENGINE_SERVICE_ID, 'simulate', args, timeout=self.dse_long_timeout) except exception.PolicyException as e: (num, desc) = error_codes.get('simulate_error') raise webservice.DataModelException(num, desc + "::" + str(e)) # always return dict if trace: return {'result': result[0], 'trace': result[1]} return {'result': result}
def add_item(self, item, params, id_=None, context=None): """Add item to model. Args: item: The item to add to the model params: A dict-like object containing parameters from the request query string and body. id_: The ID of the item, or None if an ID should be generated context: Key-values providing frame of reference of request Returns: Tuple of (ID, newly_created_item) Raises: KeyError: ID already exists. DataModelException: Addition cannot be performed. """ if id_ is not None: (num, desc) = error_codes.get("policy_id_must_not_be_provided") raise webservice.DataModelException(num, desc) if "name" not in item: (num, desc) = error_codes.get("policy_name_must_be_provided") raise webservice.DataModelException(num, desc) name = item["name"] try: policy_metadata = self.rpc( "persistent_create_policy", name, abbr=item.get("abbreviation"), kind=item.get("kind"), desc=item.get("description"), ) except exception.CongressException as e: (num, desc) = error_codes.get("failed_to_create_policy") raise webservice.DataModelException(num, desc + ": " + str(e)) return (policy_metadata["id"], policy_metadata)
def test_get_unknown__error_code(self): name = 'unknown' error_codes.errors = { "fake-error": ( 0000, 'This is a fake error code.' ) } expected_ret = ( 1000, 'Unknown error' ) ret = error_codes.get(name) self.assertEqual(expected_ret, ret)
def simulate_action(self, params, context=None, request=None): """Simulate the effects of executing a sequence of updates. :returns: the result of a query. """ # grab string arguments theory = context.get('policy_id') or params.get('policy') if theory is None: (num, desc) = error_codes.get('simulate_without_policy') raise webservice.DataModelException(num, desc) body = json.loads(request.body) query = body.get('query') sequence = body.get('sequence') actions = body.get('action_policy') delta = self._get_boolean_param('delta', params) trace = self._get_boolean_param('trace', params) if query is None or sequence is None or actions is None: (num, desc) = error_codes.get('incomplete_simulate_args') raise webservice.DataModelException(num, desc) # parse arguments so that result of simulate is an object query = self._parse_rule(query) sequence = self._parse_rules(sequence) try: result = self.engine.simulate(query, theory, sequence, actions, delta, trace) except PolicyException as e: (num, desc) = error_codes.get('simulate_error') raise webservice.DataModelException(num, desc + "::" + str(e)) # always return dict if trace: return {'result': [str(x) for x in result[0]], 'trace': result[1]} return {'result': [str(x) for x in result]}
def test_get_error_code(self): name = 'fake-error' error_codes.errors = { "fake-error": (0000, 'This is a fake error code.', 400) } expected_num = 0000 expected_desc = 'This is a fake error code.' expected_http = 400 expected_ret = (expected_num, expected_desc) ret = error_codes.get(name) self.assertEqual(expected_ret, ret) num = error_codes.get_num(name) self.assertEqual(expected_num, num) desc = error_codes.get_desc(name) self.assertEqual(expected_desc, desc) http = error_codes.get_http(name) self.assertEqual(expected_http, http)
def test_get_unknown__error_code(self): name = 'fake_error_code' error_codes.errors = { error_codes.UNKNOWN: (0000, 'Unknown error', 400), 'fake-error': (1000, 'Fake error', 404) } expected_num = 0000 expected_desc = 'Unknown error' expected_http = 400 expected_ret = (expected_num, expected_desc) ret = error_codes.get(name) self.assertEqual(expected_ret, ret) num = error_codes.get_num(name) self.assertEqual(expected_num, num) desc = error_codes.get_desc(name) self.assertEqual(expected_desc, desc) http = error_codes.get_http(name) self.assertEqual(expected_http, http)
def add_item(self, item, params, id_=None, context=None): """Add item to model. Args: item: The item to add to the model params: A dict-like object containing parameters from the request query string and body. id_: The ID of the item, or None if an ID should be generated context: Key-values providing frame of reference of request Returns: Tuple of (ID, newly_created_item) Raises: KeyError: ID already exists. """ if id_ is not None: raise webservice.DataModelException( *error_codes.get('add_item_id')) # Reject rules inserted into non-persisted policies # (i.e. datasource policies) policy_name = self.policy_name(context) policies = db_policy_rules.get_policies() persisted_policies = set([p.name for p in policies]) if policy_name not in persisted_policies: if policy_name in self.engine.theory: LOG.debug("add_item error: rule not permitted for policy %s", policy_name) raise webservice.DataModelException( *error_codes.get('rule_not_permitted'), http_status_code=httplib.FORBIDDEN) else: LOG.debug("add_item error: policy %s not exist", policy_name) raise webservice.DataModelException( *error_codes.get('policy_not_exist'), http_status_code=httplib.NOT_FOUND) str_rule = item['rule'] id = uuid.uuid4() try: rule = self.engine.parse(str_rule) if len(rule) == 1: rule = rule[0] else: (num, desc) = error_codes.get('multiple_rules') raise webservice.DataModelException( num, desc + ":: Received multiple rules: " + "; ".join(str(x) for x in rule)) rule.set_id(id) rule.set_name(item.get('name')) rule.set_comment(None) rule.set_original_str(str_rule) changes = self.change_rule(rule, context) except exception.PolicyException as e: LOG.debug("add_item error: invalid rule syntax") (num, desc) = error_codes.get('rule_syntax') raise webservice.DataModelException(num, desc + "::" + str(e)) for change in changes: if change.formula == rule: d = {'rule': rule.pretty_str(), 'id': str(id), 'comment': rule.comment, 'name': item.get('name')} try: db_policy_rules.add_policy_rule( d['id'], policy_name, str_rule, d['comment'], rule_name=d['name']) return (d['id'], d) except Exception as db_exception: try: self.change_rule(rule, context, insert=False) except Exception as change_exception: raise Exception( "Error thrown during recovery from DB error. " "Inconsistent state. DB error: %s. " "New error: %s.", str(db_exception), str(change_exception)) num, desc = error_codes.get('rule_already_exists') raise webservice.DataModelException( num, desc, http_status_code=httplib.CONFLICT)
def add_item(self, item, params, id_=None, context=None): """Add item to model. Args: item: The item to add to the model params: A dict-like object containing parameters from the request query string and body. id_: The ID of the item, or None if an ID should be generated context: Key-values providing frame of reference of request Returns: Tuple of (ID, newly_created_item) Raises: KeyError: ID already exists. DataModelException: Addition cannot be performed. """ # validation if id_ is None: id_ = str(uuidutils.generate_uuid()) else: (num, desc) = error_codes.get('policy_id_must_not_be_provided') raise webservice.DataModelException(num, desc) if 'name' not in item: (num, desc) = error_codes.get('policy_name_must_be_provided') raise webservice.DataModelException(num, desc) name = item['name'] try: self.engine.parse("%s() :- true()" % name) except PolicyException: (num, desc) = error_codes.get('policy_name_must_be_id') raise webservice.DataModelException( num, desc + ": " + str(name)) # create policy in policy engine try: policy_obj = self.engine.create_policy( name, abbr=item.get('abbreviation'), kind=item.get('kind')) policy_obj.set_id(id_) except PolicyException as e: (num, desc) = error_codes.get('failed_to_create_policy') raise webservice.DataModelException( num, desc + ": " + str(e)) # save policy to database desc = item.get('description', '') if desc is None: desc = '' obj = {'id': id_, 'name': name, 'owner_id': 'user', 'description': desc, 'abbreviation': policy_obj.abbr, 'kind': self.engine.policy_type(name)} # TODO(thinrichs): add rollback of policy engine if this fails db_policy_rules.add_policy(obj['id'], obj['name'], obj['abbreviation'], obj['description'], obj['owner_id'], obj['kind']) return (id_, obj)
def add_item(self, item, params, id_=None, context=None): """Add item to model. :param: item: The item to add to the model :param: params: A dict-like object containing parameters from the request query string and body. :param: id\_: The ID of the item, or None if an ID should be generated :param: context: Key-values providing frame of reference of request :returns: Tuple of (ID, newly_created_item) :raises KeyError: ID already exists. :raises DataModelException: Addition cannot be performed. :raises BadRequest: library_policy parameter and request body both present """ if id_ is not None: (num, desc) = error_codes.get('policy_id_must_not_be_provided') raise webservice.DataModelException(num, desc) # case 1: parameter gives library policy UUID if 'library_policy' in params: if item: raise exception.BadRequest( 'Policy creation request with `library_policy` parameter ' 'must not have non-empty body.') try: # Note(thread-safety): blocking call library_policy_object = self.invoke_rpc( base.LIBRARY_SERVICE_ID, 'get_policy', {'id_': params['library_policy']}) policy_metadata = self.invoke_rpc( base.ENGINE_SERVICE_ID, 'persistent_create_policy_with_rules', {'policy_rules_obj': library_policy_object}, timeout=self.dse_long_timeout) except exception.CongressException as e: raise webservice.DataModelException.create(e) return (policy_metadata['id'], policy_metadata) # case 2: item contains rules if 'rules' in item: self._check_create_policy_item(item) try: library_service.validate_policy_item(item) # Note(thread-safety): blocking call policy_metadata = self.invoke_rpc( base.ENGINE_SERVICE_ID, 'persistent_create_policy_with_rules', {'policy_rules_obj': item}, timeout=self.dse_long_timeout) except exception.CongressException as e: raise webservice.DataModelException.create(e) return (policy_metadata['id'], policy_metadata) # case 3: item does not contain rules self._check_create_policy_item(item) name = item['name'] try: # Note(thread-safety): blocking call policy_metadata = self.invoke_rpc( base.ENGINE_SERVICE_ID, 'persistent_create_policy', {'name': name, 'abbr': item.get('abbreviation'), 'kind': item.get('kind'), 'desc': item.get('description')}) except exception.CongressException as e: raise webservice.DataModelException.create(e) return (policy_metadata['id'], policy_metadata)
def add_item(self, item, params, id_=None, context=None): """Add item to model. :param: item: The item to add to the model :param: params: A dict-like object containing parameters from the request query string and body. :param: id\_: The ID of the item, or None if an ID should be generated :param: context: Key-values providing frame of reference of request :returns: Tuple of (ID, newly_created_item) :raises KeyError: ID already exists. :raises DataModelException: Addition cannot be performed. :raises BadRequest: library_policy parameter and request body both present """ if id_ is not None: (num, desc) = error_codes.get('policy_id_must_not_be_provided') raise webservice.DataModelException(num, desc) # case 1: parameter gives library policy UUID if 'library_policy' in params: if item: raise exception.BadRequest( 'Policy creation request with `library_policy` parameter ' 'must not have non-empty body.') try: # Note(thread-safety): blocking call library_policy_object = self.invoke_rpc( base.LIBRARY_SERVICE_ID, 'get_policy', {'id_': params['library_policy']}) policy_metadata = self.invoke_rpc( base.ENGINE_SERVICE_ID, 'persistent_create_policy_with_rules', {'policy_rules_obj': library_policy_object}, timeout=self.dse_long_timeout) except exception.CongressException as e: raise webservice.DataModelException.create(e) return (policy_metadata['id'], policy_metadata) # case 2: item contains rules if 'rules' in item: self._check_create_policy_item(item) try: library_service.validate_policy_item(item) # Note(thread-safety): blocking call policy_metadata = self.invoke_rpc( base.ENGINE_SERVICE_ID, 'persistent_create_policy_with_rules', {'policy_rules_obj': item}, timeout=self.dse_long_timeout) except exception.CongressException as e: raise webservice.DataModelException.create(e) return (policy_metadata['id'], policy_metadata) # case 3: item does not contain rules self._check_create_policy_item(item) name = item['name'] try: # Note(thread-safety): blocking call policy_metadata = self.invoke_rpc( base.ENGINE_SERVICE_ID, 'persistent_create_policy', { 'name': name, 'abbr': item.get('abbreviation'), 'kind': item.get('kind'), 'desc': item.get('description') }) except exception.CongressException as e: raise webservice.DataModelException.create(e) return (policy_metadata['id'], policy_metadata)