Adds audit support for VIM, VNFD and VNF

implements blueprint: audit-support

Co-Authored-By: Vishwanath Jayaraman <vishwanathj@hotmail.com>

Change-Id: I8e6c4d6d47130c447c9a77e654d2dfad5d23ae7e
This commit is contained in:
Kanagaraj Manickam 2016-06-06 10:07:52 +05:30 committed by vish
parent 492796465f
commit 8ca9c9cfea
9 changed files with 112 additions and 8 deletions

View File

@ -0,0 +1,37 @@
# Copyright 2016 OpenStack Foundation
#
# 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.
#
"""audit support
Revision ID: 2ff0a0e360f1
Revises: 22f5385a3d50
Create Date: 2016-06-02 15:14:31.888078
"""
# revision identifiers, used by Alembic.
revision = '2ff0a0e360f1'
down_revision = '22f5385a3d50'
from alembic import op
import sqlalchemy as sa
def upgrade(active_plugins=None, options=None):
for table in ['vims', 'vnf', 'vnfd']:
op.add_column(table,
sa.Column('created_at', sa.DateTime(), nullable=True))
op.add_column(table,
sa.Column('updated_at', sa.DateTime(), nullable=True))

View File

@ -1 +1,2 @@
22f5385a3d50
2ff0a0e360f1

View File

@ -13,6 +13,7 @@
# License for the specific language governing permissions and limitations
# under the License.
from oslo_utils import timeutils
from oslo_utils import uuidutils
import sqlalchemy as sa
@ -31,3 +32,11 @@ class HasId(object):
id = sa.Column(types.Uuid,
primary_key=True,
default=uuidutils.generate_uuid)
class Audit(object):
"""Helps to add time stamp for create, update and delete actions. """
created_at = sa.Column(sa.DateTime,
default=lambda: timeutils.utcnow())
updated_at = sa.Column(sa.DateTime)

View File

@ -18,6 +18,7 @@ import uuid
from oslo_db import exception
from oslo_utils import strutils
from oslo_utils import timeutils
import sqlalchemy as sa
from sqlalchemy import orm
from sqlalchemy.orm import exc as orm_exc
@ -33,11 +34,16 @@ from tacker import manager
VIM_ATTRIBUTES = ('id', 'type', 'tenant_id', 'name', 'description',
'placement_attr', 'shared', 'is_default', 'status')
'placement_attr', 'shared', 'is_default',
'created_at', 'updated_at', 'status')
VIM_AUTH_ATTRIBUTES = ('auth_url', 'vim_project', 'password', 'auth_cred')
class Vim(model_base.BASE, models_v1.HasId, models_v1.HasTenant):
class Vim(model_base.BASE,
models_v1.HasId,
models_v1.HasTenant,
models_v1.Audit):
type = sa.Column(sa.String(64), nullable=False)
name = sa.Column(sa.String(255), nullable=False)
description = sa.Column(sa.Text, nullable=True)
@ -151,9 +157,9 @@ class NfvoPluginDb(nfvo.NFVOPluginBase, db_base.CommonDbMixin):
vim_cred = vim['auth_cred']
vim_project = vim['vim_project']
is_default = vim.get('is_default')
vim_db = self._get_resource(context, Vim, vim_id)
try:
if is_default:
vim_db = self._get_resource(context, Vim, vim_id)
vim_db.update({'is_default': is_default})
vim_auth_db = (self._model_query(context, VimAuth).filter(
VimAuth.vim_id == vim_id).with_lockmode('update').one())
@ -162,6 +168,8 @@ class NfvoPluginDb(nfvo.NFVOPluginBase, db_base.CommonDbMixin):
vim_auth_db.update({'auth_cred': vim_cred, 'password':
vim_cred.pop('password'), 'vim_project':
vim_project})
vim_db.update({'updated_at': timeutils.utcnow()})
return self.get_vim(context, vim_id)
def update_vim_status(self, context, vim_id, status):

View File

@ -17,6 +17,8 @@
import uuid
from oslo_log import log as logging
from oslo_utils import timeutils
import sqlalchemy as sa
from sqlalchemy import orm
from sqlalchemy.orm import exc as orm_exc
@ -42,7 +44,8 @@ CREATE_STATES = (constants.PENDING_CREATE, constants.DEAD)
###########################################################################
# db tables
class VNFD(model_base.BASE, models_v1.HasId, models_v1.HasTenant):
class VNFD(model_base.BASE, models_v1.HasId, models_v1.HasTenant,
models_v1.Audit):
"""Represents VNFD to create VNF."""
__tablename__ = 'vnfd'
@ -92,7 +95,8 @@ class VNFDAttribute(model_base.BASE, models_v1.HasId):
value = sa.Column(sa.TEXT(65535), nullable=True)
class VNF(model_base.BASE, models_v1.HasId, models_v1.HasTenant):
class VNF(model_base.BASE, models_v1.HasId, models_v1.HasTenant,
models_v1.Audit):
"""Represents devices that hosts services.
Here the term, 'VM', is intentionally avoided because it can be
@ -181,7 +185,8 @@ class VNFMPluginDb(vnfm.VNFMPluginBase, db_base.CommonDbMixin):
template.service_types)
}
key_list = ('id', 'tenant_id', 'name', 'description',
'infra_driver', 'mgmt_driver')
'infra_driver', 'mgmt_driver',
'created_at', 'updated_at')
res.update((key, template[key]) for key in key_list)
return self._fields(res, fields)
@ -198,7 +203,7 @@ class VNFMPluginDb(vnfm.VNFMPluginBase, db_base.CommonDbMixin):
}
key_list = ('id', 'tenant_id', 'name', 'description', 'instance_id',
'vim_id', 'placement_attr', 'vnfd_id', 'status',
'mgmt_url', 'error_reason')
'mgmt_url', 'error_reason', 'created_at', 'updated_at')
res.update((key, device_db[key]) for key in key_list)
return self._fields(res, fields)
@ -269,6 +274,7 @@ class VNFMPluginDb(vnfm.VNFMPluginBase, db_base.CommonDbMixin):
template_db = self._get_resource(context, VNFD,
device_template_id)
template_db.update(device_template['device_template'])
template_db.update({'updated_at': timeutils.utcnow()})
return self._make_template_dict(template_db)
def delete_device_template(self, context, device_template_id):
@ -435,6 +441,11 @@ class VNFMPluginDb(vnfm.VNFMPluginBase, db_base.CommonDbMixin):
filter(VNF.id == device_id).
filter(VNF.status == constants.PENDING_UPDATE).
update({'status': new_status}))
(self._model_query(context, VNF).
filter(VNF.id == device_id).
filter(VNF.status == constants.PENDING_UPDATE).
update({'status': new_status,
'updated_at': timeutils.utcnow()}))
dev_attrs = new_device_dict.get('attributes', {})
(context.session.query(VNFAttribute).

View File

@ -160,6 +160,16 @@ RESOURCE_ATTRIBUTE_MAP = {
'is_visible': True,
'default': False
},
'created_at': {
'allow_post': False,
'allow_put': False,
'is_visible': True,
},
'updated_at': {
'allow_post': False,
'allow_put': False,
'is_visible': True,
},
}
}

View File

@ -224,6 +224,16 @@ RESOURCE_ATTRIBUTE_MAP = {
'is_visible': True,
'default': None,
},
'created_at': {
'allow_post': False,
'allow_put': False,
'is_visible': True,
},
'updated_at': {
'allow_post': False,
'allow_put': False,
'is_visible': True,
},
},
'vnfs': {
@ -303,6 +313,16 @@ RESOURCE_ATTRIBUTE_MAP = {
'allow_put': False,
'is_visible': True,
},
'created_at': {
'allow_post': False,
'allow_put': False,
'is_visible': True,
},
'updated_at': {
'allow_post': False,
'allow_put': False,
'is_visible': True,
},
},
}

View File

@ -88,6 +88,8 @@ class TestNfvoPlugin(db_base.SqlTestCase):
self.assertEqual(SECRET_PASSWORD, res['auth_cred']['password'])
self.assertIn('id', res)
self.assertIn('placement_attr', res)
self.assertIn('created_at', res)
self.assertIn('updated_at', res)
def test_delete_vim(self):
self._insert_dummy_vim()
@ -118,3 +120,4 @@ class TestNfvoPlugin(db_base.SqlTestCase):
self.assertEqual(vim_project, res['vim_project'])
self.assertEqual(vim_auth_username, res['auth_cred']['username'])
self.assertEqual(SECRET_PASSWORD, res['auth_cred']['password'])
self.assertIn('updated_at', res)

View File

@ -152,6 +152,8 @@ class TestVNFMPlugin(db_base.SqlTestCase):
self.assertIn('id', result)
self.assertIn('service_types', result)
self.assertIn('attributes', result)
self.assertIn('created_at', result)
self.assertIn('updated_at', result)
self._device_manager.invoke.assert_called_once_with(
mock.ANY,
mock.ANY,
@ -183,6 +185,8 @@ class TestVNFMPlugin(db_base.SqlTestCase):
self.assertIn('status', result)
self.assertIn('attributes', result)
self.assertIn('mgmt_url', result)
self.assertIn('created_at', result)
self.assertIn('updated_at', result)
self._device_manager.invoke.assert_called_with(mock.ANY, mock.ANY,
plugin=mock.ANY,
context=mock.ANY,
@ -217,5 +221,6 @@ class TestVNFMPlugin(db_base.SqlTestCase):
self.assertIn('status', result)
self.assertIn('attributes', result)
self.assertIn('mgmt_url', result)
self.assertIn('updated_at', result)
self._pool.spawn_n.assert_called_once_with(mock.ANY, mock.ANY,
mock.ANY, mock.ANY)