Feature 10339 - Enhanced Alarm Mgmt. (SOL005 FM Interface)
[osm/POL.git] / osm_policy_module / tests / integration / test_policy_agent.py
1 # -*- coding: utf-8 -*-
2
3 # Copyright 2018 Whitestack, LLC
4 # *************************************************************
5
6 # This file is part of OSM Monitoring module
7 # All Rights Reserved to Whitestack, LLC
8
9 # Licensed under the Apache License, Version 2.0 (the "License"); you may
10 # not use this file except in compliance with the License. You may obtain
11 # a copy of the License at
12
13 # http://www.apache.org/licenses/LICENSE-2.0
14
15 # Unless required by applicable law or agreed to in writing, software
16 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
17 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
18 # License for the specific language governing permissions and limitations
19 # under the License.
20
21 # For those usages not covered by the Apache License, Version 2.0 please
22 # contact: bdiaz@whitestack.com or glavado@whitestack.com
23 ##
24 import asyncio
25 import logging
26 import os
27 import sys
28 import unittest
29 import uuid
30 from unittest.mock import patch, Mock
31
32 from kafka import KafkaProducer
33 from osm_common.dbmongo import DbMongo
34 from playhouse.db_url import connect
35
36 from osm_policy_module.common.common_db_client import CommonDbClient
37 from osm_policy_module.common.mon_client import MonClient
38 from osm_policy_module.core import database
39 from osm_policy_module.core.agent import PolicyModuleAgent
40 from osm_policy_module.core.config import Config
41 from osm_policy_module.core.database import (
42 ScalingGroup,
43 ScalingAlarm,
44 ScalingPolicy,
45 ScalingCriteria,
46 VnfAlarm,
47 AlarmAction,
48 )
49
50 log = logging.getLogger()
51 log.level = logging.INFO
52 stream_handler = logging.StreamHandler(sys.stdout)
53 log.addHandler(stream_handler)
54
55 nsr_record_mock = {
56 "_id": "87776f33-b67c-417a-8119-cb08e4098951",
57 "crete-time": 1535392482.0044956,
58 "operational-status": "running",
59 "ssh-authorized-key": None,
60 "name-ref": "cirros_ns",
61 "nsd": {
62 "_id": "d7c8bd3c-eb39-4514-8847-19f01345524f",
63 "_admin": {
64 "created": 1535392246.499733,
65 "userDefinedData": {},
66 "usageSate": "NOT_IN_USE",
67 "storage": {
68 "zipfile": "package.tar.gz",
69 "fs": "local",
70 "path": "/app/storage/",
71 "folder": "d7c8bd3c-eb39-4514-8847-19f01345524f",
72 "pkg-dir": "cirros_nsd",
73 "descriptor": "cirros_nsd/cirros_vdu_scaling_nsd.yaml",
74 },
75 "onboardingState": "ONBOARDED",
76 "modified": 1535392246.499733,
77 "projects_read": ["admin"],
78 "operationalState": "ENABLED",
79 "projects_write": ["admin"],
80 },
81 "id": "cirros_vdu_scaling_ns",
82 "name": "cirros_vdu_scaling_ns",
83 "description": "Simple NS example with a cirros_vdu_scaling_vnf",
84 "designer": "OSM",
85 "version": "1.0",
86 "vnfd-id": ["cirros_vdu_scaling_vnf"],
87 "df": [
88 {
89 "id": "default-df",
90 "vnf-profile": [
91 {
92 "id": "1",
93 "vnfd-id": "cirros_vdu_scaling_vnf",
94 "virtual-link-connectivity": [
95 {
96 "virtual-link-profile-id": "cirros_nsd_vld1",
97 "constituent-cpd-id": [
98 {
99 "constituent-base-element-id": "1",
100 "constituent-cpd-id": "eth0-ext",
101 }
102 ],
103 }
104 ],
105 },
106 {
107 "id": "2",
108 "vnfd-id": "cirros_vdu_scaling_vnf",
109 "virtual-link-connectivity": [
110 {
111 "virtual-link-profile-id": "cirros_nsd_vld1",
112 "constituent-cpd-id": [
113 {
114 "constituent-base-element-id": "2",
115 "constituent-cpd-id": "eth0-ext",
116 }
117 ],
118 }
119 ],
120 },
121 ],
122 }
123 ],
124 "virtual-link-desc": [{"id": "cirros_nsd_vld1", "mgmt-network": "true"}],
125 },
126 "id": "87776f33-b67c-417a-8119-cb08e4098951",
127 "config-status": "configured",
128 "operational-events": [],
129 "_admin": {
130 "created": 1535392482.0084584,
131 "projects_read": ["admin"],
132 "nsState": "INSTANTIATED",
133 "modified": 1535392482.0084584,
134 "projects_write": ["admin"],
135 "deployed": {
136 "RO": {
137 "vnfd_id": {
138 "cirros_vdu_scaling_vnf": "7445e347-fe2f-431a-abc2-8b9be3d093c6"
139 },
140 "nsd_id": "92c56cf0-f8fa-488c-9afb-9f3d78ae6bbb",
141 "nsr_id": "637e12cd-c201-4c44-8ebd-70fb57a4dcee",
142 "nsr_status": "BUILD",
143 }
144 },
145 },
146 "nsd-ref": "cirros_vdu_scaling_ns",
147 "name": "cirros_ns",
148 "resource-orchestrator": "osmopenmano",
149 "instantiate_params": {
150 "nsDescription": "default description",
151 "nsdId": "d7c8bd3c-eb39-4514-8847-19f01345524f",
152 "nsr_id": "87776f33-b67c-417a-8119-cb08e4098951",
153 "nsName": "cirros_ns",
154 "vimAccountId": "be48ae31-1d46-4892-a4b4-d69abd55714b",
155 },
156 "description": "default description",
157 "constituent-vnfr-ref": [
158 "0d9d06ad-3fc2-418c-9934-465e815fafe2",
159 "3336eb44-77df-4c4f-9881-d2828d259864",
160 ],
161 "admin-status": "ENABLED",
162 "detailed-status": "done",
163 "datacenter": "be48ae31-1d46-4892-a4b4-d69abd55714b",
164 "orchestration-progress": {},
165 "short-name": "cirros_ns",
166 "ns-instance-config-ref": "87776f33-b67c-417a-8119-cb08e4098951",
167 "nsd-name-ref": "cirros_vdu_scaling_ns",
168 "admin": {"deployed": {"RO": {"nsr_status": "ACTIVE"}}},
169 }
170
171 vnfr_record_mocks = [
172 {
173 "_id": "0d9d06ad-3fc2-418c-9934-465e815fafe2",
174 "ip-address": "192.168.160.2",
175 "created-time": 1535392482.0044956,
176 "vim-account-id": "be48ae31-1d46-4892-a4b4-d69abd55714b",
177 "vdur": [
178 {
179 "interfaces": [
180 {
181 "mac-address": "fa:16:3e:71:fd:b8",
182 "name": "eth0",
183 "ip-address": "192.168.160.2",
184 }
185 ],
186 "status": "ACTIVE",
187 "vim-id": "63a65636-9fc8-4022-b070-980823e6266a",
188 "name": "cirros_ns-1-cirros_vnfd-VM-1",
189 "status-detailed": None,
190 "ip-address": "192.168.160.2",
191 "vdu-id-ref": "cirros_vnfd-VM",
192 }
193 ],
194 "id": "0d9d06ad-3fc2-418c-9934-465e815fafe2",
195 "vnfd-ref": "cirros_vdu_scaling_vnf",
196 "vnfd-id": "63f44c41-45ee-456b-b10d-5f08fb1796e0",
197 "_admin": {
198 "created": 1535392482.0067868,
199 "projects_read": ["admin"],
200 "modified": 1535392482.0067868,
201 "projects_write": ["admin"],
202 },
203 "nsr-id-ref": "87776f33-b67c-417a-8119-cb08e4098951",
204 "member-vnf-index-ref": "1",
205 "connection-point": [{"name": "eth0", "id": None, "connection-point-id": None}],
206 },
207 {
208 "_id": "3336eb44-77df-4c4f-9881-d2828d259864",
209 "ip-address": "192.168.160.10",
210 "created-time": 1535392482.0044956,
211 "vim-account-id": "be48ae31-1d46-4892-a4b4-d69abd55714b",
212 "vdur": [
213 {
214 "interfaces": [
215 {
216 "mac-address": "fa:16:3e:1e:76:e8",
217 "name": "eth0",
218 "ip-address": "192.168.160.10",
219 }
220 ],
221 "status": "ACTIVE",
222 "vim-id": "a154b8d3-2b10-421a-a51d-4b391d9bd366",
223 "name": "cirros_ns-2-cirros_vnfd-VM-1",
224 "status-detailed": None,
225 "ip-address": "192.168.160.10",
226 "vdu-id-ref": "cirros_vnfd-VM",
227 }
228 ],
229 "id": "3336eb44-77df-4c4f-9881-d2828d259864",
230 "vnfd-ref": "cirros_vdu_scaling_vnf",
231 "vnfd-id": "63f44c41-45ee-456b-b10d-5f08fb1796e0",
232 "_admin": {
233 "created": 1535392482.0076294,
234 "projects_read": ["admin"],
235 "modified": 1535392482.0076294,
236 "projects_write": ["admin"],
237 },
238 "nsr-id-ref": "87776f33-b67c-417a-8119-cb08e4098951",
239 "member-vnf-index-ref": "2",
240 "connection-point": [{"name": "eth0", "id": None, "connection-point-id": None}],
241 },
242 ]
243
244 nsd_record_mock = {
245 "id": "cirros_vdu_scaling_ns",
246 "name": "cirros_vdu_scaling_ns",
247 "description": "Simple NS example with a cirros_vdu_scaling_vnf",
248 "designer": "OSM",
249 "version": "1.0",
250 "vnfd-id": ["cirros_vdu_scaling_vnf"],
251 "df": [
252 {
253 "id": "default-df",
254 "vnf-profile": [
255 {
256 "id": "1",
257 "vnfd-id": "cirros_vdu_scaling_vnf",
258 "virtual-link-connectivity": [
259 {
260 "virtual-link-profile-id": "cirros_nsd_vld1",
261 "constituent-cpd-id": [
262 {
263 "constituent-base-element-id": "1",
264 "constituent-cpd-id": "eth0-ext",
265 }
266 ],
267 }
268 ],
269 },
270 {
271 "id": "2",
272 "vnfd-id": "cirros_vdu_scaling_vnf",
273 "virtual-link-connectivity": [
274 {
275 "virtual-link-profile-id": "cirros_nsd_vld1",
276 "constituent-cpd-id": [
277 {
278 "constituent-base-element-id": "2",
279 "constituent-cpd-id": "eth0-ext",
280 }
281 ],
282 }
283 ],
284 },
285 ],
286 }
287 ],
288 "virtual-link-desc": [{"id": "cirros_nsd_vld1", "mgmt-network": "true"}],
289 }
290
291
292 vnfd_record_mock = {
293 "id": "cirros_vdu_scaling_vnf",
294 "_id": "63f44c41-45ee-456b-b10d-5f08fb1796e0",
295 "product-name": "cirros_vdu_scaling_vnf",
296 "description": "Simple VNF example with a cirros and a scaling group descriptor",
297 "provider": "OSM",
298 "version": "1.0",
299 "mgmt-cp": "eth0-ext",
300 "virtual-storage-desc": [{"id": "cirros_vnfd-VM-storage", "size-of-storage": 2}],
301 "virtual-compute-desc": [
302 {
303 "id": "cirros_vnfd-VM-compute",
304 "virtual-cpu": {"num-virtual-cpu": 1},
305 "virtual-memory": {"size": 0.25},
306 }
307 ],
308 "sw-image-desc": [{"id": "cirros034", "name": "cirros034", "image": "cirros034"}],
309 "vdu": [
310 {
311 "id": "cirros_vnfd-VM",
312 "description": "cirros_vnfd-VM",
313 "name": "cirros_vnfd-VM",
314 "alarm": [
315 {
316 "value": 20.0,
317 "actions": {
318 "insufficient-data": [{"url": "localhost:9090"}],
319 "ok": [{"url": "localhost:9090"}],
320 "alarm": [{"url": "localhost:9090"}],
321 },
322 "alarm-id": "alarm-1",
323 "operation": "LT",
324 "vnf-monitoring-param-ref": "cirros_vnf_memory_util",
325 }
326 ],
327 "sw-image-desc": "cirros034",
328 "virtual-compute-desc": "cirros_vnfd-VM-compute",
329 "virtual-storage-desc": ["cirros_vnfd-VM-storage"],
330 "int-cpd": [
331 {
332 "id": "eth0-int",
333 "virtual-network-interface-requirement": [
334 {
335 "name": "eth0",
336 "virtual-interface": {
337 "bandwidth": "0",
338 "type": "VIRTIO",
339 "vpci": "0000:00:0a.0",
340 },
341 }
342 ],
343 }
344 ],
345 "monitoring-parameter": [
346 {
347 "id": "cirros_vnf_memory_util",
348 "name": "cirros_vnf_memory_util",
349 "performance-metric": "average_memory_utilization",
350 }
351 ],
352 }
353 ],
354 "df": [
355 {
356 "id": "default-df",
357 "vdu-profile": [
358 {
359 "id": "cirros_vnfd-VM",
360 "min-number-of-instances": 1,
361 "max-number-of-instances": 10,
362 "vdu-configuration-id": "cirros_vnfd-VM-vdu-configuration",
363 }
364 ],
365 "instantiation-level": [
366 {
367 "id": "default-instantiation-level",
368 "vdu-level": [
369 {"vdu-id": "cirros_vnfd-VM", "number-of-instances": 1}
370 ],
371 }
372 ],
373 "scaling-aspect": [
374 {
375 "id": "scale_cirros_vnfd-VM",
376 "name": "scale_cirros_vnfd-VM",
377 "max-scale-level": 10,
378 "scaling-policy": [
379 {
380 "name": "auto_memory_util_above_threshold",
381 "scaling-type": "automatic",
382 "cooldown-time": 60,
383 "threshold-time": 10,
384 "scaling-criteria": [
385 {
386 "name": "group1_memory_util_above_threshold",
387 "vnf-monitoring-param-ref": "cirros_vnf_memory_util",
388 "scale-out-threshold": 80,
389 "scale-out-relational-operation": "GT",
390 "scale-in-relational-operation": "LT",
391 "scale-in-threshold": 20,
392 }
393 ],
394 }
395 ],
396 "aspect-delta-details": {
397 "deltas": [
398 {
399 "id": "scale_cirros_vnfd-VM-delta",
400 "vdu-delta": [
401 {"number-of-instances": 1, "id": "cirros_vnfd-VM"}
402 ],
403 }
404 ]
405 },
406 }
407 ],
408 }
409 ],
410 "ext-cpd": [
411 {"id": "eth0-ext", "int-cpd": {"vdu-id": "cirros_vnfd-VM", "cpd": "eth0-int"}}
412 ],
413 "vdu-configuration": [
414 {
415 "juju": {"charm": "testmetrics", "proxy": True},
416 "metrics": [{"name": "users"}],
417 "id": "cirros_vnfd-VM-vdu-configuration",
418 }
419 ],
420 "_admin": {
421 "created": 1535392242.6281035,
422 "modified": 1535392242.6281035,
423 "storage": {
424 "zipfile": "package.tar.gz",
425 "pkg-dir": "cirros_vnf",
426 "path": "/app/storage/",
427 "folder": "63f44c41-45ee-456b-b10d-5f08fb1796e0",
428 "fs": "local",
429 "descriptor": "cirros_vnf/cirros_vdu_scaling_vnfd.yaml",
430 },
431 "usageSate": "NOT_IN_USE",
432 "onboardingState": "ONBOARDED",
433 "userDefinedData": {},
434 "projects_read": ["admin"],
435 "operationalState": "ENABLED",
436 "projects_write": ["admin"],
437 },
438 }
439
440 MODELS = [
441 ScalingGroup,
442 ScalingPolicy,
443 ScalingCriteria,
444 ScalingAlarm,
445 VnfAlarm,
446 AlarmAction,
447 ]
448
449
450 class PolicyModuleAgentTest(unittest.TestCase):
451 def setUp(self):
452 super()
453 database.db.initialize(connect("sqlite:///test_db.sqlite"))
454 database.db.bind(MODELS)
455 database.db.connect()
456 database.db.drop_tables(MODELS)
457 database.db.create_tables(MODELS)
458 database.db.close()
459 self.loop = asyncio.new_event_loop()
460
461 def tearDown(self):
462 super()
463 os.remove("test_db.sqlite")
464
465 @patch.object(DbMongo, "db_connect", Mock())
466 @patch.object(KafkaProducer, "__init__")
467 @patch.object(MonClient, "create_alarm")
468 @patch.object(CommonDbClient, "get_vnfd")
469 @patch.object(CommonDbClient, "get_nsr")
470 @patch.object(CommonDbClient, "get_vnfr")
471 def test_configure_scaling_groups(
472 self, get_vnfr, get_nsr, get_vnfd, create_alarm, kafka_producer_init
473 ):
474 def _test_configure_scaling_groups_get_vnfr(*args, **kwargs):
475 if "1" in args[1]:
476 return vnfr_record_mocks[0]
477 if "2" in args[1]:
478 return vnfr_record_mocks[1]
479
480 def assert_not_called_with(*args, **kwargs):
481 try:
482 create_alarm.assert_called_with(*args, **kwargs)
483 except AssertionError:
484 return
485 raise AssertionError("Expected to not have been called.")
486
487 async def _test_configure_scaling_groups_create_alarm(*args, **kwargs):
488 return uuid.uuid4()
489
490 kafka_producer_init.return_value = None
491 get_vnfr.side_effect = _test_configure_scaling_groups_get_vnfr
492 get_nsr.return_value = nsr_record_mock
493 get_vnfd.return_value = vnfd_record_mock
494 create_alarm.side_effect = _test_configure_scaling_groups_create_alarm
495 create_alarm.assert_not_called_with = assert_not_called_with
496 config = Config()
497 agent = PolicyModuleAgent(config, self.loop)
498 self.loop.run_until_complete(
499 agent.autoscaling_service.configure_scaling_groups("test_nsr_id")
500 )
501 create_alarm.assert_any_call(
502 metric_name="average_memory_utilization",
503 ns_id="test_nsr_id",
504 operation="GT",
505 threshold=80,
506 vdu_name="cirros_ns-1-cirros_vnfd-VM-1",
507 vnf_member_index="1",
508 action="scale_out",
509 )
510 create_alarm.assert_not_called_with(
511 metric_name="average_memory_utilization",
512 ns_id="test_nsr_id",
513 operation="LT",
514 threshold=20,
515 vdu_name="cirros_ns-1-cirros_vnfd-VM-1",
516 vnf_member_index="1",
517 action="scale_out",
518 )
519 create_alarm.assert_any_call(
520 metric_name="average_memory_utilization",
521 ns_id="test_nsr_id",
522 operation="GT",
523 threshold=80,
524 vdu_name="cirros_ns-2-cirros_vnfd-VM-1",
525 vnf_member_index="2",
526 action="scale_out",
527 )
528 create_alarm.assert_not_called_with(
529 metric_name="average_memory_utilization",
530 ns_id="test_nsr_id",
531 operation="LT",
532 threshold=20,
533 vdu_name="cirros_ns-2-cirros_vnfd-VM-1",
534 vnf_member_index="2",
535 action="scale_out",
536 )
537 scaling_record = ScalingGroup.get()
538 self.assertEqual(scaling_record.name, "scale_cirros_vnfd-VM")
539 self.assertEqual(scaling_record.nsr_id, "test_nsr_id")
540
541 @patch.object(DbMongo, "db_connect", Mock())
542 @patch.object(KafkaProducer, "__init__")
543 @patch.object(MonClient, "create_alarm")
544 @patch.object(CommonDbClient, "get_vnfd")
545 @patch.object(CommonDbClient, "get_nsr")
546 @patch.object(CommonDbClient, "get_vnfr")
547 def test_configure_vnf_alarms(
548 self, get_vnfr, get_nsr, get_vnfd, create_alarm, kafka_producer_init
549 ):
550 def _test_configure_scaling_groups_get_vnfr(*args, **kwargs):
551 if "1" in args[1]:
552 return vnfr_record_mocks[0]
553 if "2" in args[1]:
554 return vnfr_record_mocks[1]
555
556 async def _test_configure_vnf_alarms_create_alarm(*args, **kwargs):
557 return uuid.uuid4()
558
559 kafka_producer_init.return_value = None
560 get_vnfr.side_effect = _test_configure_scaling_groups_get_vnfr
561 get_nsr.return_value = nsr_record_mock
562 get_vnfd.return_value = vnfd_record_mock
563 create_alarm.side_effect = _test_configure_vnf_alarms_create_alarm
564 config = Config()
565 agent = PolicyModuleAgent(config, self.loop)
566 self.loop.run_until_complete(
567 agent.alarming_service.configure_vnf_alarms("test_nsr_id")
568 )
569 create_alarm.assert_any_call(
570 metric_name="average_memory_utilization",
571 ns_id="test_nsr_id",
572 vdu_name="cirros_ns-1-cirros_vnfd-VM-1",
573 vnf_member_index="1",
574 threshold=20.0,
575 operation="LT",
576 action="{'webhook': ['localhost:9090', 'localhost:9090', 'localhost:9090']}"
577 )
578 create_alarm.assert_any_call(
579 metric_name="average_memory_utilization",
580 ns_id="test_nsr_id",
581 vdu_name="cirros_ns-2-cirros_vnfd-VM-1",
582 vnf_member_index="2",
583 threshold=20.0,
584 operation="LT",
585 action="{'webhook': ['localhost:9090', 'localhost:9090', 'localhost:9090']}"
586 )
587
588
589 if __name__ == "__main__":
590 unittest.main()