Removed deadline, version, extra & host_aggregate

As we are about to version the Watcher objects, we need to make sure
that upcoming model/object modifications are additive in order to
avoid having to bump the major version of the API. Therefore,
this changeset removes 4 unused DB fields that were exposed in their
associated Watcher objects (i.e. AuditTemplate and Audit).

Change-Id: Ifb0783f21cd66db16b31e3c8e376fc9d6c07dea3
Partially-Implements: blueprint watcher-versioned-objects
This commit is contained in:
Vincent Françoise
2016-10-03 14:38:49 +02:00
parent 750e6bf213
commit ed95d621f4
21 changed files with 50 additions and 184 deletions

View File

@@ -54,16 +54,12 @@ class AuditPostType(wtypes.Base):
audit_template_uuid = wtypes.wsattr(types.uuid, mandatory=False)
scope = wtypes.wsattr(types.jsontype, readonly=True)
goal = wtypes.wsattr(wtypes.text, mandatory=False)
strategy = wtypes.wsattr(wtypes.text, mandatory=False)
audit_type = wtypes.wsattr(wtypes.text, mandatory=True)
deadline = wtypes.wsattr(datetime.datetime, mandatory=False)
state = wsme.wsattr(wtypes.text, readonly=True,
default=objects.audit.State.PENDING)
@@ -71,6 +67,8 @@ class AuditPostType(wtypes.Base):
default={})
interval = wsme.wsattr(int, mandatory=False)
scope = wtypes.wsattr(types.jsontype, readonly=True)
def as_audit(self, context):
audit_type_values = [val.value for val in objects.audit.AuditType]
if self.audit_type not in audit_type_values:
@@ -81,7 +79,7 @@ class AuditPostType(wtypes.Base):
raise exception.AuditIntervalNotAllowed(audit_type=self.audit_type)
if (self.audit_type == objects.audit.AuditType.CONTINUOUS.value and
self.interval in (wtypes.Unset, None)):
self.interval in (wtypes.Unset, None)):
raise exception.AuditIntervalNotSpecified(
audit_type=self.audit_type)
@@ -113,7 +111,6 @@ class AuditPostType(wtypes.Base):
pass
return Audit(
audit_type=self.audit_type,
deadline=self.deadline,
parameters=self.parameters,
goal_id=self.goal,
strategy_id=self.strategy,
@@ -229,9 +226,6 @@ class Audit(base.APIBase):
audit_type = wtypes.text
"""Type of this audit"""
deadline = datetime.datetime
"""deadline of the audit"""
state = wtypes.text
"""This audit state"""
@@ -291,8 +285,8 @@ class Audit(base.APIBase):
@staticmethod
def _convert_with_links(audit, url, expand=True):
if not expand:
audit.unset_fields_except(['uuid', 'audit_type', 'deadline',
'state', 'goal_uuid', 'interval',
audit.unset_fields_except(['uuid', 'audit_type', 'state',
'goal_uuid', 'interval', 'scope',
'strategy_uuid', 'goal_name',
'strategy_name'])
@@ -315,7 +309,6 @@ class Audit(base.APIBase):
sample = cls(uuid='27e3153e-d5bf-4b7e-b517-fb518e17f34c',
audit_type='ONESHOT',
state='PENDING',
deadline=None,
created_at=datetime.datetime.utcnow(),
deleted_at=None,
updated_at=datetime.datetime.utcnow(),
@@ -324,6 +317,7 @@ class Audit(base.APIBase):
sample.goal_id = '7ae81bb3-dec3-4289-8d6c-da80bd8001ae'
sample.strategy_id = '7ae81bb3-dec3-4289-8d6c-da80bd8001ff'
return cls._convert_with_links(sample, 'http://localhost:9322', expand)
@@ -423,16 +417,14 @@ class AuditsController(rest.RestController):
@wsme_pecan.wsexpose(AuditCollection, types.uuid, int, wtypes.text,
wtypes.text, wtypes.text, wtypes.text, int)
def get_all(self, marker=None, limit=None,
sort_key='id', sort_dir='asc', goal=None,
strategy=None):
def get_all(self, marker=None, limit=None, sort_key='id', sort_dir='asc',
goal=None, strategy=None):
"""Retrieve a list of audits.
:param marker: pagination marker for large data sets.
:param limit: maximum number of resources to return in a single result.
:param sort_key: column to sort results by. Default: id.
:param sort_dir: direction to sort. "asc" or "desc". Default: asc.
id.
:param goal: goal UUID or name to filter by
:param strategy: strategy UUID or name to filter by
"""

View File

@@ -41,11 +41,6 @@ settings related to the level of automation for the
A flag will indicate whether the :ref:`Action Plan <action_plan_definition>`
will be launched automatically or will need a manual confirmation from the
:ref:`Administrator <administrator_definition>`.
Last but not least, an :ref:`Audit Template <audit_template_definition>` may
contain a list of extra parameters related to the
:ref:`Strategy <strategy_definition>` configuration. These parameters can be
provided as a list of key-value pairs.
"""
import datetime
@@ -79,21 +74,12 @@ class AuditTemplatePostType(wtypes.Base):
description = wtypes.wsattr(wtypes.text, mandatory=False)
"""Short description of this audit template"""
deadline = wsme.wsattr(datetime.datetime, mandatory=False)
"""deadline of the audit template"""
extra = wtypes.wsattr({wtypes.text: types.jsontype}, mandatory=False)
"""The metadata of the audit template"""
goal = wtypes.wsattr(wtypes.text, mandatory=True)
"""Goal UUID or name of the audit template"""
strategy = wtypes.wsattr(wtypes.text, mandatory=False)
"""Strategy UUID or name of the audit template"""
version = wtypes.text
"""Internal version of the audit template"""
scope = wtypes.wsattr(types.jsontype, mandatory=False, default=[])
"""Audit Scope"""
@@ -101,13 +87,10 @@ class AuditTemplatePostType(wtypes.Base):
return AuditTemplate(
name=self.name,
description=self.description,
deadline=self.deadline,
extra=self.extra,
goal_id=self.goal, # Dirty trick ...
goal=self.goal,
strategy_id=self.strategy, # Dirty trick ...
strategy_uuid=self.strategy,
version=self.version,
scope=self.scope,
)
@@ -308,15 +291,9 @@ class AuditTemplate(base.APIBase):
name = wtypes.text
"""Name of this audit template"""
description = wtypes.text
description = wtypes.wsattr(wtypes.text, mandatory=False)
"""Short description of this audit template"""
deadline = datetime.datetime
"""deadline of the audit template"""
extra = {wtypes.text: types.jsontype}
"""The metadata of the audit template"""
goal_uuid = wsme.wsproperty(
wtypes.text, _get_goal_uuid, _set_goal_uuid, mandatory=True)
"""Goal UUID the audit template refers to"""
@@ -333,9 +310,6 @@ class AuditTemplate(base.APIBase):
wtypes.text, _get_strategy_name, _set_strategy_name, mandatory=False)
"""The name of the strategy this audit template refers to"""
version = wtypes.text
"""Internal version of the audit template"""
audits = wsme.wsattr([link.Link], readonly=True)
"""Links to the collection of audits contained in this audit template"""
@@ -378,7 +352,7 @@ class AuditTemplate(base.APIBase):
if not expand:
audit_template.unset_fields_except(
['uuid', 'name', 'goal_uuid', 'goal_name',
'strategy_uuid', 'strategy_name'])
'scope', 'strategy_uuid', 'strategy_name'])
# The numeric ID should not be exposed to
# the user, it's internal only.
@@ -407,7 +381,6 @@ class AuditTemplate(base.APIBase):
description='Description of my audit template',
goal_uuid='83e44733-b640-40e2-8d8a-7dd3be7134e6',
strategy_uuid='367d826e-b6a4-4b70-bc44-c3f6fe1c9986',
extra={'automatic': True},
created_at=datetime.datetime.utcnow(),
deleted_at=None,
updated_at=datetime.datetime.utcnow(),

View File

@@ -275,7 +275,6 @@ class BaseConnection(object):
'name': 'example',
'description': 'free text description'
'goal': 'DUMMY'
'extra': {'automatic': True}
}
:returns: An audit template.
:raises: :py:class:`~.AuditTemplateAlreadyExists`
@@ -375,7 +374,6 @@ class BaseConnection(object):
{
'uuid': utils.generate_uuid(),
'type': 'ONESHOT',
'deadline': None
}
:returns: An audit.
:raises: :py:class:`~.AuditAlreadyExists`

View File

@@ -165,8 +165,6 @@ class AuditTemplate(Base):
description = Column(String(255), nullable=True)
goal_id = Column(Integer, ForeignKey('goals.id'), nullable=False)
strategy_id = Column(Integer, ForeignKey('strategies.id'), nullable=True)
extra = Column(JSONEncodedDict)
version = Column(String(15), nullable=True)
scope = Column(JSONEncodedList)
goal = orm.relationship(Goal, foreign_keys=goal_id, lazy=None)
@@ -185,7 +183,6 @@ class Audit(Base):
uuid = Column(String(36))
audit_type = Column(String(20))
state = Column(String(20), nullable=True)
deadline = Column(DateTime, nullable=True)
parameters = Column(JSONEncodedDict, nullable=True)
interval = Column(Integer, nullable=True)
goal_id = Column(Integer, ForeignKey('goals.id'), nullable=False)

View File

@@ -83,7 +83,6 @@ class Audit(base.WatcherObject):
'uuid': obj_utils.str_or_none,
'audit_type': obj_utils.str_or_none,
'state': obj_utils.str_or_none,
'deadline': obj_utils.datetime_or_str_or_none,
'parameters': obj_utils.dict_or_none,
'interval': obj_utils.int_or_none,
'goal_id': obj_utils.int_or_none,

View File

@@ -67,8 +67,6 @@ class AuditTemplate(base.WatcherObject):
'description': obj_utils.str_or_none,
'goal_id': obj_utils.int_or_none,
'strategy_id': obj_utils.int_or_none,
'extra': obj_utils.dict_or_none,
'version': obj_utils.str_or_none,
'scope': obj_utils.list_or_none,
}

View File

@@ -87,7 +87,7 @@ class TestListAudit(api_base.FunctionalTest):
self.assertEqual([], response['audits'])
def _assert_audit_fields(self, audit):
audit_fields = ['audit_type', 'deadline', 'state', 'goal_uuid',
audit_fields = ['audit_type', 'scope', 'state', 'goal_uuid',
'strategy_uuid']
for field in audit_fields:
self.assertIn(field, audit)

View File

@@ -1,52 +0,0 @@
# 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.
"""Tests for custom SQLAlchemy types via Magnum DB."""
from oslo_db import exception as db_exc
from watcher.common import utils as w_utils
from watcher.db import api as dbapi
import watcher.db.sqlalchemy.api as sa_api
from watcher.db.sqlalchemy import models
from watcher.tests.db import base
class SqlAlchemyCustomTypesTestCase(base.DbTestCase):
def setUp(self):
super(SqlAlchemyCustomTypesTestCase, self).setUp()
self.dbapi = dbapi.get_instance()
def test_JSONEncodedDict_default_value(self):
# Create audit_template w/o extra
audit_template1_id = w_utils.generate_uuid()
self.dbapi.create_audit_template({'uuid': audit_template1_id,
'goal_id': "DUMMY"})
audit_template1 = sa_api.model_query(models.AuditTemplate) \
.filter_by(uuid=audit_template1_id).one()
self.assertEqual({}, audit_template1.extra)
def test_JSONEncodedDict_extra_value(self):
# Create audit_template with extra
audit_template2_id = w_utils.generate_uuid()
self.dbapi.create_audit_template({'uuid': audit_template2_id,
'goal_id': "DUMMY",
'extra': {'bar': 'foo'}})
audit_template2 = sa_api.model_query(models.AuditTemplate) \
.filter_by(uuid=audit_template2_id).one()
self.assertEqual('foo', audit_template2.extra['bar'])
def test_JSONEncodedDict_type_check(self):
self.assertRaises(db_exc.DBError,
self.dbapi.create_audit_template,
{'extra': ['this is not a dict']})

View File

@@ -278,7 +278,6 @@ class DbActionPlanTestCase(base.DbTestCase):
id=2,
audit_type='ONESHOT',
uuid=w_utils.generate_uuid(),
deadline=None,
state=ap_objects.State.ONGOING)
action_plan1 = self._create_test_action_plan(
id=1,

View File

@@ -291,13 +291,11 @@ class DbAuditTestCase(base.DbTestCase):
id=1,
audit_type=objects.audit.AuditType.ONESHOT.value,
uuid=w_utils.generate_uuid(),
deadline=None,
state=objects.audit.State.ONGOING)
audit2 = self._create_test_audit(
id=2,
audit_type='CONTINUOUS',
uuid=w_utils.generate_uuid(),
deadline=None,
state=objects.audit.State.PENDING)
res = self.dbapi.get_audit_list(

View File

@@ -273,15 +273,21 @@ class DbAuditTemplateTestCase(base.DbTestCase):
uuid=w_utils.generate_uuid(),
name='My Audit Template 1',
description='Description of my audit template 1',
goal='DUMMY',
extra={'automatic': True})
goal='DUMMY')
audit_template2 = self._create_test_audit_template(
id=2,
uuid=w_utils.generate_uuid(),
name='My Audit Template 2',
description='Description of my audit template 2',
goal='DUMMY',
extra={'automatic': True})
goal='DUMMY')
res = self.dbapi.get_audit_template_list(
self.context, filters={'name': 'My Audit Template 1'})
self.assertEqual([audit_template1['id']], [r.id for r in res])
res = self.dbapi.get_audit_template_list(
self.context, filters={'name': 'Does not exist'})
self.assertEqual([], [r.id for r in res])
res = self.dbapi.get_audit_template_list(
self.context,

View File

@@ -28,12 +28,10 @@ def get_test_audit_template(**kwargs):
'strategy_id': kwargs.get('strategy_id', None),
'name': kwargs.get('name', 'My Audit Template'),
'description': kwargs.get('description', 'Desc. Of My Audit Template'),
'extra': kwargs.get('extra', {'automatic': False}),
'version': kwargs.get('version', 'v1'),
'scope': kwargs.get('scope', []),
'created_at': kwargs.get('created_at'),
'updated_at': kwargs.get('updated_at'),
'deleted_at': kwargs.get('deleted_at'),
'scope': kwargs.get('scope', []),
}
@@ -59,7 +57,6 @@ def get_test_audit(**kwargs):
'uuid': kwargs.get('uuid', '10a47dd1-4874-4298-91cf-eff046dbdb8d'),
'audit_type': kwargs.get('audit_type', 'ONESHOT'),
'state': kwargs.get('state'),
'deadline': kwargs.get('deadline'),
'created_at': kwargs.get('created_at'),
'updated_at': kwargs.get('updated_at'),
'deleted_at': kwargs.get('deleted_at'),