vnf_monitoring_param = next(
filter(
lambda param: param['id'] == alarm_descriptor['vnf-monitoring-param-ref'],
- vnfd['monitoring-param'])
+ vdu.get('monitoring-parameter', [])
+ ),
+ {}
)
- metric_name = self._get_metric_name(vnf_monitoring_param, vdur, vnfd)
+ metric_name = self._get_metric_name(vnf_monitoring_param)
alarm_uuid = await self.mon_client.create_alarm(
metric_name=metric_name,
ns_id=nsr_id,
vdu_name=vdur['name'],
vnf_member_index=vnfr['member-vnf-index-ref'],
threshold=alarm_descriptor['value'],
- operation=alarm_descriptor['operation'],
- statistic=vnf_monitoring_param['aggregation-type']
+ operation=alarm_descriptor['operation']
)
alarm = VnfAlarmRepository.create(
alarm_id=alarm_descriptor['alarm-id'],
database.db.close()
async def delete_orphaned_alarms(self, nsr_id):
+ # TODO: Review as it seems this code is never called
log.info("Deleting orphaned vnf alarms for network service %s", nsr_id)
database.db.connect()
try:
finally:
database.db.close()
- def _get_metric_name(self, vnf_monitoring_param: dict, vdur: dict, vnfd: dict):
- vdu = next(
- filter(lambda vdu: vdu['id'] == vdur['vdu-id-ref'], vnfd['vdu'])
- )
- if 'vdu-monitoring-param' in vnf_monitoring_param:
- vdu_monitoring_param = next(filter(
- lambda param: param['id'] == vnf_monitoring_param['vdu-monitoring-param'][
- 'vdu-monitoring-param-ref'], vdu['monitoring-param']))
- nfvi_metric = vdu_monitoring_param['nfvi-metric']
- return nfvi_metric
- if 'vdu-metric' in vnf_monitoring_param:
- vnf_metric_name = vnf_monitoring_param['vdu-metric']['vdu-metric-name-ref']
- return vnf_metric_name
- if 'vnf-metric' in vnf_monitoring_param:
- vnf_metric_name = vnf_monitoring_param['vnf-metric']['vnf-metric-name-ref']
- return vnf_metric_name
+ def _get_metric_name(self, vnf_monitoring_param: dict):
+ if 'performance-metric' in vnf_monitoring_param:
+ return vnf_monitoring_param['performance-metric']
raise ValueError('No metric name found for vnf_monitoring_param %s' % vnf_monitoring_param['id'])
import datetime
import json
import logging
-from typing import List
from osm_policy_module.common.common_db_client import CommonDbClient
from osm_policy_module.common.lcm_client import LcmClient
from osm_policy_module.core.database import ScalingGroup, ScalingAlarm, ScalingPolicy, ScalingCriteria, \
ScalingAlarmRepository, ScalingGroupRepository, ScalingPolicyRepository, ScalingCriteriaRepository
from osm_policy_module.core.exceptions import VdurNotFound
-from osm_policy_module.utils.vnfd import VnfdUtils
log = logging.getLogger(__name__)
for vnfr in vnfrs:
log.debug("Processing vnfr: %s", vnfr)
vnfd = self.db_client.get_vnfd(vnfr['vnfd-id'])
- if 'scaling-group-descriptor' not in vnfd:
- log.debug("No scaling group present in vnfd")
+ # TODO: Change for multiple DF support
+ df = vnfd.get('df', [{}])[0]
+ if 'scaling-aspect' not in df:
+ log.debug("No scaling aspect present in vnfd")
continue
- scaling_groups = vnfd['scaling-group-descriptor']
- vnf_monitoring_params = vnfd['monitoring-param']
- for scaling_group in scaling_groups:
+ # TODO: Change for multiple instantiation levels support
+ instantiation_level = df.get('instantiation-level', [{}])[0]
+ scaling_aspects = df['scaling-aspect']
+ all_vnfd_monitoring_params = self._get_all_vnfd_monitoring_params(vnfd)
+ for scaling_aspect in scaling_aspects:
scaling_group_record = self._get_or_create_scaling_group(nsr_id,
vnfr['member-vnf-index-ref'],
- scaling_group)
- for scaling_policy in scaling_group['scaling-policy']:
+ scaling_aspect)
+ vdurs = self._get_monitored_vdurs(scaling_aspect, vnfr['vdur'])
+ for scaling_policy in scaling_aspect.get('scaling-policy', ()):
if scaling_policy['scaling-type'] != 'automatic':
continue
scaling_policy_record = self._get_or_create_scaling_policy(nsr_id,
scaling_criteria,
scaling_policy_record
)
- vnf_monitoring_param = next(
- filter(
- lambda param: param['id'] == scaling_criteria[
- 'vnf-monitoring-param-ref'
- ],
- vnf_monitoring_params)
- )
- vdurs = self._get_monitored_vdurs(vnf_monitoring_param, vnfr['vdur'], vnfd)
+ monitoring_param_ref = scaling_criteria.get('vnf-monitoring-param-ref')
+ vnf_monitoring_param = all_vnfd_monitoring_params[monitoring_param_ref]
+
for vdur in vdurs:
+ vdu_id = vdur['vdu-id-ref']
log.debug("Creating alarm for vdur %s ", vdur)
try:
ScalingAlarmRepository.get(ScalingAlarm.vdu_name == vdur['name'],
continue
except ScalingAlarm.DoesNotExist:
pass
- metric_name = self._get_metric_name(vnf_monitoring_param, vdur, vnfd)
+ metric_name = self._get_metric_name(vnf_monitoring_param)
db_nsr = self.db_client.get_nsr(nsr_id)
nb_scale_op = 0
if db_nsr["_admin"].get("scaling-group"):
db_nsr_admin = db_nsr["_admin"]["scaling-group"]
for admin_scale_index, admin_scale_info in enumerate(db_nsr_admin):
- if admin_scale_info["name"] == scaling_group["name"]:
+ if admin_scale_info["name"] == scaling_aspect["name"]:
nb_scale_op = admin_scale_info.get("nb-scale-op", 0)
break
- min_instance_count = int(scaling_group["min-instance-count"])
+ for vdu_level in instantiation_level.get('vdu-level', ()):
+ if vdu_level.get('vdu-id') == vdu_id:
+ min_instance_count = int(vdu_level['number-of-instances'])
if nb_scale_op > min_instance_count:
alarm_uuid = await self.mon_client.create_alarm(
metric_name=metric_name,
vdu_name=vdur['name'],
vnf_member_index=vnfr['member-vnf-index-ref'],
threshold=scaling_criteria['scale-in-threshold'],
- operation=scaling_criteria['scale-in-relational-operation'],
- statistic=vnf_monitoring_param['aggregation-type']
+ operation=scaling_criteria['scale-in-relational-operation']
)
alarm = ScalingAlarmRepository.create(
alarm_uuid=alarm_uuid,
vdu_name=vdur['name'],
vnf_member_index=vnfr['member-vnf-index-ref'],
threshold=scaling_criteria['scale-out-threshold'],
- operation=scaling_criteria['scale-out-relational-operation'],
- statistic=vnf_monitoring_param['aggregation-type']
+ operation=scaling_criteria['scale-out-relational-operation']
)
alarm = ScalingAlarmRepository.create(
alarm_uuid=alarm_uuid,
finally:
database.db.close()
- def _get_or_create_scaling_group(self, nsr_id: str, vnf_member_index: str, scaling_group: dict):
+ def _get_all_vnfd_monitoring_params(self, vnfd):
+ all_monitoring_params = {}
+ for ivld in vnfd.get("int-virtual-link-desc", ()):
+ for mp in ivld.get("monitoring-parameters", ()):
+ all_monitoring_params[mp.get("id")] = mp
+
+ for vdu in vnfd.get("vdu", ()):
+ for mp in vdu.get("monitoring-parameter", ()):
+ all_monitoring_params[mp.get("id")] = mp
+
+ for df in vnfd.get("df", ()):
+ for mp in df.get("monitoring-parameter", ()):
+ all_monitoring_params[mp.get("id")] = mp
+
+ return all_monitoring_params
+
+ def _get_or_create_scaling_group(self, nsr_id: str, vnf_member_index: str, scaling_aspect: dict):
try:
scaling_group_record = ScalingGroupRepository.get(
ScalingGroup.nsr_id == nsr_id,
ScalingGroup.vnf_member_index == vnf_member_index,
- ScalingGroup.name == scaling_group['name']
+ ScalingGroup.name == scaling_aspect['name']
)
log.debug("Found existing scaling group record in DB...")
except ScalingGroup.DoesNotExist:
scaling_group_record = ScalingGroupRepository.create(
nsr_id=nsr_id,
vnf_member_index=vnf_member_index,
- name=scaling_group['name'],
- content=json.dumps(scaling_group)
+ name=scaling_aspect['name'],
+ content=json.dumps(scaling_aspect)
)
log.debug(
"Created scaling group record in DB : nsr_id=%s, vnf_member_index=%s, name=%s",
scaling_group=scaling_group_record,
)
if 'scale-in-operation-type' in scaling_policy:
- scaling_policy_record.scale_in_operation = scaling_policy[
- 'scale-in-operation-type']
+ scaling_policy_record.scale_in_operation = scaling_policy['scale-in-operation-type']
if 'scale-out-operation-type' in scaling_policy:
- scaling_policy_record.scale_out_operation = scaling_policy[
- 'scale-out-operation-type']
+ scaling_policy_record.scale_out_operation = scaling_policy['scale-out-operation-type']
if 'enabled' in scaling_policy:
scaling_policy_record.enabled = scaling_policy['enabled']
scaling_policy_record.save()
scaling_criteria_record.scaling_policy.name)
return scaling_criteria_record
- def _get_monitored_vdurs(self, vnf_monitoring_param: dict, vdurs: List[dict], vnfd: dict):
- monitored_vdurs = []
- if 'vdu-monitoring-param' in vnf_monitoring_param:
- monitored_vdurs = list(
- filter(
- lambda vdur: vdur['vdu-id-ref'] == vnf_monitoring_param
- ['vdu-monitoring-param']
- ['vdu-ref'],
- vdurs
- )
- )
- elif 'vdu-metric' in vnf_monitoring_param:
- monitored_vdurs = list(
- filter(
- lambda vdur: vdur['vdu-id-ref'] == vnf_monitoring_param
- ['vdu-metric']
- ['vdu-ref'],
- vdurs
- )
- )
- elif 'vnf-metric' in vnf_monitoring_param:
- vdu = VnfdUtils.get_mgmt_vdu(vnfd)
- monitored_vdurs = list(
- filter(
- lambda vdur: vdur['vdu-id-ref'] == vdu['id'],
- vdurs
- )
- )
- else:
+ def _get_monitored_vdurs(self, scaling_aspect: dict, vdurs):
+ all_monitored_vdus = set()
+ for delta in scaling_aspect.get('aspect-delta-details', {}).get('deltas', ()):
+ for vdu_delta in delta.get('vdu-delta', ()):
+ all_monitored_vdus.add(vdu_delta.get('id'))
+
+ monitored_vdurs = list(filter(lambda vdur: vdur['vdu-id-ref'] in all_monitored_vdus, vdurs))
+
+ if not monitored_vdurs:
log.warning(
"Scaling criteria is referring to a vnf-monitoring-param that does not "
"contain a reference to a vdu or vnf metric.")
return monitored_vdurs
- def _get_metric_name(self, vnf_monitoring_param: dict, vdur: dict, vnfd: dict):
- vdu = next(
- filter(lambda vdu: vdu['id'] == vdur['vdu-id-ref'], vnfd['vdu'])
- )
- if 'vdu-monitoring-param' in vnf_monitoring_param:
- vdu_monitoring_param = next(filter(
- lambda param: param['id'] == vnf_monitoring_param['vdu-monitoring-param'][
- 'vdu-monitoring-param-ref'], vdu['monitoring-param']))
- nfvi_metric = vdu_monitoring_param['nfvi-metric']
- return nfvi_metric
- if 'vdu-metric' in vnf_monitoring_param:
- vnf_metric_name = vnf_monitoring_param['vdu-metric']['vdu-metric-name-ref']
- return vnf_metric_name
- if 'vnf-metric' in vnf_monitoring_param:
- vnf_metric_name = vnf_monitoring_param['vnf-metric']['vnf-metric-name-ref']
- return vnf_metric_name
+ def _get_metric_name(self, vnf_monitoring_param: dict):
+ if 'performance-metric' in vnf_monitoring_param:
+ return vnf_monitoring_param['performance-metric']
raise ValueError('No metric name found for vnf_monitoring_param %s' % vnf_monitoring_param['id'])
return vnfr
def get_vnfrs(self, nsr_id: str):
- return [self.get_vnfr(nsr_id, member['member-vnf-index']) for member in
- self.get_nsr(nsr_id)['nsd']['constituent-vnfd']]
+ # TODO: Change for multiple DF support
+ nsr_nsd_df = self.get_nsr(nsr_id)['nsd'].get('df', [{}])[0]
+ all_nsd_member_vnf_index = [vnf.get('id') for vnf in nsr_nsd_df.get('vnf-profile', [])]
+ return [self.get_vnfr(nsr_id, member_index) for member_index in all_nsd_member_vnf_index]
def get_vnfd(self, vnfd_id: str):
vnfr = self.common_db.get_one("vnfds",
self.loop = loop
async def create_alarm(self, metric_name: str, ns_id: str, vdu_name: str, vnf_member_index: str, threshold: int,
- statistic: str, operation: str):
+ operation: str, statistic: str = 'AVERAGE'):
cor_id = random.randint(1, 10e7)
msg = self._build_create_alarm_payload(cor_id,
metric_name,
"ssh-authorized-key": None,
"name-ref": "cirros_ns",
"nsd": {
- "name": "cirros_vdu_scaling_ns",
"_id": "d7c8bd3c-eb39-4514-8847-19f01345524f",
- "vld": [
- {
- "id": "cirros_nsd_vld1",
- "name": "cirros_nsd_vld1",
- "type": "ELAN",
- "mgmt-network": "true",
- "vnfd-connection-point-ref": [
- {
- "vnfd-id-ref": "cirros_vdu_scaling_vnf",
- "member-vnf-index-ref": 1,
- "vnfd-connection-point-ref": "eth0"
- },
- {
- "vnfd-id-ref": "cirros_vdu_scaling_vnf",
- "member-vnf-index-ref": 2,
- "vnfd-connection-point-ref": "eth0"
- }
- ]
- }
- ],
- "vendor": "OSM",
- "constituent-vnfd": [
- {
- "member-vnf-index": "1",
- "vnfd-id-ref": "cirros_vdu_scaling_vnf"
- },
- {
- "member-vnf-index": "2",
- "vnfd-id-ref": "cirros_vdu_scaling_vnf"
- }
- ],
- "version": "1.0",
- "id": "cirros_vdu_scaling_ns",
- "description": "Simple NS example with a cirros_vdu_scaling_vnf",
- "logo": "osm.png",
"_admin": {
"created": 1535392246.499733,
"userDefinedData": {
"admin"
]
},
- "short-name": "cirros_vdu_scaling_ns"
+ "id": "cirros_vdu_scaling_ns",
+ "name": "cirros_vdu_scaling_ns",
+ "description": "Simple NS example with a cirros_vdu_scaling_vnf",
+ "designer": "OSM", "version": "1.0",
+ "vnfd-id": ["cirros_vdu_scaling_vnf"],
+ "df": [{
+ "id": "default-df",
+ "vnf-profile": [
+ {
+ "id": "1",
+ "vnfd-id": "cirros_vdu_scaling_vnf",
+ "virtual-link-connectivity": [{
+ "virtual-link-profile-id": "cirros_nsd_vld1",
+ "constituent-cpd-id": [{
+ "constituent-base-element-id": "1",
+ "constituent-cpd-id": "eth0-ext"
+ }]
+ }]
+ }, {
+ "id": "2",
+ "vnfd-id": "cirros_vdu_scaling_vnf",
+ "virtual-link-connectivity": [{
+ "virtual-link-profile-id": "cirros_nsd_vld1",
+ "constituent-cpd-id": [{
+ "constituent-base-element-id": "2",
+ "constituent-cpd-id": "eth0-ext"
+ }]
+ }]
+ }
+ ]
+ }],
+ "virtual-link-desc": [{
+ "id": "cirros_nsd_vld1", "mgmt-network": "true"
+ }]
},
"id": "87776f33-b67c-417a-8119-cb08e4098951",
"config-status": "configured",
}
]}]
-nsd_record_mock = {'name': 'cirros_vdu_scaling_ns',
- 'version': '1.0',
- 'short-name': 'cirros_vdu_scaling_ns',
- 'logo': 'osm.png',
- 'id': 'cirros_vdu_scaling_ns',
- 'description': 'Simple NS example with a cirros_vdu_scaling_vnf',
- 'vendor': 'OSM',
- 'vld': [
- {'name': 'cirros_nsd_vld1',
- 'type': 'ELAN',
- 'id': 'cirros_nsd_vld1',
- 'mgmt-network': 'true',
- 'vnfd-connection-point-ref': [
- {'vnfd-id-ref': 'cirros_vdu_scaling_vnf',
- 'vnfd-connection-point-ref': 'eth0',
- 'member-vnf-index-ref': 1},
- {'vnfd-id-ref': 'cirros_vdu_scaling_vnf',
- 'vnfd-connection-point-ref': 'eth0',
- 'member-vnf-index-ref': 2}]}],
- 'constituent-vnfd': [{'vnfd-id-ref': 'cirros_vdu_scaling_vnf',
- 'member-vnf-index': '1'},
- {'vnfd-id-ref': 'cirros_vdu_scaling_vnf',
- 'member-vnf-index': '2'}]}
+nsd_record_mock = {
+ 'id': 'cirros_vdu_scaling_ns',
+ 'name': 'cirros_vdu_scaling_ns',
+ 'description': 'Simple NS example with a cirros_vdu_scaling_vnf',
+ 'designer': 'OSM',
+ 'version': '1.0',
+ 'vnfd-id': ['cirros_vdu_scaling_vnf'],
+ 'df': [{
+ 'id': 'default-df',
+ 'vnf-profile': [
+ {
+ 'id': '1',
+ 'vnfd-id': 'cirros_vdu_scaling_vnf',
+ 'virtual-link-connectivity': [{
+ 'virtual-link-profile-id': 'cirros_nsd_vld1',
+ 'constituent-cpd-id': [{
+ 'constituent-base-element-id': '1',
+ 'constituent-cpd-id': 'eth0-ext'
+ }]
+ }]
+ }, {
+ 'id': '2',
+ 'vnfd-id': 'cirros_vdu_scaling_vnf',
+ 'virtual-link-connectivity': [{
+ 'virtual-link-profile-id': 'cirros_nsd_vld1',
+ 'constituent-cpd-id': [{
+ 'constituent-base-element-id': '2',
+ 'constituent-cpd-id': 'eth0-ext'
+ }]
+ }]
+ }
+ ]
+ }],
+ 'virtual-link-desc': [{
+ 'id': 'cirros_nsd_vld1',
+ 'mgmt-network': 'true'
+ }]
+}
+
vnfd_record_mock = {
+ 'id': 'cirros_vdu_scaling_vnf',
"_id": "63f44c41-45ee-456b-b10d-5f08fb1796e0",
- "name": "cirros_vdu_scaling_vnf",
- "vendor": "OSM",
- "vdu": [
- {
- "name": "cirros_vnfd-VM",
- "monitoring-param": [
- {
- "id": "cirros_vnfd-VM_memory_util",
- "nfvi-metric": "average_memory_utilization"
- }
- ],
- "vm-flavor": {
- "vcpu-count": 1,
- "memory-mb": 256,
- "storage-gb": 2
- },
- "description": "cirros_vnfd-VM",
- "count": 1,
- "id": "cirros_vnfd-VM",
- "interface": [
- {
- "name": "eth0",
- "external-connection-point-ref": "eth0",
- "type": "EXTERNAL",
- "virtual-interface": {
- "bandwidth": "0",
- "type": "VIRTIO",
- "vpci": "0000:00:0a.0"
- }
- }
- ],
- "image": "cirros034",
- "alarm": [
- {
- "value": 20.0000,
- "actions": {
- "insufficient-data": [
- {
- "url": "localhost:9090"
- }
- ],
- "ok": [
- {
- "url": "localhost:9090"
- }
- ],
- "alarm": [
- {
- "url": "localhost:9090"
- }
- ]
- },
- "alarm-id": "alarm-1",
- "operation": "LT",
- "vnf-monitoring-param-ref": "cirros_vnf_memory_util"
- }
- ]
+ 'product-name': 'cirros_vdu_scaling_vnf',
+ 'description': 'Simple VNF example with a cirros and a scaling group descriptor',
+ 'provider': 'OSM',
+ 'version': '1.0',
+ 'mgmt-cp': 'eth0-ext',
+ 'virtual-storage-desc': [{
+ 'id': 'cirros_vnfd-VM-storage',
+ 'size-of-storage': 2
+ }],
+ 'virtual-compute-desc': [{
+ 'id': 'cirros_vnfd-VM-compute',
+ 'virtual-cpu': {
+ 'num-virtual-cpu': 1
+ },
+ 'virtual-memory': {
+ 'size': 0.25
}
- ],
- "monitoring-param": [
- {
- "id": "cirros_vnf_memory_util",
- "name": "cirros_vnf_memory_util",
- "aggregation-type": "AVERAGE",
- "vdu-monitoring-param": {
- "vdu-monitoring-param-ref": "cirros_vnfd-VM_memory_util",
- "vdu-ref": "cirros_vnfd-VM"
+ }],
+ 'sw-image-desc': [{
+ 'id': 'cirros034',
+ 'name': 'cirros034',
+ 'image': 'cirros034'
+ }],
+ 'vdu': [{
+ 'id': 'cirros_vnfd-VM',
+ 'description': 'cirros_vnfd-VM',
+ 'name': 'cirros_vnfd-VM',
+ 'alarm': [{
+ 'value': 20.0,
+ 'actions': {
+ 'insufficient-data': [{
+ 'url': 'localhost:9090'
+ }],
+ 'ok': [{
+ 'url': 'localhost:9090'
+ }],
+ 'alarm': [{
+ 'url': 'localhost:9090'
+ }]
+ },
+ 'alarm-id': 'alarm-1',
+ 'operation': 'LT',
+ 'vnf-monitoring-param-ref': 'cirros_vnf_memory_util'
+ }],
+ 'sw-image-desc': 'cirros034',
+ 'virtual-compute-desc': 'cirros_vnfd-VM-compute',
+ 'virtual-storage-desc': ['cirros_vnfd-VM-storage'],
+ 'int-cpd': [{
+ 'id': 'eth0-int',
+ 'virtual-network-interface-requirement': [{
+ 'name': 'eth0',
+ 'virtual-interface': {
+ 'bandwidth': '0',
+ 'type': 'VIRTIO',
+ 'vpci': '0000:00:0a.0'}
+ }]
+ }],
+ 'monitoring-parameter': [{
+ 'id': 'cirros_vnf_memory_util',
+ 'name': 'cirros_vnf_memory_util',
+ 'performance-metric': 'average_memory_utilization'
+ }]
+ }],
+ 'df': [{
+ 'id': 'default-df',
+ 'vdu-profile': [{
+ 'id': 'cirros_vnfd-VM',
+ 'min-number-of-instances': 1,
+ 'max-number-of-instances': 10,
+ 'vdu-configuration-id': 'cirros_vnfd-VM-vdu-configuration'
+ }],
+ 'instantiation-level': [{
+ 'id': 'default-instantiation-level',
+ 'vdu-level': [{
+ 'vdu-id': 'cirros_vnfd-VM',
+ 'number-of-instances': 1}]
+ }],
+ 'scaling-aspect': [{
+ 'id': 'scale_cirros_vnfd-VM',
+ 'name': 'scale_cirros_vnfd-VM',
+ 'max-scale-level': 10,
+ 'scaling-policy': [{
+ 'name': 'auto_memory_util_above_threshold',
+ 'scaling-type': 'automatic',
+ 'cooldown-time': 60,
+ 'threshold-time': 10,
+ 'scaling-criteria': [{
+ 'name': 'group1_memory_util_above_threshold',
+ 'vnf-monitoring-param-ref': 'cirros_vnf_memory_util',
+ 'scale-out-threshold': 80,
+ 'scale-out-relational-operation': 'GT',
+ 'scale-in-relational-operation': 'LT',
+ 'scale-in-threshold': 20
+ }]
+ }],
+ 'aspect-delta-details': {
+ 'deltas': [{
+ 'id': 'scale_cirros_vnfd-VM-delta',
+ 'vdu-delta': [{
+ 'number-of-instances': 1,
+ 'id': 'cirros_vnfd-VM'}]
+ }]
}
- },
- {
- "id": "haproxy_users",
- "name": "haproxy_users",
- "aggregation-type": "AVERAGE",
- "vnf-metric":
- {"vnf-metric-name-ref": "users"}
+ }]
+ }],
+ 'ext-cpd': [{
+ 'id': 'eth0-ext',
+ 'int-cpd': {
+ 'vdu-id': 'cirros_vnfd-VM',
+ 'cpd': 'eth0-int'
}
- ],
- "vdu-configuration": {
- "juju": {
- "charm": "testmetrics",
- "proxy": True
+ }],
+ 'vdu-configuration': [{
+ 'juju': {
+ 'charm': 'testmetrics',
+ 'proxy': True
},
- "metrics": {
- "name": "users"
- }
- },
- "description": "Simple VNF example with a cirros and a scaling group descriptor",
- "id": "cirros_vdu_scaling_vnf",
- "logo": "cirros-64.png",
- "version": "1.0",
- "connection-point": [
- {
- "name": "eth0",
- "type": "VPORT"
- }
- ],
- "mgmt-interface": {
- "cp": "eth0"
- },
- "scaling-group-descriptor": [
- {
- "name": "scale_cirros_vnfd-VM",
- "min-instance-count": 1,
- "vdu": [
- {
- "count": 1,
- "vdu-id-ref": "cirros_vnfd-VM"
- }
- ],
- "max-instance-count": 10,
- "scaling-policy": [
- {
- "name": "auto_memory_util_above_threshold",
- "scaling-type": "automatic",
- "cooldown-time": 60,
- "threshold-time": 10,
- "scaling-criteria": [
- {
- "name": "group1_memory_util_above_threshold",
- "vnf-monitoring-param-ref": "cirros_vnf_memory_util",
- "scale-out-threshold": 80,
- "scale-out-relational-operation": "GT",
- "scale-in-relational-operation": "LT",
- "scale-in-threshold": 20
- }
- ]
- }
- ]
- }
- ],
- "short-name": "cirros_vdu_scaling_vnf",
+ 'metrics': [{
+ 'name': 'users'
+ }],
+ 'id': 'cirros_vnfd-VM-vdu-configuration'
+ }],
"_admin": {
"created": 1535392242.6281035,
"modified": 1535392242.6281035,
create_alarm.assert_any_call(metric_name='average_memory_utilization',
ns_id='test_nsr_id',
operation='GT',
- statistic='AVERAGE',
threshold=80,
vdu_name='cirros_ns-1-cirros_vnfd-VM-1',
vnf_member_index='1')
create_alarm.assert_not_called_with(metric_name='average_memory_utilization',
ns_id='test_nsr_id',
operation='LT',
- statistic='AVERAGE',
threshold=20,
vdu_name='cirros_ns-1-cirros_vnfd-VM-1',
vnf_member_index='1')
create_alarm.assert_any_call(metric_name='average_memory_utilization',
ns_id='test_nsr_id',
operation='GT',
- statistic='AVERAGE',
threshold=80,
vdu_name='cirros_ns-2-cirros_vnfd-VM-1',
vnf_member_index='2')
create_alarm.assert_not_called_with(metric_name='average_memory_utilization',
ns_id='test_nsr_id',
operation='LT',
- statistic='AVERAGE',
threshold=20,
vdu_name='cirros_ns-2-cirros_vnfd-VM-1',
vnf_member_index='2')
vdu_name='cirros_ns-1-cirros_vnfd-VM-1',
vnf_member_index='1',
threshold=20.0,
- operation='LT',
- statistic='AVERAGE')
+ operation='LT')
create_alarm.assert_any_call(metric_name='average_memory_utilization',
ns_id='test_nsr_id',
vdu_name='cirros_ns-2-cirros_vnfd-VM-1',
vnf_member_index='2',
threshold=20.0,
- operation='LT',
- statistic='AVERAGE')
+ operation='LT')
if __name__ == '__main__':
-nsd:nsd-catalog:
- nsd:
- - id: cirros_vdu_scaling_ns
- name: cirros_vdu_scaling_ns
- short-name: cirros_vdu_scaling_ns
- description: Simple NS example with a cirros_vdu_scaling_vnf
- vendor: OSM
- version: '1.0'
-
- # Place the logo as png in icons directory and provide the name here
- logo: osm.png
-
- # Specify the VNFDs that are part of this NSD
- constituent-vnfd:
- # The member-vnf-index needs to be unique, starting from 1
- # vnfd-id-ref is the id of the VNFD
- # Multiple constituent VNFDs can be specified
- - member-vnf-index: '1'
- vnfd-id-ref: cirros_vdu_scaling_vnf
- - member-vnf-index: '2'
- vnfd-id-ref: cirros_vdu_scaling_vnf
- vld:
- # Networks for the VNFs
- - id: cirros_nsd_vld1
- name: cirros_nsd_vld1
- type: ELAN
- mgmt-network: 'true'
- # vim-network-name: <update>
- # provider-network:
- # segmentation_id: <update>
- vnfd-connection-point-ref:
- # Specify the constituent VNFs
- # member-vnf-index-ref - entry from constituent vnf
- # vnfd-id-ref - VNFD id
- # vnfd-connection-point-ref - connection point name in the VNFD
- - member-vnf-index-ref: 1
- vnfd-id-ref: cirros_vdu_scaling_vnf
- # NOTE: Validate the entry below
- vnfd-connection-point-ref: eth0
- - member-vnf-index-ref: 2
- vnfd-id-ref: cirros_vdu_scaling_vnf
- vnfd-connection-point-ref: eth0
\ No newline at end of file
+# -*- coding: utf-8 -*-
+# pylint: disable=no-member
+
+# Copyright 2020 Whitestack, LLC
+# *************************************************************
+
+# This file is part of OSM Monitoring module
+# All Rights Reserved to Whitestack, LLC
+
+# 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.
+
+# For those usages not covered by the Apache License, Version 2.0 please
+# contact: agarcia@whitestack.com
+##
+
+nsd:
+ nsd:
+ - id: cirros_vdu_scaling_ns
+ name: cirros_vdu_scaling_ns
+ description: Simple NS example with a cirros_vdu_scaling_vnf
+ designer: OSM
+ version: '1.0'
+
+ df:
+ - id: default-df
+ vnf-profile:
+ - id: '1'
+ virtual-link-connectivity:
+ - constituent-cpd-id:
+ - constituent-base-element-id: '1'
+ constituent-cpd-id: eth0-ext
+ virtual-link-profile-id: cirros_nsd_vld1
+ vnfd-id: cirros_vdu_scaling_vnf
+ - id: '2'
+ virtual-link-connectivity:
+ - constituent-cpd-id:
+ - constituent-base-element-id: '2'
+ constituent-cpd-id: eth0-ext
+ virtual-link-profile-id: cirros_nsd_vld1
+ vnfd-id: cirros_vdu_scaling_vnf
+
+ virtual-link-desc:
+ - id: cirros_nsd_vld1
+ mgmt-network: 'true'
+ vnfd-id:
+ - cirros_vdu_scaling_vnf
--- /dev/null
+# -*- coding: utf-8 -*-
+# pylint: disable=no-member
+
+# Copyright 2020 Whitestack, LLC
+# *************************************************************
+
+# This file is part of OSM Monitoring module
+# All Rights Reserved to Whitestack, LLC
+
+# 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.
+
+# For those usages not covered by the Apache License, Version 2.0 please
+# contact: agarcia@whitestack.com
+##
+
+vnfd:
+ id: cirros_vdu_scaling_vnf
+ product-name: cirros_vdu_scaling_vnf
+ description: Simple VNF example with a cirros and a scaling group descriptor
+ provider: OSM
+ version: '1.0'
+ mgmt-cp: eth0-ext
+
+ ext-cpd:
+ - id: eth0-ext
+ int-cpd:
+ cpd: eth0-int
+ vdu-id: cirros_vnfd-VM
+
+ df:
+ - id: default-df
+ instantiation-level:
+ - id: default-instantiation-level
+ vdu-level:
+ - number-of-instances: 1
+ vdu-id: cirros_vnfd-VM
+ scaling-aspect:
+ - id: scale_cirros_vnfd-VM
+ name: scale_cirros_vnfd-VM
+ aspect-delta-details:
+ deltas:
+ - id: scale_cirros_vnfd-VM-delta
+ vdu-delta:
+ - id: cirros_vnfd-VM
+ number-of-instances: 1
+ max-scale-level: 10
+ scaling-policy:
+ - name: auto_cpu_util_above_threshold
+ cooldown-time: 60
+ scaling-criteria:
+ - name: group1_cpu_util_above_threshold
+ scale-in-relational-operation: LT
+ scale-in-threshold: 20
+ scale-out-relational-operation: GT
+ scale-out-threshold: 80
+ vnf-monitoring-param-ref: cirros_vnf_cpu_util
+ scaling-type: automatic
+ threshold-time: 10
+ vdu-profile:
+ - id: cirros_vnfd-VM
+ max-number-of-instances: 10
+ min-number-of-instances: 1
+
+ vdu:
+ - id: cirros_vnfd-VM
+ name: cirros_vnfd-VM
+ description: cirros_vnfd-VM
+ int-cpd:
+ - id: eth0-int
+ virtual-network-interface-requirement:
+ - name: eth0
+ virtual-interface:
+ bandwidth: '0'
+ type: VIRTIO
+ vpci: 0000:00:0a.0
+ monitoring-parameter:
+ - id: cirros_vnf_cpu_util
+ name: cirros_vnf_cpu_util
+ performance-metric: cpu_utilization
+ sw-image-desc: cirros034
+ virtual-compute-desc: cirros_vnfd-VM-compute
+ virtual-storage-desc:
+ - cirros_vnfd-VM-storage
+
+ sw-image-desc:
+ - id: cirros034
+ name: cirros034
+ image: cirros034
+
+ virtual-compute-desc:
+ - id: cirros_vnfd-VM-compute
+ virtual-cpu:
+ num-virtual-cpu: 1
+ virtual-memory:
+ size: 0.25
+
+ virtual-storage-desc:
+ - id: cirros_vnfd-VM-storage
+ size-of-storage: 2
+++ /dev/null
-vnfd:vnfd-catalog:
- vnfd:
- - id: cirros_vdu_scaling_vnf
- name: cirros_vdu_scaling_vnf
- short-name: cirros_vdu_scaling_vnf
- description: Simple VNF example with a cirros and a scaling group descriptor
- vendor: OSM
- version: '1.0'
- # Place the logo as png in icons directory and provide the name here
- logo: cirros-64.png
- # Management interface
- mgmt-interface:
- cp: eth0
- # Atleast one VDU need to be specified
- vdu:
- - id: cirros_vnfd-VM
- name: cirros_vnfd-VM
- description: cirros_vnfd-VM
- count: 1
-
- # Flavour of the VM to be instantiated for the VDU
- # flavor below can fit into m1.micro
- vm-flavor:
- vcpu-count: 1
- memory-mb: 256
- storage-gb: 2
- # Image/checksum or image including the full path
- image: 'cirros034'
- #checksum:
- interface:
- # Specify the external interfaces
- # There can be multiple interfaces defined
- - name: eth0
- type: EXTERNAL
- virtual-interface:
- type: VIRTIO
- bandwidth: '0'
- vpci: 0000:00:0a.0
- external-connection-point-ref: eth0
- monitoring-param:
- - id: "cirros_vnfd-VM_cpu_util"
- nfvi-metric: "cpu_utilization" # The associated NFVI metric to be monitored. Id of the metric
- #interface-name-ref: reference to interface name, required for some metrics
- connection-point:
- - name: eth0
- type: VPORT
- scaling-group-descriptor:
- - name: "scale_cirros_vnfd-VM"
- min-instance-count: 1
- max-instance-count: 10
- scaling-policy:
- - name: "auto_cpu_util_above_threshold"
- scaling-type: "automatic"
- threshold-time: 10
- cooldown-time: 60
- scaling-criteria:
- - name: "group1_cpu_util_above_threshold"
- scale-in-threshold: 20
- scale-in-relational-operation: "LT"
- scale-out-threshold: 80
- scale-out-relational-operation: "GT"
- vnf-monitoring-param-ref: "cirros_vnf_cpu_util"
- vdu:
- - vdu-id-ref: cirros_vnfd-VM
- count: 1
- # scaling-config-action: # Para utilizar charms
- # - trigger: post-scale-out
- # vnf-config-primitive-name-ref:
- monitoring-param:
- - id: "cirros_vnf_cpu_util"
- name: "cirros_vnf_cpu_util"
- aggregation-type: AVERAGE
- vdu-monitoring-param:
- vdu-ref: "cirros_vnfd-VM"
- vdu-monitoring-param-ref: "cirros_vnfd-VM_cpu_util"
\ No newline at end of file
+++ /dev/null
-vnfd:vnfd-catalog:
- vnfd:
- - id: cirros_vdu_scaling_vnf
- name: cirros_vdu_scaling_vnf
- short-name: cirros_vdu_scaling_vnf
- description: Simple VNF example with a cirros and a scaling group descriptor
- vendor: OSM
- version: '1.0'
- # Place the logo as png in icons directory and provide the name here
- logo: cirros-64.png
- # Management vdu id
- mgmt-interface:
- vdu-id: cirros_vnfd-VM
- # Atleast one VDU need to be specified
- vdu:
- - id: cirros_vnfd-VM
- name: cirros_vnfd-VM
- description: cirros_vnfd-VM
- count: 1
-
- # Flavour of the VM to be instantiated for the VDU
- # flavor below can fit into m1.micro
- vm-flavor:
- vcpu-count: 1
- memory-mb: 256
- storage-gb: 2
- # Image/checksum or image including the full path
- image: 'cirros034'
- #checksum:
- interface:
- # Specify the external interfaces
- # There can be multiple interfaces defined
- - name: eth0
- type: EXTERNAL
- virtual-interface:
- type: VIRTIO
- bandwidth: '0'
- vpci: 0000:00:0a.0
- external-connection-point-ref: eth0
- monitoring-param:
- - id: "cirros_vnfd-VM_cpu_util"
- nfvi-metric: "cpu_utilization" # The associated NFVI metric to be monitored. Id of the metric
- #interface-name-ref: reference to interface name, required for some metrics
- connection-point:
- - name: eth0
- type: VPORT
- scaling-group-descriptor:
- - name: "scale_cirros_vnfd-VM"
- min-instance-count: 1
- max-instance-count: 10
- scaling-policy:
- - name: "auto_cpu_util_above_threshold"
- scaling-type: "automatic"
- threshold-time: 10
- cooldown-time: 60
- scaling-criteria:
- - name: "group1_cpu_util_above_threshold"
- scale-in-threshold: 20
- scale-in-relational-operation: "LT"
- scale-out-threshold: 80
- scale-out-relational-operation: "GT"
- vnf-monitoring-param-ref: "cirros_vnf_cpu_util"
- vdu:
- - vdu-id-ref: cirros_vnfd-VM
- count: 1
- # scaling-config-action: # Para utilizar charms
- # - trigger: post-scale-out
- # vnf-config-primitive-name-ref:
- monitoring-param:
- - id: "cirros_vnf_cpu_util"
- name: "cirros_vnf_cpu_util"
- aggregation-type: AVERAGE
- vdu-monitoring-param:
- vdu-ref: "cirros_vnfd-VM"
- vdu-monitoring-param-ref: "cirros_vnfd-VM_cpu_util"
\ No newline at end of file
##
import os
import unittest
-
import yaml
from osm_policy_module.utils.vnfd import VnfdUtils
+from osm_policy_module.core.exceptions import ManagementVduNotFound
class VnfdUtilsTest(unittest.TestCase):
- def test_get_mgmt_vdu_by_cp(self):
- with open(
- os.path.join(os.path.dirname(__file__), 'examples/cirros_vdu_scaling_vnfd_1.yaml'), 'r') as file:
- vnfd = yaml.safe_load(file)['vnfd:vnfd-catalog']['vnfd'][0]
+ def test_get_mgmt_vdu_on_valid_descriptor(self):
+ example_file = os.path.join(os.path.dirname(__file__), 'examples/cirros_vdu_scaling_vnfd.yaml')
+ with open(example_file, 'r') as file:
+ vnfd = yaml.safe_load(file)['vnfd']
vdu = VnfdUtils.get_mgmt_vdu(vnfd)
self.assertEqual(vdu['id'], 'cirros_vnfd-VM')
- def test_get_mgmt_vdu_by_id(self):
- with open(
- os.path.join(os.path.dirname(__file__), 'examples/cirros_vdu_scaling_vnfd_2.yaml'), 'r') as file:
- vnfd = yaml.safe_load(file)['vnfd:vnfd-catalog']['vnfd'][0]
- vdu = VnfdUtils.get_mgmt_vdu(vnfd)
- self.assertEqual(vdu['id'], 'cirros_vnfd-VM')
+ def test_get_mgmt_vdu_on_invalid_descriptor(self):
+ example_file = os.path.join(os.path.dirname(__file__), 'examples/cirros_vdu_scaling_vnfd.yaml')
+ with open(example_file, 'r') as file:
+ vnfd = yaml.safe_load(file)['vnfd']
+ vnfd['mgmt-cp'] = 'invalid-cp'
+ with self.assertRaises(ManagementVduNotFound):
+ VnfdUtils.get_mgmt_vdu(vnfd)
@staticmethod
def get_mgmt_vdu(vnfd: dict):
- if 'cp' in vnfd['mgmt-interface']:
- for vdu in vnfd['vdu']:
- for interface in vdu['interface']:
- if 'external-connection-point-ref' in interface:
- if interface['external-connection-point-ref'] == vnfd['mgmt-interface']['cp']:
- return vdu
- elif 'vdu-id' in vnfd['mgmt-interface']:
- for vdu in vnfd['vdu']:
- if vdu['id'] == vnfd['mgmt-interface']['vdu-id']:
+ if 'mgmt-cp' in vnfd:
+ mgmt_cp = vnfd['mgmt-cp']
+ mgmt_cp_vdu_id = None
+ for cpd in vnfd.get('ext-cpd', ()):
+ if cpd.get('id') == mgmt_cp:
+ mgmt_cp_vdu_id = cpd.get('int-cpd', {}).get('vdu-id')
+ for vdu in vnfd.get('vdu', ()):
+ if vdu.get('id') == mgmt_cp_vdu_id:
return vdu
- raise ManagementVduNotFound("Management vdu not founr in vnfd %s", vnfd['id'])
+ raise ManagementVduNotFound("Management vdu not found in vnfd %s", vnfd['id'])
# test suite on all supported python versions. To use it, "pip install tox"
# and then run "tox" from this directory.
[tox]
-envlist = cover, flake8, pylint
+envlist = cover, flake8
[testenv]