Adds SecretMetadatum table
This patch is the first planned in a series to add KMIP support to Barbican. Barbican currently returns metadata about secrets to the user, but adding secret_metadata table will allow users to set additional metadata options that are not supported by Barbican. After this submission is accepted, another patch will be created to move the current Secret attribute metadata to the new metadata table. Change-Id: Ibc990f798b118eeda705360e40ecf439d5a1b0cd Implements: blueprint add-metadata-to-secrets
This commit is contained in:
parent
0494edc559
commit
6966018eaa
@ -0,0 +1,51 @@
|
||||
# Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, 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.
|
||||
|
||||
"""create_secret_metadata_table
|
||||
|
||||
Revision ID: 13d127569afa
|
||||
Revises: 1a0c2cdafb38
|
||||
Create Date: 2014-04-24 13:15:41.858266
|
||||
|
||||
"""
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '13d127569afa'
|
||||
down_revision = '1a0c2cdafb38'
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
def upgrade():
|
||||
meta = sa.MetaData()
|
||||
meta.reflect(bind=rep._ENGINE, only=['secret_metadata'])
|
||||
if 'secret_metadata' not in meta.tables.keys():
|
||||
op.create_table('secret_metadata',
|
||||
sa.Column('id', sa.String(length=36), nullable=False),
|
||||
sa.Column('created_at', sa.DateTime(), nullable=False),
|
||||
sa.Column('updated_at', sa.DateTime(), nullable=False),
|
||||
sa.Column('deleted_at', sa.DateTime(), nullable=True),
|
||||
sa.Column('deleted', sa.Boolean(), nullable=False),
|
||||
sa.Column('status', sa.String(length=20), nullable=False),
|
||||
sa.Column('secret_id', sa.String(length=36), nullable=False),
|
||||
sa.Column('key', sa.String(length=255), nullable=False),
|
||||
sa.Column('value', sa.String(length=255), nullable=False),
|
||||
sa.ForeignKeyConstraint(['secret_id'], ['secrets.id'],),
|
||||
sa.PrimaryKeyConstraint('id'),
|
||||
)
|
||||
|
||||
def downgrade():
|
||||
op.drop_table('secret_metadata')
|
@ -21,6 +21,7 @@ from sqlalchemy.ext import compiler
|
||||
from sqlalchemy.ext import declarative
|
||||
from sqlalchemy import orm
|
||||
|
||||
from barbican.common import exception
|
||||
from barbican.common import utils
|
||||
from barbican.openstack.common import timeutils
|
||||
|
||||
@ -216,6 +217,7 @@ class Secret(BASE, ModelBase):
|
||||
# metadata is retrieved.
|
||||
# See barbican.api.resources.py::SecretsResource.on_get()
|
||||
encrypted_data = orm.relationship("EncryptedDatum", lazy='joined')
|
||||
secret_metadata = orm.relationship("SecretMetadatum", lazy='joined')
|
||||
|
||||
def __init__(self, parsed_request=None):
|
||||
"""Creates secret from a dict."""
|
||||
@ -232,6 +234,9 @@ class Secret(BASE, ModelBase):
|
||||
|
||||
def _do_delete_children(self, session):
|
||||
"""Sub-class hook: delete children relationships."""
|
||||
for datum in self.secret_metadata:
|
||||
datum.delete(session)
|
||||
|
||||
for datum in self.encrypted_data:
|
||||
datum.delete(session)
|
||||
|
||||
@ -240,16 +245,58 @@ class Secret(BASE, ModelBase):
|
||||
|
||||
def _do_extra_dict_fields(self):
|
||||
"""Sub-class hook method: return dict of fields."""
|
||||
return {'secret_id': self.id,
|
||||
'name': self.name or self.id,
|
||||
'expiration': self.expiration,
|
||||
'algorithm': self.algorithm,
|
||||
'bit_length': self.bit_length,
|
||||
'mode': self.mode}
|
||||
fields = {'secret_id': self.id,
|
||||
'name': self.name or self.id,
|
||||
'expiration': self.expiration,
|
||||
'algorithm': self.algorithm,
|
||||
'bit_length': self.bit_length,
|
||||
'mode': self.mode}
|
||||
#TODO(kaitlin.farr) will change implementation to avoid overwriting
|
||||
# existing fields in a future patch
|
||||
for m in self.secret_metadata:
|
||||
metadata_field = m._do_extra_dict_fields()
|
||||
fields.update({metadata_field['key']: metadata_field['value']})
|
||||
return fields
|
||||
|
||||
|
||||
class SecretMetadatum(BASE, ModelBase):
|
||||
"""Represents the metadatum for a single key-value pair for a Secret"""
|
||||
|
||||
__tablename__ = "secret_metadata"
|
||||
|
||||
secret_id = sa.Column(sa.String(36), sa.ForeignKey('secrets.id'),
|
||||
nullable=False)
|
||||
key = sa.Column(sa.String(255), nullable=False)
|
||||
value = sa.Column(sa.String(255), nullable=False)
|
||||
|
||||
def __init__(self, secret, key, value):
|
||||
super(SecretMetadatum, self).__init__()
|
||||
|
||||
msg = ("Must supply non-None {0} argument for SecretMetadatum entry.")
|
||||
|
||||
if secret is None:
|
||||
raise exception.MissingArgumentError(msg.format("secret"))
|
||||
else:
|
||||
self.secret_id = secret.id
|
||||
|
||||
if key is None:
|
||||
raise exception.MissingArgumentError(msg.format("key"))
|
||||
else:
|
||||
self.key = key
|
||||
|
||||
if value is None:
|
||||
raise exception.MissingArgumentError(msg.format("value"))
|
||||
else:
|
||||
self.value = value
|
||||
|
||||
def _do_extra_dict_fields(self):
|
||||
"""Sub-class hook method: return dict of fields."""
|
||||
return {'key': self.key,
|
||||
'value': self.value}
|
||||
|
||||
|
||||
class EncryptedDatum(BASE, ModelBase):
|
||||
"""Represents a the encrypted data for a Secret."""
|
||||
"""Represents the encrypted data for a Secret."""
|
||||
|
||||
__tablename__ = 'encrypted_data'
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user