class Token(Access): impl = MongoDBAccess(TokenDB) @classmethod def _get_impl(cls): return cls.impl @classmethod def add_or_update(cls, model_object, publish=True, validate=True): if not getattr(model_object, 'user', None): raise ValueError('User is not provided in the token.') if not getattr(model_object, 'token', None): raise ValueError('Token value is not set.') if not getattr(model_object, 'expiry', None): raise ValueError('Token expiry is not provided in the token.') return super(Token, cls).add_or_update(model_object, publish=publish, validate=validate) @classmethod def get(cls, value): result = cls.query(token=value).first() if not result: raise TokenNotFoundError() return result
class ApiKey(Access): impl = MongoDBAccess(ApiKeyDB) @classmethod def _get_impl(cls): return cls.impl @classmethod def get(cls, value): # DB does not contain key but the key_hash. value_hash = hash_utils.hash(value) for model_object in ApiKeyDB.objects(key_hash=value_hash): return model_object raise ApiKeyNotFoundError('ApiKey with key_hash=%s not found.' % value_hash) @classmethod def get_by_key_or_id(cls, value): try: return cls.get(value) except ApiKeyNotFoundError: pass try: return cls.get_by_id(value) except: raise ApiKeyNotFoundError('ApiKey with key or id=%s not found.' % value)
class User(Access): impl = MongoDBAccess(UserDB) @classmethod def get(cls, username): return cls.get_by_name(username) @classmethod def get_by_nickname(cls, nickname, origin): if not origin: raise NoNicknameOriginProvidedError() result = cls.query(**{('nicknames__%s' % origin): nickname}) if not result.first(): raise UserNotFoundError() if result.count() > 1: raise AmbiguousUserError() return result.first() @classmethod def _get_impl(cls): return cls.impl @classmethod def _get_by_object(cls, object): # For User name is unique. name = getattr(object, 'name', '') return cls.get_by_name(name)
class DumperMarker(Access): impl = MongoDBAccess(DumperMarkerDB) publisher = None @classmethod def _get_impl(cls): return cls.impl
class PolicyType(Access): impl = MongoDBAccess(PolicyTypeDB) @classmethod def _get_impl(cls): return cls.impl @classmethod def get_by_ref(cls, ref): if ref: ref_obj = PolicyTypeReference.from_string_reference(ref=ref) result = cls.query( name=ref_obj.name, resource_type=ref_obj.resource_type ).first() return result else: return None @classmethod def _get_by_object(cls, object): name = getattr(object, "name", "") resource_type = getattr(object, "resource_type", "") ref = PolicyTypeReference.to_string_reference( resource_type=resource_type, name=name ) return cls.get_by_ref(ref)
class ApiKey(Access): impl = MongoDBAccess(ApiKeyDB) @classmethod def _get_impl(cls): return cls.impl @classmethod def get(cls, value): # DB does not contain key but the key_hash. value_hash = hash_utils.hash(value) result = cls.query(key_hash=value_hash).first() if not result: raise ApiKeyNotFoundError('ApiKey with key_hash=%s not found.' % value_hash) return result @classmethod def get_by_key_or_id(cls, value): try: return cls.get(value) except ApiKeyNotFoundError: pass try: return cls.get_by_id(value) except: raise ApiKeyNotFoundError('ApiKey with key or id=%s not found.' % value)
class User(Access): impl = MongoDBAccess(UserDB) @classmethod def _get_impl(cls): return cls.impl @classmethod def _get_by_object(cls, object): # For User name is unique. name = getattr(object, 'name', '') return cls.get_by_name(name)
class ActionExecution(Access): impl = MongoDBAccess(ActionExecutionDB) publisher = None @classmethod def _get_impl(cls): return cls.impl @classmethod def _get_publisher(cls): if not cls.publisher: cls.publisher = transport.execution.ActionExecutionPublisher( urls=transport_utils.get_messaging_urls()) return cls.publisher
class ActionExecution(Access): impl = MongoDBAccess(ActionExecutionDB) publisher = None @classmethod def _get_impl(cls): return cls.impl @classmethod def _get_publisher(cls): if not cls.publisher: cls.publisher = transport.execution.ActionExecutionPublisher( cfg.CONF.messaging.url) return cls.publisher
class ActionExecutionOutput(Access): impl = MongoDBAccess(ActionExecutionOutputDB) @classmethod def _get_impl(cls): return cls.impl @classmethod def _get_publisher(cls): if not cls.publisher: cls.publisher = transport.execution.ActionExecutionOutputPublisher() return cls.publisher @classmethod def delete_by_query(cls, *args, **query): return cls._get_impl().delete_by_query(*args, **query)
class Token(Access): impl = MongoDBAccess(TokenDB) @classmethod def _get_impl(kls): return kls.impl @classmethod def add_or_update(kls, model_object, publish=True): if not getattr(model_object, 'user', None): raise ValueError('User is not provided in the token.') if not getattr(model_object, 'token', None): raise ValueError('Token value is not set.') if not getattr(model_object, 'expiry', None): raise ValueError('Token expiry is not provided in the token.') return super(Token, kls).add_or_update(model_object, publish=publish) @classmethod def get(kls, value): for model_object in TokenDB.objects(token=value): return model_object raise TokenNotFoundError()
artifact_uri - URI to the artifact file. entry_point - Full path to the sensor entry point (e.g. module.foo.ClassSensor). trigger_type - A list of references to the TriggerTypeDB objects exposed by this sensor. poll_interval - Poll interval for this sensor. """ RESOURCE_TYPE = ResourceType.SENSOR_TYPE UID_FIELDS = ['pack', 'name'] name = me.StringField(required=True) pack = me.StringField(required=True, unique_with='name') artifact_uri = me.StringField() entry_point = me.StringField() trigger_types = me.ListField(field=me.StringField()) poll_interval = me.IntField() enabled = me.BooleanField( default=True, help_text=u'Flag indicating whether the sensor is enabled.') meta = {'indexes': stormbase.UIDFieldMixin.get_indexes()} def __init__(self, *args, **values): super(SensorTypeDB, self).__init__(*args, **values) self.ref = self.get_reference().ref self.uid = self.get_uid() sensor_type_access = MongoDBAccess(SensorTypeDB) MODELS = [SensorTypeDB]
""" RESOURCE_TYPE = ResourceType.KEY_VALUE_PAIR UID_FIELDS = ['scope', 'name'] scope = me.StringField(default=FULL_SYSTEM_SCOPE, unique_with='name') name = me.StringField(required=True) value = me.StringField() secret = me.BooleanField(default=False) expire_timestamp = me.DateTimeField() meta = { 'indexes': [ {'fields': ['name']}, { 'fields': ['expire_timestamp'], 'expireAfterSeconds': 0 } ] + stormbase.UIDFieldMixin.get_indexes() } def __init__(self, *args, **values): super(KeyValuePairDB, self).__init__(*args, **values) self.uid = self.get_uid() # specialized access objects keyvaluepair_access = MongoDBAccess(KeyValuePairDB) MODELS = [KeyValuePairDB]
"""Specifies the action to invoke on the occurrence of a Trigger. It also includes the transformation to perform to match the impedance between the payload of a TriggerInstance and input of a action. Attribute: trigger: Trigger that trips this rule. criteria: action: Action to execute when the rule is tripped. status: enabled or disabled. If disabled occurrence of the trigger does not lead to execution of a action and vice-versa. """ name = me.StringField(required=True) ref = me.StringField(required=True) description = me.StringField() pack = me.StringField(required=False, help_text='Name of the content pack.', unique_with='name') trigger = me.StringField() criteria = stormbase.EscapedDictField() action = me.EmbeddedDocumentField(ActionExecutionSpecDB) enabled = me.BooleanField( required=True, default=True, help_text=u'Flag indicating whether the rule is enabled.') meta = {'indexes': stormbase.TagsMixin.get_indices()} rule_access = MongoDBAccess(RuleDB) MODELS = [RuleDB]
class RuleEnforcementDB(stormbase.StormFoundationDB, stormbase.TagsMixin): UID_FIELDS = ['id'] trigger_instance_id = me.StringField(required=True) execution_id = me.StringField(required=False) failure_reason = me.StringField(required=False) rule = me.EmbeddedDocumentField(RuleReferenceSpecDB, required=True) enforced_at = ComplexDateTimeField( default=date_utils.get_datetime_utc_now, help_text='The timestamp when the rule enforcement happened.') meta = { 'indexes': [ {'fields': ['rule.ref']}, ] } # XXX: Note the following method is exposed so loggers in rbac resolvers can log objects # with a consistent get_uid interface. def get_uid(self): # TODO Construct uid from non id field: uid = [self.RESOURCE_TYPE, str(self.id)] return ':'.join(uid) rule_enforcement_access = MongoDBAccess(RuleEnforcementDB) MODELS = [RuleEnforcementDB]
meta = { 'indexes': [ { 'fields': ['enabled'] }, { 'fields': ['action.ref'] }, { 'fields': ['trigger'] }, { 'fields': ['context.user'] }, ] + (stormbase.ContentPackResourceMixin.get_indexes() + stormbase.TagsMixin.get_indexes() + stormbase.UIDFieldMixin.get_indexes()) } def __init__(self, *args, **values): super(RuleDB, self).__init__(*args, **values) self.ref = self.get_reference().ref self.uid = self.get_uid() rule_access = MongoDBAccess(RuleDB) rule_type_access = MongoDBAccess(RuleTypeDB) MODELS = [RuleDB]
default=True, help_text= 'A flag indicating whether the runner for this type is enabled.') runner_package = me.StringField( required=False, help_text= ('The python package that implements the action runner for this type. If' 'not provided it assumes package name equals module name.')) runner_module = me.StringField( required=True, help_text= 'The python module that implements the action runner for this type.') runner_parameters = me.DictField( help_text='The specification for parameters for the action runner.') query_module = me.StringField( required=False, help_text= 'The python module that implements the query module for this runner.') meta = {'indexes': stormbase.UIDFieldMixin.get_indexes()} def __init__(self, *args, **values): super(RunnerTypeDB, self).__init__(*args, **values) self.uid = self.get_uid() # specialized access objects runnertype_access = MongoDBAccess(RunnerTypeDB) MODELS = [RunnerTypeDB]
# TODO: This results into two DB looks, we should cache action and runner type object # for each liveaction... # # ,-'"-. # . f .--. \ # .\._,\._',' j_ # 7______""-'__`, parameters = action_db.get_action_parameters_specs( action_ref=self.action) secret_parameters = get_secret_parameters(parameters=parameters) result['parameters'] = mask_secret_parameters( parameters=execution_parameters, secret_parameters=secret_parameters) return result def get_masked_parameters(self): """ Retrieve parameters with the secrets masked. :rtype: ``dict`` """ serializable_dict = self.to_serializable_dict(mask_secrets=True) return serializable_dict['parameters'] # specialized access objects liveaction_access = MongoDBAccess(LiveActionDB) MODELS = [LiveActionDB]
pack = me.StringField(required=False, help_text='Name of the content pack.', unique_with='name') trigger = me.StringField() criteria = stormbase.EscapedDictField() action = me.EmbeddedDocumentField(ActionExecutionSpecDB) enabled = me.BooleanField( required=True, default=True, help_text=u'Flag indicating whether the rule is enabled.') meta = {'indexes': stormbase.TagsMixin.get_indices()} # specialized access objects rule_access_with_pack = MongoDBAccess(Migration.RuleDB) class RuleDB(stormbase.StormBaseDB, stormbase.TagsMixin): """Specifies the action to invoke on the occurrence of a Trigger. It also includes the transformation to perform to match the impedance between the payload of a TriggerInstance and input of a action. Attribute: trigger: Trigger that trips this rule. criteria: action: Action to execute when the rule is tripped. status: enabled or disabled. If disabled occurrence of the trigger does not lead to execution of a action and vice-versa. """ trigger = me.StringField() criteria = stormbase.EscapedDictField()
__all__ = [ 'ActionExecutionStateDB', ] LOG = logging.getLogger(__name__) PACK_SEPARATOR = '.' class ActionExecutionStateDB(stormbase.StormFoundationDB): """ Database entity that represents the state of Action execution. """ execution_id = me.ObjectIdField(required=True, unique=True, help_text='liveaction ID.') query_module = me.StringField(required=True, help_text='Reference to the runner model.') query_context = me.DictField( required=True, help_text= 'Context about the action execution that is needed for results query.') meta = {'indexes': ['query_module']} # specialized access objects actionexecstate_access = MongoDBAccess(ActionExecutionStateDB) MODELS = [ActionExecutionStateDB]
def get_uid(self): # Note: Trigger is uniquely identified using name + pack + parameters attributes uid = super(TriggerDB, self).get_uid() parameters = getattr(self, 'parameters', {}) parameters = bencode.bencode(parameters) parameters = hashlib.md5(parameters).hexdigest() uid = uid + self.UID_SEPARATOR + parameters return uid class TriggerInstanceDB(stormbase.StormFoundationDB): """An instance or occurrence of a type of Trigger. Attribute: trigger: Reference to the Trigger object. payload (dict): payload specific to the occurrence. occurrence_time (datetime): time of occurrence of the trigger. """ trigger = me.StringField() payload = stormbase.EscapedDictField() occurrence_time = me.DateTimeField() # specialized access objects triggertype_access = MongoDBAccess(TriggerTypeDB) trigger_access = MongoDBAccess(TriggerDB) triggerinstance_access = MongoDBAccess(TriggerInstanceDB) MODELS = [TriggerTypeDB, TriggerDB, TriggerInstanceDB]
help_text='The timestamp when the Trace was created.') meta = { 'indexes': [ { 'fields': ['trace_tag'] }, { 'fields': ['start_timestamp'] }, { 'fields': ['action_executions.object_id'] }, { 'fields': ['trigger_instances.object_id'] }, { 'fields': ['rules.object_id'] }, { 'fields': ['-start_timestamp', 'trace_tag'] }, ] } # specialized access objects trace_access = MongoDBAccess(TraceDB) MODELS = [TraceDB]
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. from st2common import log as logging from st2common.models.db import MongoDBAccess from st2common.models.db.stormbase import StormFoundationDB __all__ = [ 'ActionRunnerDB' ] LOG = logging.getLogger(__name__) class ActionRunnerDB(StormFoundationDB): """ The system entity that represents an ActionRunner environment in the system. This entity is used internally to manage and scale-out the StackStorm services. the system. Attributes: """ pass actionrunner_access = MongoDBAccess(ActionRunnerDB) MODELS = [ActionRunnerDB]
""" name = me.StringField(required=True) ref = me.StringField(required=True) description = me.StringField() enabled = me.BooleanField( required=True, default=True, help_text='A flag indicating whether the action is enabled.') entry_point = me.StringField( required=True, help_text='The entry point to the action.') pack = me.StringField( required=False, help_text='Name of the content pack.', unique_with='name') runner_type = me.DictField( required=True, default={}, help_text='The action runner to use for executing the action.') parameters = me.DictField( help_text='The specification for parameters for the action.') notify = me.EmbeddedDocumentField(NotificationSchema) meta = { 'indexes': stormbase.TagsMixin.get_indices() } # specialized access objects action_access = MongoDBAccess(ActionDB) MODELS = [ActionDB, ActionExecutionDB, ActionExecutionStateDB, ActionAliasDB, LiveActionDB, RunnerTypeDB]
'Callback information for the on completion of action execution.') meta = {'indexes': ['-start_timestamp', 'action']} class ActionExecutionStateDB(stormbase.StormFoundationDB): """ Database entity that represents the state of Action execution. """ execution_id = me.ObjectIdField(required=True, unique=True, help_text='liveaction ID.') query_module = me.StringField(required=True, help_text='Reference to the runner model.') query_context = me.DictField( required=True, help_text= 'Context about the action execution that is needed for results query.') meta = {'indexes': ['query_module']} # specialized access objects runnertype_access = MongoDBAccess(RunnerTypeDB) action_access = MongoDBAccess(ActionDB) liveaction_access = MongoDBAccess(LiveActionDB) actionexecstate_access = MongoDBAccess(ActionExecutionStateDB) MODELS = [RunnerTypeDB, ActionDB, LiveActionDB, ActionExecutionStateDB]
class RuleDB(stormbase.StormBaseDB, stormbase.TagsMixin): """Specifies the action to invoke on the occurrence of a Trigger. It also includes the transformation to perform to match the impedance between the payload of a TriggerInstance and input of a action. Attribute: trigger: Trigger that trips this rule. criteria: action: Action to execute when the rule is tripped. status: enabled or disabled. If disabled occurrence of the trigger does not lead to execution of a action and vice-versa. """ trigger = me.StringField() criteria = stormbase.EscapedDictField() action = me.EmbeddedDocumentField(ActionExecutionSpecDB) enabled = me.BooleanField( required=True, default=True, help_text=u'Flag indicating whether the rule is enabled.') meta = {'indexes': stormbase.TagsMixin.get_indices()} # specialized access objects sensor_type_access = MongoDBAccess(SensorTypeDB) triggertype_access = MongoDBAccess(TriggerTypeDB) trigger_access = MongoDBAccess(TriggerDB) triggerinstance_access = MongoDBAccess(TriggerInstanceDB) rule_access = MongoDBAccess(RuleDB) MODELS = [SensorTypeDB, TriggerTypeDB, TriggerDB, TriggerInstanceDB, RuleDB]
formats: Alias format strings. """ RESOURCE_TYPE = ResourceType.ACTION UID_FIELDS = ['pack', 'name'] ref = me.StringField(required=True) pack = me.StringField(required=True, help_text='Name of the content pack.') enabled = me.BooleanField( required=True, default=True, help_text='A flag indicating whether the action alias is enabled.') action_ref = me.StringField( required=True, help_text='Reference of the Action map this alias.') formats = me.ListField( field=me.StringField(), help_text='Possible parameter formats that an alias supports.') meta = {'indexes': ['name']} def __init__(self, *args, **values): super(ActionAliasDB, self).__init__(*args, **values) self.ref = self.get_reference().ref self.uid = self.get_uid() # specialized access objects actionalias_access = MongoDBAccess(ActionAliasDB) MODELS = [ActionAliasDB]
# TODO: Can status be an enum at the Mongo layer? status = me.StringField( required=True, help_text='The current status of the ActionExecution.') start_timestamp = me.DateTimeField( default=datetime.datetime.utcnow, help_text='The timestamp when the ActionExecution was created.') action = me.StringField( required=True, help_text='Reference to the action that has to be executed.') parameters = me.DictField( default={}, help_text= 'The key-value pairs passed as to the action runner & execution.') result = EscapedDynamicField(default={}, help_text='Action defined result.') context = me.DictField( default={}, help_text='Contextual information on the action execution.') callback = me.DictField( default={}, help_text= 'Callback information for the on completion of action execution.') # specialized access objects runnertype_access = MongoDBAccess(RunnerTypeDB) action_access = MongoDBAccess(ActionDB) actionexec_access = MongoDBAccess(ActionExecutionDB) MODELS = [RunnerTypeDB, ActionDB, ActionExecutionDB]
values = stormbase.EscapedDynamicField( help_text='Config values.', default={}) def mask_secrets(self, value): """ Process the model dictionary and mask secret values. :type value: ``dict`` :param value: Document dictionary. :rtype: ``dict`` """ result = copy.deepcopy(value) config_schema = config_schema_access.get_by_pack(result['pack']) secret_parameters = get_secret_parameters(parameters=config_schema.attributes) result['values'] = mask_secret_parameters(parameters=result['values'], secret_parameters=secret_parameters) return result # specialized access objects pack_access = MongoDBAccess(PackDB) config_schema_access = MongoDBAccess(ConfigSchemaDB) config_access = MongoDBAccess(ConfigDB) MODELS = [PackDB, ConfigSchemaDB, ConfigDB]
class GroupToRoleMappingDB(stormbase.StormFoundationDB): """ An entity which represents mapping from a remote auth backend group to StackStorm roles. Attribute: group: Name of the remote auth backend group. roles: A reference to the local RBAC role names. source: Source where this assignment comes from. Path to a file for local assignments and "API" for API assignments. description: Optional description for this mapping. """ group = me.StringField(required=True, unique=True) roles = me.ListField(field=me.StringField()) source = me.StringField() description = me.StringField() enabled = me.BooleanField( required=True, default=True, help_text='A flag indicating whether the mapping is enabled.') # Specialized access objects role_access = MongoDBAccess(RoleDB) user_role_assignment_access = MongoDBAccess(UserRoleAssignmentDB) permission_grant_access = MongoDBAccess(PermissionGrantDB) group_to_role_mapping_access = MongoDBAccess(GroupToRoleMappingDB) MODELS = [ RoleDB, UserRoleAssignmentDB, PermissionGrantDB, GroupToRoleMappingDB ]