def _inner(): if initial_delay: greenthread.sleep(initial_delay) try: while self._running: start = timeutils.utcnow() self.f(*self.args, **self.kw) end = timeutils.utcnow() if not self._running: break delay = interval - timeutils.delta_seconds(start, end) if delay <= 0: LOG.warn(_('task run outlasted interval by %s sec') % -delay) greenthread.sleep(delay if delay > 0 else 0) except LoopingCallDone as e: self.stop() done.send(e.retvalue) except Exception: LOG.exception(_('in fixed duration looping call')) done.send_exception(*sys.exc_info()) return else: done.send(True)
def _inner(): if initial_delay: greenthread.sleep(initial_delay) try: while self._running: start = timeutils.utcnow() self.f(*self.args, **self.kw) end = timeutils.utcnow() if not self._running: break delay = interval - timeutils.delta_seconds(start, end) if delay <= 0: LOG.warn( _('task run outlasted interval by %s sec') % -delay) greenthread.sleep(delay if delay > 0 else 0) except LoopingCallDone as e: self.stop() done.send(e.retvalue) except Exception: LOG.exception(_('in fixed duration looping call')) done.send_exception(*sys.exc_info()) return else: done.send(True)
def upgrade(): op.add_column( 'order_retry_tasks', sa.Column( 'created_at', sa.DateTime(), nullable=False, server_default=str(timeutils.utcnow()))) op.add_column( 'order_retry_tasks', sa.Column( 'deleted', sa.Boolean(), nullable=False, server_default='0')) op.add_column( 'order_retry_tasks', sa.Column('deleted_at', sa.DateTime(), nullable=True)) op.add_column( 'order_retry_tasks', sa.Column( 'status', sa.String(length=20), nullable=False, server_default=m.States.PENDING)) op.add_column( 'order_retry_tasks', sa.Column( 'updated_at', sa.DateTime(), nullable=False, server_default=str(timeutils.utcnow())))
def get_by_create_date(self, keystone_id, offset_arg=None, limit_arg=None, name=None, alg=None, mode=None, bits=0, suppress_exception=False, session=None): """Returns a list of secrets, ordered by the date they were created at and paged based on the offset and limit fields. The keystone_id is external-to-Barbican value assigned to the tenant by Keystone. """ offset, limit = clean_paging_values(offset_arg, limit_arg) session = self.get_session(session) utcnow = timeutils.utcnow() try: query = session.query(models.Secret) \ .order_by(models.Secret.created_at) \ .filter_by(deleted=False) # Note: Must use '== None' below, not 'is None'. query = query.filter( or_(models.Secret.expiration == None, models.Secret.expiration > utcnow)) if name: query = query.filter(models.Secret.name.like(name)) if alg: query = query.filter(models.Secret.algorithm.like(alg)) if mode: query = query.filter(models.Secret.mode.like(mode)) if bits > 0: query = query.filter(models.Secret.bit_length == bits) query = query.join(models.TenantSecret, models.Secret.tenant_assocs) \ .join(models.Tenant, models.TenantSecret.tenants) \ .filter(models.Tenant.keystone_id == keystone_id) start = offset end = offset + limit LOG.debug('Retrieving from {0} to {1}'.format(start, end)) total = query.count() entities = query[start:end] LOG.debug('Number entities retrieved: {0} out of {1}'.format( len(entities), total)) except sa_orm.exc.NoResultFound: entities = None total = 0 if not suppress_exception: raise exception.NotFound("No %s's found" % (self._do_entity_name())) return entities, offset, limit, total
def setUp(self): super(WhenBeginningAsymmetricTypeOrder, self).setUp() self.requestor = 'requestor1234' self.order = models.Order() self.order.id = "id1" self.order.requestor = self.requestor self.order.type = "asymmetric" self.meta = {'name': 'myrsakey', 'payload_content_type': 'application/octet-stream', 'algorithm': 'rsa', 'bit_length': 2048, 'expiration': timeutils.utcnow()} self.order.meta = self.meta self.keystone_id = 'keystone1234' self.tenant_id = 'tenantid1234' self.tenant = models.Tenant() self.tenant.id = self.tenant_id self.tenant.keystone_id = self.keystone_id self.tenant_repo = mock.MagicMock() self.tenant_repo.get.return_value = self.tenant self.order.status = models.States.PENDING self.order.tenant_id = self.tenant_id self.order_repo = mock.MagicMock() self.order_repo.get.return_value = self.order self.order_repo = mock.MagicMock() self.order_repo.get.return_value = self.order self.secret_repo = mock.MagicMock() self.secret_repo.create_from.return_value = None self.tenant_secret_repo = mock.MagicMock() self.tenant_secret_repo.create_from.return_value = None self.datum_repo = mock.MagicMock() self.datum_repo.create_from.return_value = None self.kek_repo = mock.MagicMock() self.secret_meta_repo = mock.MagicMock() self.container_repo = mock.MagicMock() self.container_repo.create_from.return_value = None self.container_secret_repo = mock.MagicMock() self.container_secret_repo.create_from.return_value = None self.container = models.Container() self.resource = resources.BeginTypeOrder(self.tenant_repo, self.order_repo, self.secret_repo, self.tenant_secret_repo, self.datum_repo, self.kek_repo, self.secret_meta_repo, self.container_repo, self.container_secret_repo)
def delete(self, session=None): """Delete this object.""" import barbican.model.repositories session = session or barbican.model.repositories.get_session() self.deleted = True self.deleted_at = timeutils.utcnow() self.save(session=session) self._do_delete_children(session)
def setUp(self): super(WhenBeginningOrder, self).setUp() self.requestor = 'requestor1234' self.order = models.Order() self.order.id = "id1" self.order.requestor = self.requestor self.secret_name = "name" self.secret_algorithm = "AES" self.secret_bit_length = 256 self.secret_mode = "CBC" self.secret_expiration = timeutils.utcnow() self.secret_payload_content_type = 'application/octet-stream' self.keystone_id = 'keystone1234' self.tenant_id = 'tenantid1234' self.tenant = models.Tenant() self.tenant.id = self.tenant_id self.tenant.keystone_id = self.keystone_id self.tenant_repo = mock.MagicMock() self.tenant_repo.get.return_value = self.tenant self.order.status = models.States.PENDING self.order.tenant_id = self.tenant_id self.order.secret_name = self.secret_name self.order.secret_algorithm = self.secret_algorithm self.order.secret_bit_length = self.secret_bit_length self.order.secret_mode = self.secret_mode self.order.secret_expiration = self.secret_expiration self.order.secret_payload_content_type = self\ .secret_payload_content_type self.order_repo = mock.MagicMock() self.order_repo.get.return_value = self.order self.secret = models.Secret() self.secret_repo = mock.MagicMock() self.secret_repo.create_from.return_value = None self.tenant_secret_repo = mock.MagicMock() self.tenant_secret_repo.create_from.return_value = None self.datum_repo = mock.MagicMock() self.datum_repo.create_from.return_value = None self.kek_repo = mock.MagicMock() self.secret_meta_repo = mock.MagicMock() self.resource = resources.BeginOrder(self.tenant_repo, self.order_repo, self.secret_repo, self.tenant_secret_repo, self.datum_repo, self.kek_repo, self.secret_meta_repo )
def delete(self, session=None): """Delete this object.""" import barbican.model.repositories session = session or barbican.model.repositories.get_session() self.deleted = True self.deleted_at = timeutils.utcnow() self.save(session=session) self._do_delete_children(session)
def get_by_create_date(self, external_project_id, offset_arg=None, limit_arg=None, name=None, alg=None, mode=None, bits=0, suppress_exception=False, session=None): """Returns a list of secrets The returned secrets are ordered by the date they were created at and paged based on the offset and limit fields. The external_project_id is external-to-Barbican value assigned to the project by Keystone. """ offset, limit = clean_paging_values(offset_arg, limit_arg) session = self.get_session(session) utcnow = timeutils.utcnow() query = session.query(models.Secret) query = query.order_by(models.Secret.created_at) query = query.filter_by(deleted=False) # Note(john-wood-w): SQLAlchemy requires '== None' below, # not 'is None'. query = query.filter( or_(models.Secret.expiration == None, models.Secret.expiration > utcnow)) if name: query = query.filter(models.Secret.name.like(name)) if alg: query = query.filter(models.Secret.algorithm.like(alg)) if mode: query = query.filter(models.Secret.mode.like(mode)) if bits > 0: query = query.filter(models.Secret.bit_length == bits) query = query.join(models.ProjectSecret, models.Secret.project_assocs) query = query.join(models.Project, models.ProjectSecret.projects) query = query.filter(models.Project.external_id == external_project_id) start = offset end = offset + limit LOG.debug('Retrieving from %s to %s', start, end) total = query.count() entities = query[start:end] LOG.debug('Number entities retrieved: %s out of %s', len(entities), total) if total <= 0 and not suppress_exception: _raise_no_entities_found(self._do_entity_name()) return entities, offset, limit, total
def get_by_create_date(self, keystone_id, offset_arg=None, limit_arg=None, name=None, alg=None, mode=None, bits=0, suppress_exception=False, session=None): """Returns a list of secrets The returned secrets are ordered by the date they were created at and paged based on the offset and limit fields. The keystone_id is external-to-Barbican value assigned to the tenant by Keystone. """ offset, limit = clean_paging_values(offset_arg, limit_arg) session = self.get_session(session) utcnow = timeutils.utcnow() try: query = session.query(models.Secret) query = query.order_by(models.Secret.created_at) query = query.filter_by(deleted=False) # Note(john-wood-w): SQLAlchemy requires '== None' below, # not 'is None'. query = query.filter(or_(models.Secret.expiration == None, models.Secret.expiration > utcnow)) if name: query = query.filter(models.Secret.name.like(name)) if alg: query = query.filter(models.Secret.algorithm.like(alg)) if mode: query = query.filter(models.Secret.mode.like(mode)) if bits > 0: query = query.filter(models.Secret.bit_length == bits) query = query.join(models.TenantSecret, models.Secret.tenant_assocs) query = query.join(models.Tenant, models.TenantSecret.tenants) query = query.filter(models.Tenant.keystone_id == keystone_id) start = offset end = offset + limit LOG.debug('Retrieving from %s to %s', start, end) total = query.count() entities = query[start:end] LOG.debug('Number entities retrieved: %s out of %s', len(entities), total ) except sa_orm.exc.NoResultFound: entities = None total = 0 if not suppress_exception: raise exception.NotFound("No %s's found" % (self._do_entity_name())) return entities, offset, limit, total
def _assert_expiration_is_valid(self, expiration, schema_name): """Asserts that the given expiration date is valid. Which means that it should not be in the past. """ if expiration: # Verify not already expired. utcnow = timeutils.utcnow() self._assert_validity(expiration > utcnow, schema_name, u._("'expiration' is before current time"), "expiration")
def _inner(): if initial_delay: greenthread.sleep(initial_delay) try: while self._running: start = timeutils.utcnow() self.f(*self.args, **self.kw) end = timeutils.utcnow() if not self._running: break delay = interval - timeutils.delta_seconds(start, end) if delay <= 0: LOG.warn(_('task run outlasted interval by %s sec') % -delay) greenthread.sleep(delay if delay > 0 else 0) except LoopingCallDone, e: self.stop() done.send(e.retvalue)
def setUp(self): self.requestor = 'requestor1234' self.order = models.Order() self.order.id = "id1" self.order.requestor = self.requestor self.secret_name = "name" self.secret_algorithm = "AES" self.secret_bit_length = 256 self.secret_mode = "CBC" self.secret_expiration = timeutils.utcnow() self.secret_payload_content_type = 'application/octet-stream' self.keystone_id = 'keystone1234' self.tenant_id = 'tenantid1234' self.tenant = models.Tenant() self.tenant.id = self.tenant_id self.tenant.keystone_id = self.keystone_id self.tenant_repo = mock.MagicMock() self.tenant_repo.get.return_value = self.tenant self.order.status = models.States.PENDING self.order.tenant_id = self.tenant_id self.order.secret_name = self.secret_name self.order.secret_algorithm = self.secret_algorithm self.order.secret_bit_length = self.secret_bit_length self.order.secret_mode = self.secret_mode self.order.secret_expiration = self.secret_expiration self.order.secret_payload_content_type = self\ .secret_payload_content_type self.order_repo = mock.MagicMock() self.order_repo.get.return_value = self.order self.secret_repo = mock.MagicMock() self.secret_repo.create_from.return_value = None self.tenant_secret_repo = mock.MagicMock() self.tenant_secret_repo.create_from.return_value = None self.datum_repo = mock.MagicMock() self.datum_repo.create_from.return_value = None self.kek_repo = mock.MagicMock() self.conf = mock.MagicMock() self.conf.crypto.namespace = 'barbican.test.crypto.plugin' self.conf.crypto.enabled_crypto_plugins = ['test_crypto'] self.crypto_mgr = em.CryptoExtensionManager(conf=self.conf) self.resource = resources.BeginOrder(self.crypto_mgr, self.tenant_repo, self.order_repo, self.secret_repo, self.tenant_secret_repo, self.datum_repo, self.kek_repo)
def save(self, session=None): """Save this object.""" # import api here to prevent circular dependency problem import barbican.model.repositories session = session or barbican.model.repositories.get_session() # if model is being created ensure that created/updated are the same if self.id is None: self.created_at = timeutils.utcnow() self.updated_at = self.created_at session.add(self) session.flush()
def notify(context, publisher_id, event_type, priority, payload): """Sends a notification using the specified driver :param publisher_id: the source worker_type.host of the message :param event_type: the literal type of event (ex. Instance Creation) :param priority: patterned after the enumeration of Python logging levels in the set (DEBUG, WARN, INFO, ERROR, CRITICAL) :param payload: A python dictionary of attributes Outgoing message format includes the above parameters, and appends the following: message_id a UUID representing the id for this notification timestamp the GMT timestamp the notification was sent at The composite message will be constructed as a dictionary of the above attributes, which will then be sent via the transport mechanism defined by the driver. Message example:: {'message_id': str(uuid.uuid4()), 'publisher_id': 'compute.host1', 'timestamp': timeutils.utcnow(), 'priority': 'WARN', 'event_type': 'compute.create_instance', 'payload': {'instance_id': 12, ... }} """ if priority not in log_levels: raise BadPriorityException( _('%s not in valid priorities') % priority) # Ensure everything is JSON serializable. payload = jsonutils.to_primitive(payload, convert_instances=True) msg = dict(message_id=str(uuid.uuid4()), publisher_id=publisher_id, event_type=event_type, priority=priority, payload=payload, timestamp=str(timeutils.utcnow())) for driver in _get_drivers(): try: driver.notify(context, msg) except Exception as e: LOG.exception(_("Problem '%(e)s' attempting to " "send to notification system. " "Payload=%(payload)s") % dict(e=e, payload=payload))
def _assert_expiration_is_valid(self, expiration, schema_name): """Asserts that the given expiration date is valid. Expiration dates must be in the future, not the past. """ if expiration: # Verify not already expired. utcnow = timeutils.utcnow() self._assert_validity(expiration > utcnow, schema_name, u._("'expiration' is before current time"), "expiration")
def _inner(): if initial_delay: greenthread.sleep(initial_delay) try: while self._running: start = timeutils.utcnow() self.f(*self.args, **self.kw) end = timeutils.utcnow() if not self._running: break delay = interval - timeutils.delta_seconds(start, end) if delay <= 0: LOG.warn( _('task run outlasted interval by %s sec') % -delay) greenthread.sleep(delay if delay > 0 else 0) except LoopingCallDone, e: self.stop() done.send(e.retvalue)
def setUp(self): self.requestor = 'requestor1234' self.order = models.Order() self.order.id = "id1" self.order.requestor = self.requestor self.secret_name = "name" self.secret_algorithm = "AES" self.secret_bit_length = 256 self.secret_mode = "CBC" self.secret_expiration = timeutils.utcnow() self.secret_payload_content_type = 'application/octet-stream' self.keystone_id = 'keystone1234' self.tenant_id = 'tenantid1234' self.tenant = models.Tenant() self.tenant.id = self.tenant_id self.tenant.keystone_id = self.keystone_id self.tenant_repo = mock.MagicMock() self.tenant_repo.get.return_value = self.tenant self.order.status = models.States.PENDING self.order.tenant_id = self.tenant_id self.order.secret_name = self.secret_name self.order.secret_algorithm = self.secret_algorithm self.order.secret_bit_length = self.secret_bit_length self.order.secret_mode = self.secret_mode self.order.secret_expiration = self.secret_expiration self.order.secret_payload_content_type = self\ .secret_payload_content_type self.order_repo = mock.MagicMock() self.order_repo.get.return_value = self.order self.secret_repo = mock.MagicMock() self.secret_repo.create_from.return_value = None self.tenant_secret_repo = mock.MagicMock() self.tenant_secret_repo.create_from.return_value = None self.datum_repo = mock.MagicMock() self.datum_repo.create_from.return_value = None self.kek_repo = mock.MagicMock() self.conf = mock.MagicMock() self.conf.crypto.namespace = 'barbican.test.crypto.plugin' self.conf.crypto.enabled_crypto_plugins = ['test_crypto'] self.crypto_mgr = em.CryptoExtensionManager(conf=self.conf) self.resource = resources.BeginOrder(self.crypto_mgr, self.tenant_repo, self.order_repo, self.secret_repo, self.tenant_secret_repo, self.datum_repo, self.kek_repo)
def save(self, metadata, secret_model): """Saves the the specified metadata for the secret. :raises NotFound if entity does not exist. """ now = timeutils.utcnow() for k, v in metadata.items(): meta_model = models.SecretStoreMetadatum(k, v) meta_model.updated_at = now meta_model.secret = secret_model meta_model.save()
def save(self, entity): """Saves the state of the entity.""" entity.updated_at = timeutils.utcnow() # Validate the attributes before we go any further. From my # (unknown Glance developer) investigation, the @validates # decorator does not validate # on new records, only on existing records, which is, well, # idiotic. self._do_validate(entity.to_dict()) entity.save()
def save(self, metadata, secret_model): """Saves the the specified metadata for the secret. :raises NotFound if entity does not exist. """ now = timeutils.utcnow() for k, v in metadata.items(): meta_model = models.SecretStoreMetadatum(k, v) meta_model.updated_at = now meta_model.secret = secret_model meta_model.save()
def _do_build_get_query(self, entity_id, keystone_id, session): """Sub-class hook: build a retrieve query.""" utcnow = timeutils.utcnow() # Note: Must use '== None' below, not 'is None'. # TODO: Performance? Is the many-to-many join needed? return session.query(models.Secret).filter_by(id=entity_id) \ .filter_by(deleted=False) \ .filter(or_(models.Secret.expiration == None, models.Secret.expiration > utcnow)) \ .join(models.TenantSecret, models.Secret.tenant_assocs)\ .join(models.Tenant, models.TenantSecret.tenants) \ .filter(models.Tenant.keystone_id == keystone_id)
def save(self, metadata, order_model): """Saves the the specified metadata for the order. :raises NotFound if entity does not exist. """ now = timeutils.utcnow() session = get_session() for k, v in metadata.items(): meta_model = models.OrderPluginMetadatum(k, v) meta_model.updated_at = now meta_model.order = order_model meta_model.save(session=session)
def save(self, metadata, order_model): """Saves the the specified metadata for the order. :raises NotFound if entity does not exist. """ now = timeutils.utcnow() session = get_session() with session.begin(): for k, v in metadata.items(): meta_model = models.OrderPluginMetadatum(k, v) meta_model.updated_at = now meta_model.order = order_model meta_model.save(session=session)
def _do_build_get_query(self, entity_id, keystone_id, session): """Sub-class hook: build a retrieve query.""" utcnow = timeutils.utcnow() # Note: Must use '== None' below, not 'is None'. # TODO: Performance? Is the many-to-many join needed? return session.query(models.Secret).filter_by(id=entity_id) \ .filter_by(deleted=False) \ .filter(or_(models.Secret.expiration == None, models.Secret.expiration > utcnow)) \ .join(models.TenantSecret, models.Secret.tenant_assocs)\ .join(models.Tenant, models.TenantSecret.tenants) \ .filter(models.Tenant.keystone_id == keystone_id)
def setUp(self): self.requestor = 'requestor1234' self.order = Order() self.order.id = "id1" self.order.requestor = self.requestor self.secret_name = "name" self.secret_algorithm = "algo" self.secret_bit_length = 512 self.secret_cypher_type = "cytype" self.secret_mime_type = "text/plain" self.secret_expiration = timeutils.utcnow() self.keystone_id = 'keystone1234' self.tenant_id = 'tenantid1234' self.tenant = Tenant() self.tenant.id = self.tenant_id self.tenant.keystone_id = self.keystone_id self.tenant_repo = MagicMock() self.tenant_repo.get.return_value = self.tenant self.order.status = States.PENDING self.order.tenant_id = self.tenant_id self.order.secret_name = self.secret_name self.order.secret_algorithm = self.secret_algorithm self.order.secret_bit_length = self.secret_bit_length self.order.secret_cypher_type = self.secret_cypher_type self.order.secret_expiration = self.secret_expiration self.order.secret_mime_type = self.secret_mime_type self.order_repo = MagicMock() self.order_repo.get.return_value = self.order self.secret_repo = MagicMock() self.secret_repo.create_from.return_value = None self.tenant_secret_repo = MagicMock() self.tenant_secret_repo.create_from.return_value = None self.datum_repo = MagicMock() self.datum_repo.create_from.return_value = None self.conf = MagicMock() self.conf.crypto.namespace = 'barbican.test.crypto.plugin' self.conf.crypto.enabled_crypto_plugins = ['test_crypto'] self.crypto_mgr = CryptoExtensionManager(conf=self.conf) self.resource = BeginOrder(self.crypto_mgr, self.tenant_repo, self.order_repo, self.secret_repo, self.tenant_secret_repo, self.datum_repo)
def setUp(self): self.requestor = 'requestor1234' self.order = Order() self.order.id = "id1" self.order.requestor = self.requestor self.secret_name = "name" self.secret_algorithm = "algo" self.secret_bit_length = 512 self.secret_cypher_type = "cytype" self.secret_mime_type = "text/plain" self.secret_expiration = timeutils.utcnow() self.keystone_id = 'keystone1234' self.tenant_id = 'tenantid1234' self.tenant = Tenant() self.tenant.id = self.tenant_id self.tenant.keystone_id = self.keystone_id self.tenant_repo = MagicMock() self.tenant_repo.get.return_value = self.tenant self.order.status = States.PENDING self.order.tenant_id = self.tenant_id self.order.secret_name = self.secret_name self.order.secret_algorithm = self.secret_algorithm self.order.secret_bit_length = self.secret_bit_length self.order.secret_cypher_type = self.secret_cypher_type self.order.secret_expiration = self.secret_expiration self.order.secret_mime_type = self.secret_mime_type self.order_repo = MagicMock() self.order_repo.get.return_value = self.order self.secret_repo = MagicMock() self.secret_repo.create_from.return_value = None self.tenant_secret_repo = MagicMock() self.tenant_secret_repo.create_from.return_value = None self.datum_repo = MagicMock() self.datum_repo.create_from.return_value = None self.conf = MagicMock() self.conf.crypto.namespace = 'barbican.test.crypto.plugin' self.conf.crypto.enabled_crypto_plugins = ['test_crypto'] self.crypto_mgr = CryptoExtensionManager(conf=self.conf) self.resource = BeginOrder(self.crypto_mgr, self.tenant_repo, self.order_repo, self.secret_repo, self.tenant_secret_repo, self.datum_repo)
def validate(self, json_data, parent_schema=None): schema_name = self._full_name(parent_schema) try: validate(json_data, self.schema) except ValidationError as e: raise exception.InvalidObject(schema=schema_name, reason=str(e)) # Validate/normalize 'name'. name = json_data.get('name', '').strip() if not name: name = None json_data['name'] = name # Validate/convert 'expiration' if provided. expiration = self._extract_expiration(json_data) if expiration: try: expiration = dateutil.parser.parse(expiration) except ValueError: LOG.exception("Problem parsing date") raise exception.InvalidObject(schema=schema_name, reason=_("Invalid date " "for 'expiration'")) # Verify not already expired. utcnow = timeutils.utcnow() if expiration <= utcnow: raise exception.InvalidObject(schema=schema_name, reason=_("'expiration' is " "before current time")) json_data['expiration'] = expiration # Validate/convert 'plain_text' if provided. if 'plain_text' in json_data: plain_text = json_data['plain_text'] if secret_too_big(plain_text): raise exception.LimitExceeded() plain_text = plain_text.strip() if not plain_text: raise exception.InvalidObject(schema=schema_name, reason=_("If 'plain_text' " "specified, must be " "non empty")) json_data['plain_text'] = plain_text # TODO: Add validation of 'mime_type' based on loaded plugins. return json_data
def setUp(self): self.requestor = 'requestor1234' self.order = Order() self.order.id = "id1" self.order.requestor = self.requestor self.secret_name = "name" self.secret_algorithm = "algo" self.secret_bit_length = 512 self.secret_cypher_type = "cytype" self.secret_mime_type = "mimetype" self.secret_expiration = timeutils.utcnow() self.keystone_id = 'keystone1234' self.tenant_id = 'tenantid1234' self.tenant = Tenant() self.tenant.id = self.tenant_id self.tenant.keystone_id = self.keystone_id self.tenant_repo = MagicMock() self.tenant_repo.get.return_value = self.tenant self.order.status = States.PENDING self.order.tenant_id = self.tenant_id self.order.secret_name = self.secret_name self.order.secret_algorithm = self.secret_algorithm self.order.secret_bit_length = self.secret_bit_length self.order.secret_cypher_type = self.secret_cypher_type self.order.secret_expiration = self.secret_expiration self.order.secret_mime_type = self.secret_mime_type self.order_repo = MagicMock() self.order_repo.get.return_value = self.order self.secret_repo = MagicMock() self.secret_repo.create_from.return_value = None self.tenant_secret_repo = MagicMock() self.tenant_secret_repo.create_from.return_value = None self.datum_repo = MagicMock() self.datum_repo.create_from.return_value = None self.resource = BeginOrder(self.tenant_repo, self.order_repo, self.secret_repo, self.tenant_secret_repo, self.datum_repo)
def _do_build_get_query(self, entity_id, keystone_id, session): """Sub-class hook: build a retrieve query.""" utcnow = timeutils.utcnow() # Note(john-wood-w): SQLAlchemy requires '== None' below, # not 'is None'. # TODO(jfwood): Performance? Is the many-to-many join needed? expiration_filter = or_(models.Secret.expiration == None, models.Secret.expiration > utcnow) query = session.query(models.Secret) query = query.filter_by(id=entity_id, deleted=False) query = query.filter(expiration_filter) query = query.join(models.TenantSecret, models.Secret.tenant_assocs) query = query.join(models.Tenant, models.TenantSecret.tenants) query = query.filter(models.Tenant.keystone_id == keystone_id) return query
def _do_build_get_query(self, entity_id, external_project_id, session): """Sub-class hook: build a retrieve query.""" utcnow = timeutils.utcnow() # Note(john-wood-w): SQLAlchemy requires '== None' below, # not 'is None'. # TODO(jfwood): Performance? Is the many-to-many join needed? expiration_filter = or_(models.Secret.expiration == None, models.Secret.expiration > utcnow) query = session.query(models.Secret) query = query.filter_by(id=entity_id, deleted=False) query = query.filter(expiration_filter) query = query.join(models.ProjectSecret, models.Secret.project_assocs) query = query.join(models.Project, models.ProjectSecret.projects) query = query.filter(models.Project.external_id == external_project_id) return query
def _update(self, entity_id, values, purge_props=False): """ Used internally by update() :param values: A dict of attributes to set :param entity_id: If None, create the entity, otherwise, find and update it """ session = get_session() with session.begin(): if entity_id: entity_ref = self.get(entity_id, session=session) values['updated_at'] = timeutils.utcnow() else: self._do_convert_values(values) entity_ref = self._do_create_instance() # Need to canonicalize ownership if 'owner' in values and not values['owner']: values['owner'] = None entity_ref.update(values) # Validate the attributes before we go any further. From my # (unknown Glance developer) investigation, the @validates # decorator does not validate # on new records, only on existing records, which is, well, # idiotic. self._do_validate(entity_ref.to_dict()) self._update_values(entity_ref, values) try: entity_ref.save(session=session) except sqlalchemy.exc.IntegrityError: LOG.exception('Problem saving entity for _update') if entity_id: raise exception.NotFound("Entity ID %s not found" % entity_id) else: raise exception.Duplicate("Entity ID %s already exists!" % values['id']) return self.get(entity_ref.id)
def get_by_create_date(self, keystone_id, offset_arg=None, limit_arg=None, suppress_exception=False, session=None): """ Returns a list of secrets, ordered by the date they were created at and paged based on the offset and limit fields. The keystone_id is external-to-Barbican value assigned to the tenant by Keystone. """ offset, limit = clean_paging_values(offset_arg, limit_arg) session = self.get_session(session) utcnow = timeutils.utcnow() try: query = session.query(models.Secret) \ .order_by(models.Secret.created_at) \ .filter_by(deleted=False) # Note: Must use '== None' below, not 'is None'. query = query.filter(or_(models.Secret.expiration == None, models.Secret.expiration > utcnow)) query = query.join(models.TenantSecret, models.Secret.tenant_assocs) \ .join(models.Tenant, models.TenantSecret.tenants) \ .filter(models.Tenant.keystone_id == keystone_id) start = offset end = offset + limit LOG.debug('Retrieving from {0} to {1}'.format(start, end)) total = query.count() entities = query[start:end] LOG.debug('Number entities retrieved: {0} out of {1}'.format( len(entities), total )) except sa_orm.exc.NoResultFound: entities = None total = 0 if not suppress_exception: raise exception.NotFound("No %s's found" % (self._do_entity_name())) return entities, offset, limit, total
def _update(self, entity_id, values, purge_props=False): """ Used internally by update() :param values: A dict of attributes to set :param entity_id: If None, create the entity, otherwise, find and update it """ session = get_session() with session.begin(): if entity_id: entity_ref = self.get(entity_id, session=session) values['updated_at'] = timeutils.utcnow() else: self._do_convert_values(values) entity_ref = self._do_create_instance() # Need to canonicalize ownership if 'owner' in values and not values['owner']: values['owner'] = None entity_ref.update(values) # Validate the attributes before we go any further. From my # (unknown Glance developer) investigation, the @validates # decorator does not validate # on new records, only on existing records, which is, well, # idiotic. self._do_validate(entity_ref.to_dict()) self._update_values(entity_ref, values) try: entity_ref.save(session=session) except sqlalchemy.exc.IntegrityError: LOG.exception('Problem saving entity for _update') if entity_id: raise exception.NotFound("Entity ID %s not found" % entity_id) else: raise exception.Duplicate("Entity ID %s already exists!" % values['id']) return self.get(entity_ref.id)
def validate(self, json_data, parent_schema=None): schema_name = self._full_name(parent_schema) try: validate(json_data, self.schema) except ValidationError as e: raise exception.InvalidObject(schema=schema_name, reason=str(e)) # Validate/normalize 'name'. name = json_data.get('name', '').strip() if not name: name = None json_data['name'] = name # Validate/convert 'expiration' if provided. expiration = self._extract_expiration(json_data, schema_name) if expiration: # Verify not already expired. utcnow = timeutils.utcnow() if expiration <= utcnow: raise exception.InvalidObject(schema=schema_name, reason=_("'expiration' is " "before current time")) json_data['expiration'] = expiration # Validate/convert 'plain_text' if provided. if 'plain_text' in json_data: plain_text = json_data['plain_text'] if secret_too_big(plain_text): raise exception.LimitExceeded() plain_text = plain_text.strip() if not plain_text: raise exception.InvalidObject(schema=schema_name, reason=_("If 'plain_text' " "specified, must be " "non empty")) json_data['plain_text'] = plain_text # TODO: Add validation of 'mime_type' based on loaded plugins. return json_data
def save(self, entity): """Saves the state of the entity. :raises NotFound if entity does not exist. """ entity.updated_at = timeutils.utcnow() # Validate the attributes before we go any further. From my # (unknown Glance developer) investigation, the @validates # decorator does not validate # on new records, only on existing records, which is, well, # idiotic. self._do_validate(entity.to_dict()) try: entity.save() except sqlalchemy.exc.IntegrityError: LOG.exception('Problem saving entity for update') raise exception.NotFound("Entity ID %s not found" % entity.id)
def save(self, entity): """Saves the state of the entity. :raises NotFound if entity does not exist. """ session = get_session() with session.begin(): entity.updated_at = timeutils.utcnow() # Validate the attributes before we go any further. From my # (unknown Glance developer) investigation, the @validates # decorator does not validate # on new records, only on existing records, which is, well, # idiotic. self._do_validate(entity.to_dict()) try: entity.save(session=session) except sqlalchemy.exc.IntegrityError: LOG.exception('Problem saving entity for update') raise exception.NotFound("Entity ID %s not found" % entity.id)
def create_from(self, new_consumer, container): session = get_session() try: container.updated_at = timeutils.utcnow() container.consumers.append(new_consumer) container.save(session=session) except sqlalchemy.exc.IntegrityError: session.rollback() # We know consumer already exists. # This operation is idempotent, so log this and move on LOG.debug("Consumer %s already exists for container %s," " continuing...", (new_consumer.name, new_consumer.URL), new_consumer.container_id) # Get the existing entry and reuse it by clearing the deleted flags existing_consumer = self.get_by_values( new_consumer.container_id, new_consumer.name, new_consumer.URL, show_deleted=True) existing_consumer.deleted = False existing_consumer.deleted_at = None # We are not concerned about timing here -- set only, no reads existing_consumer.save()
def create_or_update_from(self, new_consumer, container, session=None): session = self.get_session(session) try: container.updated_at = timeutils.utcnow() container.consumers.append(new_consumer) container.save(session=session) except sqlalchemy.exc.IntegrityError: session.rollback() # We know consumer already exists. # This operation is idempotent, so log this and move on LOG.debug( "Consumer %s already exists for container %s," " continuing...", (new_consumer.name, new_consumer.URL), new_consumer.container_id) # Get the existing entry and reuse it by clearing the deleted flags existing_consumer = self.get_by_values(new_consumer.container_id, new_consumer.name, new_consumer.URL, show_deleted=True) existing_consumer.deleted = False existing_consumer.deleted_at = None # We are not concerned about timing here -- set only, no reads existing_consumer.save()
def validate(self, json_data, parent_schema=None): schema_name = self._full_name(parent_schema) try: schema.validate(json_data, self.schema) except schema.ValidationError as e: raise exception.InvalidObject(schema=schema_name, reason=e.message, property=get_invalid_property(e)) # Validate/normalize 'name'. name = json_data.get('name', '').strip() if not name: name = None json_data['name'] = name # Validate/convert 'expiration' if provided. expiration = self._extract_expiration(json_data, schema_name) if expiration: # Verify not already expired. utcnow = timeutils.utcnow() if expiration <= utcnow: raise exception.InvalidObject(schema=schema_name, reason=_("'expiration' is " "before current time"), property="expiration") json_data['expiration'] = expiration # Validate/convert 'payload' if provided. if 'payload' in json_data: content_type = json_data.get('payload_content_type') if content_type is None: raise exception.InvalidObject( schema=schema_name, reason=_("If 'payload' is supplied, 'payload_content_type'" " must also be supplied."), property="payload_content_type" ) content_encoding = json_data.get('payload_content_encoding') if content_type == 'application/octet-stream' and \ content_encoding is None: raise exception.InvalidObject( schema=schema_name, reason=_("payload_content_encoding must be specified " "when payload_content_type is application/" "octet-stream."), property="payload_content_encoding" ) if content_type.startswith('text/plain') and \ content_encoding is not None: raise exception.InvalidObject( schema=schema_name, reason=_("payload_content_encoding must not be specified " "when payload_content_type is text/plain"), property="payload_content_encoding" ) payload = json_data['payload'] if secret_too_big(payload): raise exception.LimitExceeded() payload = payload.strip() if not payload: raise exception.InvalidObject(schema=schema_name, reason=_("If 'payload' " "specified, must be " "non empty"), property="payload") json_data['payload'] = payload elif 'payload_content_type' in json_data and \ parent_schema is None: raise exception.InvalidObject( schema=schema_name, reason=_("payload must be provided " "when payload_content_type is specified"), property="payload" ) return json_data
def validate(self, json_data, parent_schema=None): schema_name = self._full_name(parent_schema) try: schema.validate(json_data, self.schema) except schema.ValidationError as e: raise exception.InvalidObject(schema=schema_name, reason=e.message, property=get_invalid_property(e)) # Validate/normalize 'name'. name = json_data.get('name', '').strip() if not name: name = None json_data['name'] = name # Validate/convert 'expiration' if provided. expiration = self._extract_expiration(json_data, schema_name) if expiration: # Verify not already expired. utcnow = timeutils.utcnow() if expiration <= utcnow: raise exception.InvalidObject(schema=schema_name, reason=u._("'expiration' is " "before current " "time"), property="expiration") json_data['expiration'] = expiration # Validate/convert 'payload' if provided. if 'payload' in json_data: content_type = json_data.get('payload_content_type') if content_type is None: raise exception.InvalidObject( schema=schema_name, reason=u._("If 'payload' is supplied, " "'payload_content_type' must " "also be supplied."), property="payload_content_type" ) if content_type.lower() not in mime_types.SUPPORTED: raise exception.InvalidObject( schema=schema_name, reason=u._("payload_content_type is not one of " "{0}").format(mime_types.SUPPORTED), property="payload_content_type" ) content_encoding = json_data.get('payload_content_encoding') if content_type == 'application/octet-stream' and \ content_encoding is None: raise exception.InvalidObject( schema=schema_name, reason=u._("payload_content_encoding must be specified " "when payload_content_type is application/" "octet-stream."), property="payload_content_encoding" ) if content_type.startswith('text/plain') and \ content_encoding is not None: raise exception.InvalidObject( schema=schema_name, reason=u._("payload_content_encoding must not be " "specified when payload_content_type is " "text/plain"), property="payload_content_encoding" ) payload = json_data['payload'] if secret_too_big(payload): raise exception.LimitExceeded() payload = payload.strip() if not payload: raise exception.InvalidObject(schema=schema_name, reason=u._("If 'payload' " "specified, must " "be non empty"), property="payload") json_data['payload'] = payload elif 'payload_content_type' in json_data and \ parent_schema is None: raise exception.InvalidObject( schema=schema_name, reason=u._("payload must be provided " "when payload_content_type is specified"), property="payload" ) return json_data
def setUp(self): super(WhenBeginningKeyTypeOrder, self).setUp() self.requestor = 'requestor1234' self.order = models.Order() self.order.id = "id1" self.order.requestor = self.requestor self.order.type = "key" self.meta = {'name': 'name', 'payload_content_type': 'application/octet-stream', 'algorithm': 'AES', 'bit_length': 256, 'expiration': timeutils.utcnow(), 'mode': 'CBC'} self.order.meta = self.meta self.keystone_id = 'keystone1234' self.project_id = 'projectid1234' self.project = models.Tenant() self.project.id = self.project_id self.project.keystone_id = self.keystone_id self.project_repo = mock.MagicMock() self.project_repo.get.return_value = self.project self.order.status = models.States.PENDING self.order.project_id = self.project_id self.order_repo = mock.MagicMock() self.order_repo.get.return_value = self.order self.order_repo = mock.MagicMock() self.order_repo.get.return_value = self.order self.order_plugin_meta_repo = mock.MagicMock() self.secret = models.Secret() self.secret_repo = mock.MagicMock() self.secret_repo.create_from.return_value = None self.project_secret_repo = mock.MagicMock() self.project_secret_repo.create_from.return_value = None self.datum_repo = mock.MagicMock() self.datum_repo.create_from.return_value = None self.kek_repo = mock.MagicMock() self.secret_meta_repo = mock.MagicMock() self.container_repo = mock.MagicMock() self.container_repo.create_from.return_value = None self.container_secret_repo = mock.MagicMock() self.container_secret_repo.create_from.return_value = None self.secret_meta_repo = mock.MagicMock() self.resource = resources.BeginTypeOrder(self.project_repo, self.order_repo, self.secret_repo, self.project_secret_repo, self.datum_repo, self.kek_repo, self.secret_meta_repo, self.container_repo, self.container_secret_repo, self.order_plugin_meta_repo)
def setUp(self): super(BaseOrderTestCase, self).setUp() self.requestor = 'requestor1234' self.order = models.Order() self.order.id = "id1" self.order.requestor = self.requestor self.order.type = "key" self.meta = {'name': 'name', 'payload_content_type': 'application/octet-stream', 'algorithm': 'AES', 'bit_length': 256, 'expiration': timeutils.utcnow(), 'mode': 'CBC'} self.order.meta = self.meta self.external_project_id = 'keystone1234' self.project_id = 'projectid1234' self.project = models.Project() self.project.id = self.project_id self.project.external_id = self.external_project_id self.project_repo = mock.MagicMock() self.project_repo.get.return_value = self.project self.setup_project_repository_mock(self.project_repo) self.order.status = models.States.PENDING self.order.id = 'orderid1234' self.order.project_id = self.project_id self.order_repo = mock.MagicMock() self.order_repo.get.return_value = self.order self.setup_order_repository_mock(self.order_repo) self.setup_order_plugin_meta_repository_mock() self.setup_order_barbican_meta_repository_mock() self.secret = models.Secret() self.secret_repo = mock.MagicMock() self.secret_repo.create_from.return_value = None self.setup_secret_repository_mock(self.secret_repo) self.project_secret_repo = mock.MagicMock() self.project_secret_repo.create_from.return_value = None self.setup_project_secret_repository_mock(self.project_secret_repo) self.datum_repo = mock.MagicMock() self.datum_repo.create_from.return_value = None self.setup_encrypted_datum_repository_mock(self.datum_repo) self.setup_kek_datum_repository_mock() self.setup_secret_meta_repository_mock() self.container_repo = mock.MagicMock() self.container_repo.create_from.return_value = None self.setup_container_repository_mock(self.container_repo) self.container_secret_repo = mock.MagicMock() self.container_secret_repo.create_from.return_value = None self.setup_container_secret_repository_mock(self.container_secret_repo) self.container = models.Container()
def validate(self, json_data, parent_schema=None): schema_name = self._full_name(parent_schema) try: schema.validate(json_data, self.schema) except schema.ValidationError as e: raise exception.InvalidObject(schema=schema_name, reason=str(e)) # Validate/normalize 'name'. name = json_data.get('name', '').strip() if not name: name = None json_data['name'] = name # Validate/convert 'expiration' if provided. expiration = self._extract_expiration(json_data, schema_name) if expiration: # Verify not already expired. utcnow = timeutils.utcnow() if expiration <= utcnow: raise exception.InvalidObject(schema=schema_name, reason=_("'expiration' is " "before current time")) json_data['expiration'] = expiration # Validate/convert 'payload' if provided. if 'payload' in json_data: content_type = json_data.get('payload_content_type') if content_type is None: raise exception.InvalidObject( schema=schema_name, reason=_("If 'payload' is supplied, 'payload_content_type'" " must also be supplied.") ) content_encoding = json_data.get('payload_content_encoding') if content_type == 'application/octet-stream' and \ content_encoding is None: raise exception.InvalidObject( schema=schema_name, reason=_("payload_content_encoding must be specified " "when payload_content_type is application/" "octet-stream.") ) if content_type.startswith('text/plain') and \ content_encoding is not None: raise exception.InvalidObject( schema=schema_name, reason=_("payload_content_encoding must not be specified " "when payload_content_type is text/plain") ) payload = json_data['payload'] if secret_too_big(payload): raise exception.LimitExceeded() payload = payload.strip() if not payload: raise exception.InvalidObject(schema=schema_name, reason=_("If 'payload' " "specified, must be " "non empty")) json_data['payload'] = payload return json_data