1 # -*- coding: utf-8 -*-
3 # Copyright 2018 Whitestack, LLC
4 # *************************************************************
6 # This file is part of OSM Monitoring module
7 # All Rights Reserved to Whitestack, LLC
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
13 # http://www.apache.org/licenses/LICENSE-2.0
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
21 # For those usages not covered by the Apache License, Version 2.0 please
22 # contact: bdiaz@whitestack.com or glavado@whitestack.com
30 from unittest
.mock
import patch
, Mock
32 from kafka
import KafkaProducer
33 from osm_common
.dbmongo
import DbMongo
34 from playhouse
.db_url
import connect
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 (
51 log
= logging
.getLogger()
52 log
.level
= logging
.INFO
53 stream_handler
= logging
.StreamHandler(sys
.stdout
)
54 log
.addHandler(stream_handler
)
57 "_id": "87776f33-b67c-417a-8119-cb08e4098951",
58 "crete-time": 1535392482.0044956,
59 "operational-status": "running",
60 "ssh-authorized-key": None,
61 "name-ref": "cirros_ns",
63 "_id": "d7c8bd3c-eb39-4514-8847-19f01345524f",
65 "created": 1535392246.499733,
66 "userDefinedData": {},
67 "usageSate": "NOT_IN_USE",
69 "zipfile": "package.tar.gz",
71 "path": "/app/storage/",
72 "folder": "d7c8bd3c-eb39-4514-8847-19f01345524f",
73 "pkg-dir": "cirros_nsd",
74 "descriptor": "cirros_nsd/cirros_vdu_scaling_nsd.yaml",
76 "onboardingState": "ONBOARDED",
77 "modified": 1535392246.499733,
78 "projects_read": ["admin"],
79 "operationalState": "ENABLED",
80 "projects_write": ["admin"],
82 "id": "cirros_vdu_scaling_ns",
83 "name": "cirros_vdu_scaling_ns",
84 "description": "Simple NS example with a cirros_vdu_scaling_vnf",
87 "vnfd-id": ["cirros_vdu_scaling_vnf"],
94 "vnfd-id": "cirros_vdu_scaling_vnf",
95 "virtual-link-connectivity": [
97 "virtual-link-profile-id": "cirros_nsd_vld1",
98 "constituent-cpd-id": [
100 "constituent-base-element-id": "1",
101 "constituent-cpd-id": "eth0-ext",
109 "vnfd-id": "cirros_vdu_scaling_vnf",
110 "virtual-link-connectivity": [
112 "virtual-link-profile-id": "cirros_nsd_vld1",
113 "constituent-cpd-id": [
115 "constituent-base-element-id": "2",
116 "constituent-cpd-id": "eth0-ext",
125 "virtual-link-desc": [{"id": "cirros_nsd_vld1", "mgmt-network": "true"}],
127 "id": "87776f33-b67c-417a-8119-cb08e4098951",
128 "config-status": "configured",
129 "operational-events": [],
131 "created": 1535392482.0084584,
132 "projects_read": ["admin"],
133 "nsState": "INSTANTIATED",
134 "modified": 1535392482.0084584,
135 "projects_write": ["admin"],
139 "cirros_vdu_scaling_vnf": "7445e347-fe2f-431a-abc2-8b9be3d093c6"
141 "nsd_id": "92c56cf0-f8fa-488c-9afb-9f3d78ae6bbb",
142 "nsr_id": "637e12cd-c201-4c44-8ebd-70fb57a4dcee",
143 "nsr_status": "BUILD",
147 "nsd-ref": "cirros_vdu_scaling_ns",
149 "resource-orchestrator": "osmopenmano",
150 "instantiate_params": {
151 "nsDescription": "default description",
152 "nsdId": "d7c8bd3c-eb39-4514-8847-19f01345524f",
153 "nsr_id": "87776f33-b67c-417a-8119-cb08e4098951",
154 "nsName": "cirros_ns",
155 "vimAccountId": "be48ae31-1d46-4892-a4b4-d69abd55714b",
157 "description": "default description",
158 "constituent-vnfr-ref": [
159 "0d9d06ad-3fc2-418c-9934-465e815fafe2",
160 "3336eb44-77df-4c4f-9881-d2828d259864",
162 "admin-status": "ENABLED",
163 "detailed-status": "done",
164 "datacenter": "be48ae31-1d46-4892-a4b4-d69abd55714b",
165 "orchestration-progress": {},
166 "short-name": "cirros_ns",
167 "ns-instance-config-ref": "87776f33-b67c-417a-8119-cb08e4098951",
168 "nsd-name-ref": "cirros_vdu_scaling_ns",
169 "admin": {"deployed": {"RO": {"nsr_status": "ACTIVE"}}},
172 vnfr_record_mocks
= [
174 "_id": "0d9d06ad-3fc2-418c-9934-465e815fafe2",
175 "ip-address": "192.168.160.2",
176 "created-time": 1535392482.0044956,
177 "vim-account-id": "be48ae31-1d46-4892-a4b4-d69abd55714b",
182 "mac-address": "fa:16:3e:71:fd:b8",
184 "ip-address": "192.168.160.2",
189 "vim-id": "63a65636-9fc8-4022-b070-980823e6266a",
190 "name": "cirros_ns-1-cirros_vnfd-VM-1",
191 "status-detailed": None,
192 "ip-address": "192.168.160.2",
193 "vdu-id-ref": "cirros_vnfd-VM",
196 "id": "0d9d06ad-3fc2-418c-9934-465e815fafe2",
197 "vnfd-ref": "cirros_vdu_scaling_vnf",
198 "vnfd-id": "63f44c41-45ee-456b-b10d-5f08fb1796e0",
200 "created": 1535392482.0067868,
201 "projects_read": ["admin"],
202 "modified": 1535392482.0067868,
203 "projects_write": ["admin"],
205 "nsr-id-ref": "87776f33-b67c-417a-8119-cb08e4098951",
206 "member-vnf-index-ref": "1",
207 "connection-point": [{"name": "eth0", "id": None, "connection-point-id": None}],
210 "_id": "3336eb44-77df-4c4f-9881-d2828d259864",
211 "ip-address": "192.168.160.10",
212 "created-time": 1535392482.0044956,
213 "vim-account-id": "be48ae31-1d46-4892-a4b4-d69abd55714b",
218 "mac-address": "fa:16:3e:1e:76:e8",
220 "ip-address": "192.168.160.10",
225 "vim-id": "a154b8d3-2b10-421a-a51d-4b391d9bd366",
226 "name": "cirros_ns-2-cirros_vnfd-VM-1",
227 "status-detailed": None,
228 "ip-address": "192.168.160.10",
229 "vdu-id-ref": "cirros_vnfd-VM",
232 "id": "3336eb44-77df-4c4f-9881-d2828d259864",
233 "vnfd-ref": "cirros_vdu_scaling_vnf",
234 "vnfd-id": "63f44c41-45ee-456b-b10d-5f08fb1796e0",
236 "created": 1535392482.0076294,
237 "projects_read": ["admin"],
238 "modified": 1535392482.0076294,
239 "projects_write": ["admin"],
241 "nsr-id-ref": "87776f33-b67c-417a-8119-cb08e4098951",
242 "member-vnf-index-ref": "2",
243 "connection-point": [{"name": "eth0", "id": None, "connection-point-id": None}],
248 "id": "cirros_vdu_scaling_ns",
249 "name": "cirros_vdu_scaling_ns",
250 "description": "Simple NS example with a cirros_vdu_scaling_vnf",
253 "vnfd-id": ["cirros_vdu_scaling_vnf"],
260 "vnfd-id": "cirros_vdu_scaling_vnf",
261 "virtual-link-connectivity": [
263 "virtual-link-profile-id": "cirros_nsd_vld1",
264 "constituent-cpd-id": [
266 "constituent-base-element-id": "1",
267 "constituent-cpd-id": "eth0-ext",
275 "vnfd-id": "cirros_vdu_scaling_vnf",
276 "virtual-link-connectivity": [
278 "virtual-link-profile-id": "cirros_nsd_vld1",
279 "constituent-cpd-id": [
281 "constituent-base-element-id": "2",
282 "constituent-cpd-id": "eth0-ext",
291 "virtual-link-desc": [{"id": "cirros_nsd_vld1", "mgmt-network": "true"}],
296 "id": "cirros_vdu_scaling_vnf",
297 "_id": "63f44c41-45ee-456b-b10d-5f08fb1796e0",
298 "product-name": "cirros_vdu_scaling_vnf",
299 "description": "Simple VNF example with a cirros and a scaling group descriptor",
302 "mgmt-cp": "eth0-ext",
303 "virtual-storage-desc": [{"id": "cirros_vnfd-VM-storage", "size-of-storage": 2}],
304 "virtual-compute-desc": [
306 "id": "cirros_vnfd-VM-compute",
307 "virtual-cpu": {"num-virtual-cpu": 1},
308 "virtual-memory": {"size": 0.25},
311 "sw-image-desc": [{"id": "cirros034", "name": "cirros034", "image": "cirros034"}],
314 "id": "cirros_vnfd-VM",
315 "description": "cirros_vnfd-VM",
316 "name": "cirros_vnfd-VM",
321 "insufficient-data": [{"url": "localhost:9090"}],
322 "ok": [{"url": "localhost:9090"}],
323 "alarm": [{"url": "localhost:9090"}],
325 "alarm-id": "alarm-1",
327 "vnf-monitoring-param-ref": "cirros_vnf_memory_util",
330 "sw-image-desc": "cirros034",
331 "virtual-compute-desc": "cirros_vnfd-VM-compute",
332 "virtual-storage-desc": ["cirros_vnfd-VM-storage"],
336 "virtual-network-interface-requirement": [
339 "virtual-interface": {
342 "vpci": "0000:00:0a.0",
348 "monitoring-parameter": [
350 "id": "cirros_vnf_memory_util",
351 "name": "cirros_vnf_memory_util",
352 "performance-metric": "average_memory_utilization",
362 "id": "cirros_vnfd-VM",
363 "min-number-of-instances": 1,
364 "max-number-of-instances": 10,
365 "vdu-configuration-id": "cirros_vnfd-VM-vdu-configuration",
370 "id": "cirros_vnfd-VM-autoheal",
373 "vdu-id": "cirros_vnfd-VM",
374 "event-name": "heal-alarm",
375 "recovery-type": "automatic",
376 "action-on-recovery": "REDEPLOY_ONLY",
377 "cooldown-time": 180,
383 "instantiation-level": [
385 "id": "default-instantiation-level",
387 {"vdu-id": "cirros_vnfd-VM", "number-of-instances": 1}
393 "id": "scale_cirros_vnfd-VM",
394 "name": "scale_cirros_vnfd-VM",
395 "max-scale-level": 10,
398 "name": "auto_memory_util_above_threshold",
399 "scaling-type": "automatic",
401 "threshold-time": 10,
402 "scaling-criteria": [
404 "name": "group1_memory_util_above_threshold",
405 "vnf-monitoring-param-ref": "cirros_vnf_memory_util",
406 "scale-out-threshold": 80,
407 "scale-out-relational-operation": "GT",
408 "scale-in-relational-operation": "LT",
409 "scale-in-threshold": 20,
414 "aspect-delta-details": {
417 "id": "scale_cirros_vnfd-VM-delta",
419 {"number-of-instances": 1, "id": "cirros_vnfd-VM"}
429 {"id": "eth0-ext", "int-cpd": {"vdu-id": "cirros_vnfd-VM", "cpd": "eth0-int"}}
431 "vdu-configuration": [
433 "juju": {"charm": "testmetrics", "proxy": True},
434 "metrics": [{"name": "users"}],
435 "id": "cirros_vnfd-VM-vdu-configuration",
439 "created": 1535392242.6281035,
440 "modified": 1535392242.6281035,
442 "zipfile": "package.tar.gz",
443 "pkg-dir": "cirros_vnf",
444 "path": "/app/storage/",
445 "folder": "63f44c41-45ee-456b-b10d-5f08fb1796e0",
447 "descriptor": "cirros_vnf/cirros_vdu_scaling_vnfd.yaml",
449 "usageSate": "NOT_IN_USE",
450 "onboardingState": "ONBOARDED",
451 "userDefinedData": {},
452 "projects_read": ["admin"],
453 "operationalState": "ENABLED",
454 "projects_write": ["admin"],
469 class PolicyModuleAgentTest(unittest
.TestCase
):
472 database
.db
.initialize(connect("sqlite:///test_db.sqlite"))
473 database
.db
.bind(MODELS
)
474 database
.db
.connect()
475 database
.db
.drop_tables(MODELS
)
476 database
.db
.create_tables(MODELS
)
478 self
.loop
= asyncio
.new_event_loop()
482 os
.remove("test_db.sqlite")
484 @patch.object(DbMongo
, "db_connect", Mock())
485 @patch.object(KafkaProducer
, "__init__")
486 @patch.object(MonClient
, "create_alarm")
487 @patch.object(CommonDbClient
, "get_vnfd")
488 @patch.object(CommonDbClient
, "get_nsr")
489 @patch.object(CommonDbClient
, "get_vnfr")
490 def test_configure_scaling_groups(
491 self
, get_vnfr
, get_nsr
, get_vnfd
, create_alarm
, kafka_producer_init
493 def _test_configure_scaling_groups_get_vnfr(*args
, **kwargs
):
495 return vnfr_record_mocks
[0]
497 return vnfr_record_mocks
[1]
499 def assert_not_called_with(*args
, **kwargs
):
501 create_alarm
.assert_called_with(*args
, **kwargs
)
502 except AssertionError:
504 raise AssertionError("Expected to not have been called.")
506 async def _test_configure_scaling_groups_create_alarm(*args
, **kwargs
):
509 kafka_producer_init
.return_value
= None
510 get_vnfr
.side_effect
= _test_configure_scaling_groups_get_vnfr
511 get_nsr
.return_value
= nsr_record_mock
512 get_vnfd
.return_value
= vnfd_record_mock
513 create_alarm
.side_effect
= _test_configure_scaling_groups_create_alarm
514 create_alarm
.assert_not_called_with
= assert_not_called_with
516 agent
= PolicyModuleAgent(config
, self
.loop
)
517 self
.loop
.run_until_complete(
518 agent
.autoscaling_service
.configure_scaling_groups("test_nsr_id")
520 create_alarm
.assert_any_call(
521 metric_name
="average_memory_utilization",
525 vdu_name
="cirros_ns-1-cirros_vnfd-VM-1",
526 vnf_member_index
="1",
529 create_alarm
.assert_not_called_with(
530 metric_name
="average_memory_utilization",
534 vdu_name
="cirros_ns-1-cirros_vnfd-VM-1",
535 vnf_member_index
="1",
538 create_alarm
.assert_any_call(
539 metric_name
="average_memory_utilization",
543 vdu_name
="cirros_ns-2-cirros_vnfd-VM-1",
544 vnf_member_index
="2",
547 create_alarm
.assert_not_called_with(
548 metric_name
="average_memory_utilization",
552 vdu_name
="cirros_ns-2-cirros_vnfd-VM-1",
553 vnf_member_index
="2",
556 scaling_record
= ScalingGroup
.get()
557 self
.assertEqual(scaling_record
.name
, "scale_cirros_vnfd-VM")
558 self
.assertEqual(scaling_record
.nsr_id
, "test_nsr_id")
560 @patch.object(DbMongo
, "db_connect", Mock())
561 @patch.object(KafkaProducer
, "__init__")
562 @patch.object(MonClient
, "create_alarm")
563 @patch.object(CommonDbClient
, "get_vnfd")
564 @patch.object(CommonDbClient
, "get_nsr")
565 @patch.object(CommonDbClient
, "get_vnfr")
566 def test_configure_vnf_alarms(
567 self
, get_vnfr
, get_nsr
, get_vnfd
, create_alarm
, kafka_producer_init
569 def _test_configure_scaling_groups_get_vnfr(*args
, **kwargs
):
571 return vnfr_record_mocks
[0]
573 return vnfr_record_mocks
[1]
575 async def _test_configure_vnf_alarms_create_alarm(*args
, **kwargs
):
578 kafka_producer_init
.return_value
= None
579 get_vnfr
.side_effect
= _test_configure_scaling_groups_get_vnfr
580 get_nsr
.return_value
= nsr_record_mock
581 get_vnfd
.return_value
= vnfd_record_mock
582 create_alarm
.side_effect
= _test_configure_vnf_alarms_create_alarm
584 agent
= PolicyModuleAgent(config
, self
.loop
)
585 self
.loop
.run_until_complete(
586 agent
.alarming_service
.configure_vnf_alarms("test_nsr_id")
588 create_alarm
.assert_any_call(
589 metric_name
="average_memory_utilization",
591 vdu_name
="cirros_ns-1-cirros_vnfd-VM-1",
592 vnf_member_index
="1",
595 action
="{'webhook': ['localhost:9090', 'localhost:9090', 'localhost:9090']}",
597 create_alarm
.assert_any_call(
598 metric_name
="average_memory_utilization",
600 vdu_name
="cirros_ns-2-cirros_vnfd-VM-1",
601 vnf_member_index
="2",
604 action
="{'webhook': ['localhost:9090', 'localhost:9090', 'localhost:9090']}",
607 @patch.object(DbMongo
, "db_connect", Mock())
608 @patch.object(KafkaProducer
, "__init__")
609 @patch.object(MonClient
, "create_alarm")
610 @patch.object(CommonDbClient
, "get_vnfd")
611 @patch.object(CommonDbClient
, "get_nsr")
612 @patch.object(CommonDbClient
, "get_vnfr")
613 def test_configure_healing_alarms(
614 self
, get_vnfr
, get_nsr
, get_vnfd
, create_alarm
, kafka_producer_init
616 def _test_configure_scaling_groups_get_vnfr(*args
, **kwargs
):
618 return vnfr_record_mocks
[0]
620 return vnfr_record_mocks
[1]
622 async def _test_configure_healing_alarms_create_alarm(*args
, **kwargs
):
625 kafka_producer_init
.return_value
= None
626 get_vnfr
.side_effect
= _test_configure_scaling_groups_get_vnfr
627 get_nsr
.return_value
= nsr_record_mock
628 get_vnfd
.return_value
= vnfd_record_mock
629 create_alarm
.side_effect
= _test_configure_healing_alarms_create_alarm
631 agent
= PolicyModuleAgent(config
, self
.loop
)
632 self
.loop
.run_until_complete(
633 agent
.healing_service
.configure_healing_alarms("test_nsr_id")
635 create_alarm
.assert_any_call(
636 metric_name
="vm_status",
638 vdu_name
="cirros_ns-1-cirros_vnfd-VM-1",
639 vnf_member_index
="1",
644 create_alarm
.assert_any_call(
645 metric_name
="vm_status",
647 vdu_name
="cirros_ns-2-cirros_vnfd-VM-1",
648 vnf_member_index
="2",
655 if __name__
== "__main__":