From 62d181d9256498d643adbce0c8f0438f8b8651d5 Mon Sep 17 00:00:00 2001
From: licanwei
Date: Sun, 5 May 2019 16:24:24 +0800
Subject: [PATCH] Add force field to Audit
Partially Implements: blueprint add-force-field-to-audit
Change-Id: Ia08694d2fb76907ea14e64116af2e722fe930063
---
watcher/api/controllers/v1/audit.py | 6 +++++
.../versions/609bec748f2a_add_force_field.py | 22 +++++++++++++++++++
watcher/db/sqlalchemy/models.py | 1 +
watcher/objects/audit.py | 9 +++++++-
watcher/tests/db/utils.py | 3 ++-
watcher/tests/objects/test_objects.py | 2 +-
6 files changed, 40 insertions(+), 3 deletions(-)
create mode 100644 watcher/db/sqlalchemy/alembic/versions/609bec748f2a_add_force_field.py
diff --git a/watcher/api/controllers/v1/audit.py b/watcher/api/controllers/v1/audit.py
index f31536e9a..3f67f4164 100644
--- a/watcher/api/controllers/v1/audit.py
+++ b/watcher/api/controllers/v1/audit.py
@@ -104,6 +104,8 @@ class AuditPostType(wtypes.Base):
end_time = wtypes.wsattr(datetime.datetime, mandatory=False)
+ force = wtypes.wsattr(bool, mandatory=False)
+
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:
@@ -359,6 +361,10 @@ class Audit(base.APIBase):
end_time = wtypes.wsattr(datetime.datetime, mandatory=False)
"""The end time that stopping continuous audit"""
+ force = wsme.wsattr(bool, mandatory=False, default=False)
+ """Allow Action Plan of this Audit be executed in parallel
+ with other Action Plan"""
+
def __init__(self, **kwargs):
self.fields = []
fields = list(objects.Audit.fields)
diff --git a/watcher/db/sqlalchemy/alembic/versions/609bec748f2a_add_force_field.py b/watcher/db/sqlalchemy/alembic/versions/609bec748f2a_add_force_field.py
new file mode 100644
index 000000000..4cbe606a8
--- /dev/null
+++ b/watcher/db/sqlalchemy/alembic/versions/609bec748f2a_add_force_field.py
@@ -0,0 +1,22 @@
+"""add_force_field
+
+Revision ID: 609bec748f2a
+Revises: 4b16194c56bc
+Create Date: 2019-05-05 14:06:14.249124
+
+"""
+
+# revision identifiers, used by Alembic.
+revision = '609bec748f2a'
+down_revision = '4b16194c56bc'
+
+from alembic import op
+import sqlalchemy as sa
+
+
+def upgrade():
+ op.add_column('audits', sa.Column('force', sa.Boolean, default=False))
+
+
+def downgrade():
+ op.drop_column('audits', 'force')
diff --git a/watcher/db/sqlalchemy/models.py b/watcher/db/sqlalchemy/models.py
index d014b676f..2e602236f 100644
--- a/watcher/db/sqlalchemy/models.py
+++ b/watcher/db/sqlalchemy/models.py
@@ -186,6 +186,7 @@ class Audit(Base):
hostname = Column(String(255), nullable=True)
start_time = Column(DateTime, nullable=True)
end_time = Column(DateTime, nullable=True)
+ force = Column(Boolean, nullable=False)
goal = orm.relationship(Goal, foreign_keys=goal_id, lazy=None)
strategy = orm.relationship(Strategy, foreign_keys=strategy_id, lazy=None)
diff --git a/watcher/objects/audit.py b/watcher/objects/audit.py
index d040a8063..605d49a78 100644
--- a/watcher/objects/audit.py
+++ b/watcher/objects/audit.py
@@ -89,7 +89,8 @@ class Audit(base.WatcherPersistentObject, base.WatcherObject,
# Version 1.4: Added 'name' string field
# Version 1.5: Added 'hostname' field
# Version 1.6: Added 'start_time' and 'end_time' DateTime fields
- VERSION = '1.6'
+ # Version 1.7: Added 'force' boolean field
+ VERSION = '1.7'
dbapi = db_api.get_instance()
@@ -110,6 +111,7 @@ class Audit(base.WatcherPersistentObject, base.WatcherObject,
'hostname': wfields.StringField(nullable=True),
'start_time': wfields.DateTimeField(nullable=True, tzinfo_aware=False),
'end_time': wfields.DateTimeField(nullable=True, tzinfo_aware=False),
+ 'force': wfields.BooleanField(default=False, nullable=False),
'goal': wfields.ObjectField('Goal', nullable=True),
'strategy': wfields.ObjectField('Strategy', nullable=True),
@@ -120,6 +122,11 @@ class Audit(base.WatcherPersistentObject, base.WatcherObject,
'strategy': (objects.Strategy, 'strategy_id'),
}
+ def __init__(self, *args, **kwargs):
+ if 'force' not in kwargs:
+ kwargs['force'] = False
+ super(Audit, self).__init__(*args, **kwargs)
+
# Proxified field so we can keep the previous value after an update
_state = None
_old_state = None
diff --git a/watcher/tests/db/utils.py b/watcher/tests/db/utils.py
index 840007a09..be66195c5 100644
--- a/watcher/tests/db/utils.py
+++ b/watcher/tests/db/utils.py
@@ -98,7 +98,8 @@ def get_test_audit(**kwargs):
'next_run_time': kwargs.get('next_run_time'),
'hostname': kwargs.get('hostname', 'host_1'),
'start_time': kwargs.get('start_time'),
- 'end_time': kwargs.get('end_time')
+ 'end_time': kwargs.get('end_time'),
+ 'force': kwargs.get('force', False)
}
# ObjectField doesn't allow None nor dict, so if we want to simulate a
diff --git a/watcher/tests/objects/test_objects.py b/watcher/tests/objects/test_objects.py
index 237d483d5..5b05b05de 100644
--- a/watcher/tests/objects/test_objects.py
+++ b/watcher/tests/objects/test_objects.py
@@ -412,7 +412,7 @@ expected_object_fingerprints = {
'Goal': '1.0-93881622db05e7b67a65ca885b4a022e',
'Strategy': '1.1-73f164491bdd4c034f48083a51bdeb7b',
'AuditTemplate': '1.1-b291973ffc5efa2c61b24fe34fdccc0b',
- 'Audit': '1.6-fc4abd6f133a8b419e42e05729ed0f8b',
+ 'Audit': '1.7-19bc991c0b048263df021a36c8624f4d',
'ActionPlan': '2.2-3331270cb3666c93408934826d03c08d',
'Action': '2.0-1dd4959a7e7ac30c62ef170fe08dd935',
'EfficacyIndicator': '1.0-655b71234a82bc7478aff964639c4bb0',