0
0
Fork 0
mirror of https://github.com/alerta/alerta.git synced 2025-03-13 04:53:16 +00:00

Add auditing info to blackout model ()

* Add auditing info to blackout model

* Add tests for extended blackout info
This commit is contained in:
Nick Satterly 2018-08-23 22:44:22 +02:00 committed by GitHub
parent e0bce26a58
commit d358fdf025
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 91 additions and 23 deletions

View file

@ -23,7 +23,7 @@ last to support Python 2.7. Only critical bug fixes will be backported to Releas
The only mandatory dependency is MongoDB or PostgreSQL. Everything else is optional.
- Postgres version 9.6 or better
- Postgres version 9.5 or better
- MongoDB version 3.x
Installation

View file

@ -20,22 +20,15 @@ class Backend(Database):
self.uri = uri
self.dbname = dbname
db = self.connect()
self._create_indexes(db)
def connect(self):
self.client = MongoClient(self.uri)
if self.dbname:
db = self.client[self.dbname]
return self.client[self.dbname]
else:
db = self.client.get_default_database()
# create unique indexes
try:
self._create_indexes(db)
except Exception as e:
if current_app.config['MONGO_RAISE_ON_ERROR']:
raise
current_app.logger.warning(e)
return db
return self.client.get_default_database()
@staticmethod
def _create_indexes(db):
@ -709,7 +702,10 @@ class Backend(Database):
"environment": blackout.environment,
"startTime": blackout.start_time,
"endTime": blackout.end_time,
"duration": blackout.duration
"duration": blackout.duration,
"user": blackout.user,
"createTime": blackout.create_time,
"text": blackout.text,
}
if blackout.service:
data["service"] = blackout.service

View file

@ -501,8 +501,10 @@ class Backend(Database):
def create_blackout(self, blackout):
insert = """
INSERT INTO blackouts (id, priority, environment, service, resource, event, "group", tags, customer, start_time, end_time, duration)
VALUES (%(id)s, %(priority)s, %(environment)s, %(service)s, %(resource)s, %(event)s, %(group)s, %(tags)s, %(customer)s, %(start_time)s, %(end_time)s, %(duration)s)
INSERT INTO blackouts (id, priority, environment, service, resource, event, "group", tags,
customer, start_time, end_time, duration, "user", create_time, text)
VALUES (%(id)s, %(priority)s, %(environment)s, %(service)s, %(resource)s, %(event)s, %(group)s, %(tags)s,
%(customer)s, %(start_time)s, %(end_time)s, %(duration)s, %(user)s, %(create_time)s, %(text)s)
RETURNING *
"""
return self._insert(insert, vars(blackout))

View file

@ -43,7 +43,12 @@ class Database(Base):
cls = load_backend(backend)
self.__class__ = type('DatabaseImpl', (cls.Backend, Database), {})
self.create_engine(app, uri=app.config['DATABASE_URL'], dbname=app.config['DATABASE_NAME'])
try:
self.create_engine(app, uri=app.config['DATABASE_URL'], dbname=app.config['DATABASE_NAME'])
except Exception as e:
if app.config['DATABASE_RAISE_ON_ERROR']:
raise
app.logger.warning(e)
app.before_request(self.get_db)
app.teardown_request(self.teardown_db)

View file

@ -35,6 +35,10 @@ class Blackout(object):
self.end_time = end_time
self.duration = duration
self.user = kwargs.get('user', None)
self.create_time = kwargs['create_time'] if 'create_time' in kwargs else datetime.utcnow()
self.text = kwargs.get('text', None)
if self.environment:
self.priority = 1
if self.resource and not self.event:
@ -78,7 +82,9 @@ class Blackout(object):
customer=json.get('customer', None),
start_time=DateTime.parse(json.get('startTime')),
end_time=DateTime.parse(json.get('endTime')),
duration=json.get('duration', None)
duration=json.get('duration', None),
user=json.get('user', None),
text=json.get('text', None)
)
@property
@ -98,7 +104,10 @@ class Blackout(object):
'endTime': self.end_time,
'duration': self.duration,
'status': self.status,
'remaining': self.remaining
'remaining': self.remaining,
'user': self.user,
'createTime': self.create_time,
'text': self.text
}
def __repr__(self):
@ -141,7 +150,10 @@ class Blackout(object):
customer=doc.get('customer', None),
start_time=doc.get('startTime', None),
end_time=doc.get('endTime', None),
duration=doc.get('duration', None)
duration=doc.get('duration', None),
user=doc.get('user', None),
create_time=doc.get('createTime', None),
text=doc.get('text', None)
)
@classmethod
@ -158,7 +170,10 @@ class Blackout(object):
customer=rec.customer,
start_time=rec.start_time,
end_time=rec.end_time,
duration=rec.duration
duration=rec.duration,
user=rec.user,
create_time=rec.create_time,
text=rec.text
)
@classmethod

View file

@ -35,6 +35,7 @@ POSTGRES_DB = None
DATABASE_URL = MONGO_URI # default: MongoDB
DATABASE_NAME = MONGO_DATABASE or POSTGRES_DB
DATABASE_RAISE_ON_ERROR = MONGO_RAISE_ON_ERROR # True - terminate, False - ignore and continue
AUTH_REQUIRED = False
ADMIN_USERS = [] # type: List[str]

View file

@ -62,6 +62,33 @@ CREATE TABLE IF NOT EXISTS blackouts (
duration integer
);
-- Support for "IF NOT EXISTS" added to "ADD COLUMN" in Postgres 9.6
-- ALTER TABLE blackouts
-- ADD COLUMN IF NOT EXISTS "user" text,
-- ADD COLUMN IF NOT EXISTS create_time timestamp without time zone,
-- ADD COLUMN IF NOT EXISTS text text;
DO $$
BEGIN
ALTER TABLE blackouts ADD COLUMN "user" text;
EXCEPTION
WHEN duplicate_column THEN RAISE NOTICE 'column "user" already exists in blackouts.';
END$$;
DO $$
BEGIN
ALTER TABLE blackouts ADD COLUMN create_time timestamp without time zone;
EXCEPTION
WHEN duplicate_column THEN RAISE NOTICE 'column create_time already exists in blackouts.';
END$$;
DO $$
BEGIN
ALTER TABLE blackouts ADD COLUMN text text;
EXCEPTION
WHEN duplicate_column THEN RAISE NOTICE 'column text already exists in blackouts.';
END$$;
CREATE TABLE IF NOT EXISTS customers (
id text PRIMARY KEY,

View file

@ -20,6 +20,11 @@ def create_blackout():
except Exception as e:
raise ApiError(str(e), 400)
if 'admin' in g.scopes or 'admin:blackouts' in g.scopes:
blackout.user = blackout.user or g.user
else:
blackout.user = g.user
blackout.customer = assign_customer(wanted=blackout.customer, permission='admin:blackouts')
try:

View file

@ -1,11 +1,13 @@
import json
import unittest
from datetime import datetime
from alerta.app import create_app, db, plugins
from alerta.exceptions import BlackoutPeriod
from alerta.models.key import ApiKey
from alerta.plugins import PluginBase
from alerta.utils.format import DateTime
class BlackoutsTestCase(unittest.TestCase):
@ -32,12 +34,12 @@ class BlackoutsTestCase(unittest.TestCase):
with self.app.test_request_context('/'):
self.app.preprocess_request()
self.admin_api_key = ApiKey(
user='admin',
user='admin@alerta.io',
scopes=['admin', 'read', 'write'],
text='demo-key'
)
self.customer_api_key = ApiKey(
user='admin',
user='admin@alerta.io',
scopes=['admin', 'read', 'write'],
text='demo-key',
customer='Foo'
@ -197,6 +199,21 @@ class BlackoutsTestCase(unittest.TestCase):
data = json.loads(response.data.decode('utf-8'))
self.assertEqual(data['alert']['status'], 'closed')
def test_user_info(self):
self.headers = {
'Authorization': 'Key %s' % self.admin_api_key.key,
'Content-type': 'application/json'
}
# create new blackout
response = self.client.post('/blackout', data=json.dumps({"environment": "Production", "service": ["Network"], "text": "administratively down"}), headers=self.headers)
self.assertEqual(response.status_code, 201)
data = json.loads(response.data.decode('utf-8'))
self.assertEqual(data['blackout']['user'], 'admin@alerta.io')
self.assertIsInstance(DateTime.parse(data['blackout']['createTime']), datetime)
self.assertEqual(data['blackout']['text'], 'administratively down')
class SuppressionBlackout(PluginBase):