4 # Copyright 2016 RIFT.IO Inc
6 # Licensed under the Apache License, Version 2.0 (the "License");
7 # you may not use this file except in compliance with the License.
8 # You may obtain a copy of the License at
10 # http://www.apache.org/licenses/LICENSE-2.0
12 # Unless required by applicable law or agreed to in writing, software
13 # distributed under the License is distributed on an "AS IS" BASIS,
14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 # See the License for the specific language governing permissions and
16 # limitations under the License.
27 gi
.require_version('RwYang', '1.0')
28 gi
.require_version('RwVnfdYang', '1.0')
29 gi
.require_version('VnfdYang', '1.0')
30 gi
.require_version('RwNsdYang', '1.0')
31 gi
.require_version('NsdYang', '1.0')
34 from gi
.repository
import (
44 import rift
.mano
.config_data
.config
as config_data
46 # Load modules from common which are not yet installed
47 path
= os
.path
.abspath(os
.path
.dirname(os
.path
.abspath(__file__
)) + "../../../common/python/rift/mano")
50 import config_data
.config
as config_data
53 NUM_PING_INSTANCES
= 1
54 MAX_VNF_INSTANCES_PER_NS
= 10
57 pingcount
= NUM_PING_INSTANCES
58 use_ping_cloud_init_file
= ""
59 use_pong_cloud_init_file
= ""
61 PING_USERDATA_FILE
= '''#cloud-config
63 chpasswd: { expire: False }
66 - [ systemctl, daemon-reload ]
67 - [ systemctl, enable, ping.service ]
68 - [ systemctl, start, --no-block, ping.service ]
72 PONG_USERDATA_FILE
= '''#cloud-config
74 chpasswd: { expire: False }
77 - [ systemctl, daemon-reload ]
78 - [ systemctl, enable, pong.service ]
79 - [ systemctl, start, --no-block, pong.service ]
84 class UnknownVNFError(Exception):
88 class ManoDescriptor(object):
89 def __init__(self
, name
):
91 self
.descriptor
= None
93 def write_to_file(self
, module_list
, outdir
, output_format
):
94 model
= RwYang
.Model
.create_libncx()
95 for module
in module_list
:
96 model
.load_module(module
)
98 if output_format
== 'json':
99 with
open('%s/%s.json' % (outdir
, self
.name
), "w") as fh
:
100 fh
.write(self
.descriptor
.to_json(model
))
101 elif output_format
.strip() == 'xml':
102 with
open('%s/%s.xml' % (outdir
, self
.name
), "w") as fh
:
103 fh
.write(self
.descriptor
.to_xml_v2(model
))
104 elif output_format
.strip() == 'yaml':
105 with
open('%s/%s.yaml' % (outdir
, self
.name
), "w") as fh
:
106 fh
.write(self
.descriptor
.to_yaml(model
))
108 raise Exception("Invalid output format for the descriptor")
110 def get_json(self
, module_list
):
111 model
= RwYang
.Model
.create_libncx()
112 for module
in module_list
:
113 model
.load_module(module
)
114 print(self
.descriptor
.to_json(model
))
117 class VirtualNetworkFunction(ManoDescriptor
):
118 def __init__(self
, name
, instance_count
=1):
119 self
.vnfd_catalog
= None
121 self
.instance_count
= instance_count
122 self
._placement
_groups
= []
123 self
.use_vnf_init_conf
= False
124 super(VirtualNetworkFunction
, self
).__init
__(name
)
126 def add_placement_group(self
, group
):
127 self
._placement
_groups
.append(group
)
129 def compose(self
, image_name
, cloud_init
="", cloud_init_file
="", endpoint
=None, mon_params
=[],
130 mon_port
=8888, mgmt_port
=8888, num_vlr_count
=1, num_ivlr_count
=1,
131 num_vms
=1, image_md5sum
=None, mano_ut
=False):
132 self
.descriptor
= RwVnfdYang
.YangData_Vnfd_VnfdCatalog()
133 self
.id = str(uuid
.uuid1())
134 vnfd
= self
.descriptor
.vnfd
.add()
136 vnfd
.name
= self
.name
137 vnfd
.short_name
= self
.name
138 vnfd
.vendor
= 'RIFT.io'
139 vnfd
.logo
= 'rift_logo.png'
140 vnfd
.description
= 'This is an example RIFT.ware VNF'
147 for i
in range(num_ivlr_count
):
148 internal_vld
= vnfd
.internal_vld
.add()
149 internal_vld
.id = 'ivld%s' % i
150 internal_vld
.name
= 'fabric%s' % i
151 internal_vld
.short_name
= 'fabric%s' % i
152 internal_vld
.description
= 'Virtual link for internal fabric%s' % i
153 internal_vld
.type_yang
= 'ELAN'
154 internal_vlds
.append(internal_vld
)
156 for i
in range(num_vlr_count
):
157 cp
= vnfd
.connection_point
.add()
158 cp
.type_yang
= 'VPORT'
159 cp
.name
= '%s/cp%d' % (self
.name
, i
)
161 if endpoint
is not None:
162 endp
= VnfdYang
.YangData_Vnfd_VnfdCatalog_Vnfd_HttpEndpoint(
163 path
=endpoint
, port
=mon_port
, polling_interval_secs
=2
165 vnfd
.http_endpoint
.append(endp
)
168 for monp_dict
in mon_params
:
169 monp
= VnfdYang
.YangData_Vnfd_VnfdCatalog_Vnfd_MonitoringParam
.from_dict(monp_dict
)
170 monp
.http_endpoint_ref
= endpoint
171 vnfd
.monitoring_param
.append(monp
)
173 if 'pong_' in self
.name
:
174 self
.add_pong_config()
176 self
.add_ping_config()
178 for i
in range(num_vms
):
181 vdu
.id = 'iovdu_%s' % i
182 vdu
.name
= 'iovdu_%s' % i
184 # vdu.mgmt_vpci = '0000:00:20.0'
186 # specify the VM flavor
188 vdu
.vm_flavor
.vcpu_count
= 4
189 vdu
.vm_flavor
.memory_mb
= 1024
190 vdu
.vm_flavor
.storage_gb
= 4
192 vdu
.vm_flavor
.vcpu_count
= 1
193 vdu
.vm_flavor
.memory_mb
= 512
194 vdu
.vm_flavor
.storage_gb
= 4
196 # Management interface
197 mgmt_intf
= vnfd
.mgmt_interface
198 mgmt_intf
.vdu_id
= vdu
.id
199 mgmt_intf
.port
= mgmt_port
200 mgmt_intf
.dashboard_params
.path
= endpoint
201 mgmt_intf
.dashboard_params
.port
= mgmt_port
203 if cloud_init_file
and len(cloud_init_file
):
204 vdu
.cloud_init_file
= cloud_init_file
206 vdu
.cloud_init
= cloud_init
208 vdu
.cloud_init
+= " - [ systemctl, restart, --no-block, elastic-network-interfaces.service ]\n"
210 # sepcify the guest EPA
212 vdu
.guest_epa
.trusted_execution
= False
213 vdu
.guest_epa
.mempage_size
= 'LARGE'
214 vdu
.guest_epa
.cpu_pinning_policy
= 'DEDICATED'
215 vdu
.guest_epa
.cpu_thread_pinning_policy
= 'PREFER'
216 vdu
.guest_epa
.numa_node_policy
.node_cnt
= 2
217 vdu
.guest_epa
.numa_node_policy
.mem_policy
= 'STRICT'
219 node
= vdu
.guest_epa
.numa_node_policy
.node
.add()
222 vcpu
= node
.vcpu
.add()
224 vcpu
= node
.vcpu
.add()
227 node
= vdu
.guest_epa
.numa_node_policy
.node
.add()
230 vcpu
= node
.vcpu
.add()
232 vcpu
= node
.vcpu
.add()
235 # specify the vswitch EPA
236 vdu
.vswitch_epa
.ovs_acceleration
= 'DISABLED'
237 vdu
.vswitch_epa
.ovs_offload
= 'DISABLED'
239 # Specify the hypervisor EPA
240 vdu
.hypervisor_epa
.type_yang
= 'PREFER_KVM'
242 # Specify the host EPA
243 # vdu.host_epa.cpu_model = 'PREFER_SANDYBRIDGE'
244 # vdu.host_epa.cpu_arch = 'PREFER_X86_64'
245 # vdu.host_epa.cpu_vendor = 'PREFER_INTEL'
246 # vdu.host_epa.cpu_socket_count = 2
247 # vdu.host_epa.cpu_core_count = 8
248 # vdu.host_epa.cpu_core_thread_count = 2
249 # vdu.host_epa.cpu_feature = ['PREFER_AES', 'REQUIRE_VME', 'PREFER_MMX','REQUIRE_SSE2']
252 vdu
.image
= 'rift-ping-pong'
254 vdu
.image
= image_name
255 if image_md5sum
is not None:
256 vdu
.image_checksum
= image_md5sum
259 for i
in range(num_ivlr_count
):
260 internal_cp
= vdu
.internal_connection_point
.add()
261 if vnfd
.name
.find("ping") >= 0:
265 internal_cp
.name
= cp_name
+ "/icp{}".format(i
)
266 internal_cp
.id = cp_name
+ "/icp{}".format(i
)
267 internal_cp
.type_yang
= 'VPORT'
268 ivld_cp
= internal_vlds
[i
].internal_connection_point_ref
.add()
269 ivld_cp
.id_ref
= internal_cp
.id
271 internal_interface
= vdu
.internal_interface
.add()
272 internal_interface
.name
= 'fab%d' % i
273 internal_interface
.vdu_internal_connection_point_ref
= internal_cp
.id
274 internal_interface
.virtual_interface
.type_yang
= 'VIRTIO'
276 # internal_interface.virtual_interface.vpci = '0000:00:1%d.0'%i
278 for i
in range(num_vlr_count
):
279 external_interface
= vdu
.external_interface
.add()
280 external_interface
.name
= 'eth%d' % i
281 external_interface
.vnfd_connection_point_ref
= '%s/cp%d' % (self
.name
, i
)
283 external_interface
.virtual_interface
.type_yang
= 'VIRTIO'
285 external_interface
.virtual_interface
.type_yang
= 'VIRTIO'
286 # external_interface.virtual_interface.vpci = '0000:00:2%d.0'%i
288 for group
in self
._placement
_groups
:
289 placement_group
= vnfd
.placement_groups
.add()
290 placement_group
.name
= group
.name
291 placement_group
.requirement
= group
.requirement
292 placement_group
.strategy
= group
.strategy
294 ### Add specific VDUs to placement group
295 for vdu
in group
.vdu_list
:
296 member_vdu
= placement_group
.member_vdus
.add()
297 member_vdu
.member_vdu_ref
= vdu
.id
299 ### Add all VDUs to placement group
301 member_vdu
= placement_group
.member_vdus
.add()
302 member_vdu
.member_vdu_ref
= vdu
.id
305 def add_ping_config(self
):
306 vnfd
= self
.descriptor
.vnfd
[0]
307 # Add vnf configuration
308 vnf_config
= vnfd
.vnf_configuration
309 vnf_config
.script
.script_type
= 'python'
311 # Add initial config primitive
312 init_config
= VnfdYang
.InitialConfigPrimitive
.from_dict(
315 "name": "Ping config",
316 "user_defined_script": "ping_initial_config.py",
319 vnf_config
.initial_config_primitive
.append(init_config
)
321 def add_pong_config(self
):
322 vnfd
= self
.descriptor
.vnfd
[0]
323 # Add vnf configuration
324 vnf_config
= vnfd
.vnf_configuration
325 vnf_config
.script
.script_type
= 'python'
327 # Add initial config primitive
328 init_config
= VnfdYang
.InitialConfigPrimitive
.from_dict(
331 "name": "Pong config",
332 "user_defined_script": "pong_initial_config.py",
335 vnf_config
.initial_config_primitive
.append(init_config
)
337 def write_to_file(self
, outdir
, output_format
):
338 dirpath
= "%s/%s" % (outdir
, self
.name
)
339 if not os
.path
.exists(dirpath
):
341 super(VirtualNetworkFunction
, self
).write_to_file(['vnfd', 'rw-vnfd'],
344 self
.add_scripts(outdir
)
346 def add_scripts(self
, outdir
):
347 script_dir
= os
.path
.join(outdir
, self
.name
, 'cloud_init')
349 os
.makedirs(script_dir
)
351 if not os
.path
.isdir(script_dir
):
354 if 'ping' in self
.name
:
355 script_file
= os
.path
.join(script_dir
, 'ping_cloud_init.cfg')
356 cfg
= PING_USERDATA_FILE
358 script_file
= os
.path
.join(script_dir
, 'pong_cloud_init.cfg')
359 cfg
= PONG_USERDATA_FILE
361 with
open(script_file
, "w") as f
:
362 f
.write("{}".format(cfg
))
364 self
.add_config_scripts(outdir
)
366 # Copy the vnf_init_config script
367 if self
.use_vnf_init_conf
and ('ping' in self
.name
):
368 script_name
= 'ping_set_rate.py'
370 src_path
= os
.path
.dirname(os
.path
.abspath(os
.path
.realpath(__file__
)))
371 script_src
= os
.path
.join(src_path
, script_name
)
372 if not os
.path
.exists(script_src
):
373 src_path
= os
.path
.join(os
.environ
['RIFT_ROOT'],
374 'modules/core/mano/examples/ping_pong_ns/rift/mano/examples')
375 script_src
= os
.path
.join(src_path
, script_name
)
377 dest_path
= os
.path
.join(outdir
, self
.name
, 'scripts')
378 os
.makedirs(dest_path
, exist_ok
=True)
380 shutil
.copy2(script_src
, dest_path
)
382 def add_config_scripts(self
, outdir
):
383 dest_path
= os
.path
.join(outdir
, self
.name
, 'scripts')
385 os
.makedirs(dest_path
)
387 if not os
.path
.isdir(dest_path
):
390 if 'pong_' in self
.name
:
391 scripts
= ['pong_initial_config.py']
393 scripts
= ['ping_initial_config.py']
395 for script_name
in scripts
:
396 src_path
= os
.path
.dirname(os
.path
.abspath(
397 os
.path
.realpath(__file__
)))
398 script_src
= os
.path
.join(src_path
, script_name
)
399 if not os
.path
.exists(script_src
):
400 src_path
= os
.path
.join(os
.environ
['RIFT_ROOT'],
401 'modules/core/mano/examples/'
402 'ping_pong_ns/rift/mano/examples')
403 script_src
= os
.path
.join(src_path
, script_name
)
405 shutil
.copy2(script_src
, dest_path
)
408 class NetworkService(ManoDescriptor
):
409 def __init__(self
, name
):
410 super(NetworkService
, self
).__init
__(name
)
411 self
._scale
_groups
= []
412 self
.vnfd_config
= {}
413 self
._placement
_groups
= []
415 def default_config(self
, constituent_vnfd
, vnfd
, mano_ut
, use_ns_init_conf
, use_vnf_init_conf
):
416 vnf_config
= vnfd
.vnfd
.vnf_configuration
418 vnf_config
.config_attributes
.config_priority
= 0
419 vnf_config
.config_attributes
.config_delay
= 0
421 if vnfd
.name
== 'pong_vnfd' or vnfd
.name
== 'pong_vnfd_with_epa' or vnfd
.name
== 'pong_vnfd_aws':
422 vnf_config
.config_attributes
.config_priority
= 1
423 # First priority config delay will delay the entire NS config delay
425 vnf_config
.config_attributes
.config_delay
= 60
427 # This is PONG and inside mano_ut
429 vnf_config
.config_attributes
.config_delay
= 10
431 if vnfd
.name
== 'ping_vnfd' or vnfd
.name
== 'ping_vnfd_with_epa' or vnfd
.name
== 'ping_vnfd_aws':
432 vnf_config
.config_attributes
.config_priority
= 2
435 def ns_config(self
, nsd
, vnfd_list
, mano_ut
):
436 # Used by scale group
438 nsd
.service_primitive
.add().from_dict(
440 "name": "ping config",
441 "user_defined_script": "{}".format(os
.path
.join(
442 os
.environ
['RIFT_ROOT'],
444 'examples/ping_pong_ns/rift/mano/examples',
445 'ping_config_ut.sh'))
448 nsd
.service_primitive
.add().from_dict(
450 "name": "ping config",
451 "user_defined_script": "ping_config.py"
454 def ns_initial_config(self
, nsd
):
455 nsd
.initial_config_primitive
.add().from_dict(
458 "name": "start traffic",
459 "user_defined_script": "start_traffic.py",
469 def add_scale_group(self
, scale_group
):
470 self
._scale
_groups
.append(scale_group
)
472 def add_placement_group(self
, placement_group
):
473 self
._placement
_groups
.append(placement_group
)
475 def create_mon_params(self
, vnfds
):
476 NsdMonParam
= NsdYang
.YangData_Nsd_NsdCatalog_Nsd_MonitoringParam
478 for vnfd_obj
in vnfds
:
479 for mon_param
in vnfd_obj
.vnfd
.monitoring_param
:
480 nsd_monp
= NsdMonParam
.from_dict({
482 'name': mon_param
.name
,
483 'aggregation_type': "AVERAGE",
484 'value_type': mon_param
.value_type
,
485 'vnfd_monitoring_param': [
486 {'vnfd_id_ref': vnfd_obj
.vnfd
.id,
487 'vnfd_monitoring_param_ref': mon_param
.id}]
490 self
.nsd
.monitoring_param
.append(nsd_monp
)
496 def compose(self
, vnfd_list
, cpgroup_list
, mano_ut
,
497 use_ns_init_conf
=True,
498 use_vnf_init_conf
=True,):
501 # Disable NS initial config primitive
502 use_ns_init_conf
= False
503 use_vnf_init_conf
= False
505 self
.descriptor
= RwNsdYang
.YangData_Nsd_NsdCatalog()
506 self
.id = str(uuid
.uuid1())
507 nsd
= self
.descriptor
.nsd
.add()
511 nsd
.short_name
= self
.name
512 nsd
.vendor
= 'RIFT.io'
513 nsd
.logo
= 'rift_logo.png'
514 nsd
.description
= 'Toy NS'
516 nsd
.input_parameter_xpath
.append(
517 NsdYang
.YangData_Nsd_NsdCatalog_Nsd_InputParameterXpath(
518 xpath
="/nsd:nsd-catalog/nsd:nsd/nsd:vendor",
522 ip_profile
= nsd
.ip_profiles
.add()
523 ip_profile
.name
= "InterVNFLink"
524 ip_profile
.description
= "Inter VNF Link"
525 ip_profile
.ip_profile_params
.ip_version
= "ipv4"
526 ip_profile
.ip_profile_params
.subnet_address
= "31.31.31.0/24"
527 ip_profile
.ip_profile_params
.gateway_address
= "31.31.31.210"
530 for cpgroup
in cpgroup_list
:
532 vld
.id = 'ping_pong_vld%s' % vld_id
534 vld
.name
= 'ping_pong_vld' # hard coded
535 vld
.short_name
= vld
.name
536 vld
.vendor
= 'RIFT.io'
537 vld
.description
= 'Toy VL'
539 vld
.type_yang
= 'ELAN'
540 vld
.ip_profile_ref
= 'InterVNFLink'
542 cpref
= vld
.vnfd_connection_point_ref
.add()
543 cpref
.member_vnf_index_ref
= cp
[0]
544 cpref
.vnfd_id_ref
= cp
[1]
545 cpref
.vnfd_connection_point_ref
= cp
[2]
549 for vnfd
in vnfd_list
:
550 for i
in range(vnfd
.instance_count
):
551 constituent_vnfd
= nsd
.constituent_vnfd
.add()
552 constituent_vnfd
.member_vnf_index
= member_vnf_index
553 vnfd_index_map
[vnfd
] = member_vnf_index
555 # Set the start by default to false for ping vnfd,
556 # if scaling is enabled
557 if (len(self
._scale
_groups
) and
558 vnfd
.descriptor
.vnfd
[0].name
== 'ping_vnfd'):
559 constituent_vnfd
.start_by_default
= False
561 constituent_vnfd
.vnfd_id_ref
= vnfd
.descriptor
.vnfd
[0].id
562 self
.default_config(constituent_vnfd
, vnfd
, mano_ut
,
563 - use_ns_init_conf
, use_vnf_init_conf
)
564 member_vnf_index
+= 1
566 # Enable config primitives if either mano_ut or
567 # scale groups are enabled
568 if mano_ut
or len(self
._scale
_groups
):
569 self
.ns_config(nsd
, vnfd_list
, mano_ut
)
571 # Add NS initial config to start traffic
573 self
.ns_initial_config(nsd
)
575 for scale_group
in self
._scale
_groups
:
576 group_desc
= nsd
.scaling_group_descriptor
.add()
577 group_desc
.name
= scale_group
.name
578 group_desc
.max_instance_count
= scale_group
.max_count
579 group_desc
.min_instance_count
= scale_group
.min_count
580 for vnfd
, count
in scale_group
.vnfd_count_map
.items():
581 member
= group_desc
.vnfd_member
.add()
582 member
.member_vnf_index_ref
= vnfd_index_map
[vnfd
]
585 for trigger
in scale_group
.config_action
:
586 config_action
= group_desc
.scaling_config_action
.add()
587 config_action
.trigger
= trigger
588 config
= scale_group
.config_action
[trigger
]
589 config_action
.ns_config_primitive_name_ref
= config
['ns-config-primitive-name-ref']
591 for placement_group
in self
._placement
_groups
:
592 group
= nsd
.placement_groups
.add()
593 group
.name
= placement_group
.name
594 group
.strategy
= placement_group
.strategy
595 group
.requirement
= placement_group
.requirement
596 for member_vnfd
in placement_group
.vnfd_list
:
597 member
= group
.member_vnfd
.add()
598 member
.vnfd_id_ref
= member_vnfd
.descriptor
.vnfd
[0].id
599 member
.member_vnf_index_ref
= vnfd_index_map
[member_vnfd
]
601 # self.create_mon_params(vnfd_list)
603 def write_config(self
, outdir
, vnfds
):
605 converter
= config_data
.ConfigPrimitiveConvertor()
606 yaml_data
= converter
.extract_nsd_config(self
.nsd
)
608 ns_config_dir
= os
.path
.join(outdir
, self
.name
, "ns_config")
609 os
.makedirs(ns_config_dir
, exist_ok
=True)
610 vnf_config_dir
= os
.path
.join(outdir
, self
.name
, "vnf_config")
611 os
.makedirs(vnf_config_dir
, exist_ok
=True)
614 with
open('%s/%s.yaml' % (ns_config_dir
, self
.id), "w") as fh
:
617 for i
, vnfd
in enumerate(vnfds
, start
=1):
618 yaml_data
= converter
.extract_vnfd_config(vnfd
)
621 with
open('%s/%s__%s.yaml' % (vnf_config_dir
, vnfd
.id, i
), "w") as fh
:
624 def write_initial_config_script(self
, outdir
):
625 script_name
= 'start_traffic.py'
627 src_path
= os
.path
.dirname(os
.path
.abspath(os
.path
.realpath(__file__
)))
628 script_src
= os
.path
.join(src_path
, script_name
)
629 if not os
.path
.exists(script_src
):
630 src_path
= os
.path
.join(os
.environ
['RIFT_ROOT'],
631 'modules/core/mano/examples/ping_pong_ns/rift/mano/examples')
632 script_src
= os
.path
.join(src_path
, script_name
)
634 dest_path
= os
.path
.join(outdir
, 'scripts')
635 os
.makedirs(dest_path
, exist_ok
=True)
637 shutil
.copy2(script_src
, dest_path
)
639 def write_to_file(self
, outdir
, output_format
):
640 dirpath
= os
.path
.join(outdir
, self
.name
)
641 if not os
.path
.exists(dirpath
):
644 super(NetworkService
, self
).write_to_file(["nsd", "rw-nsd"],
648 # Write the initial config script
649 self
.write_initial_config_script(dirpath
)
652 def get_ping_mon_params(path
):
656 'name': 'ping-request-tx-count',
657 'http_endpoint_ref': path
,
658 'json_query_method': "NAMEKEY",
660 'description': 'no of ping requests',
661 'group_tag': 'Group1',
662 'widget_type': 'COUNTER',
668 'name': 'ping-response-rx-count',
669 'http_endpoint_ref': path
,
670 'json_query_method': "NAMEKEY",
672 'description': 'no of ping responses',
673 'group_tag': 'Group1',
674 'widget_type': 'COUNTER',
680 def get_pong_mon_params(path
):
684 'name': 'ping-request-rx-count',
685 'http_endpoint_ref': path
,
686 'json_query_method': "NAMEKEY",
688 'description': 'no of ping requests',
689 'group_tag': 'Group1',
690 'widget_type': 'COUNTER',
696 'name': 'ping-response-tx-count',
697 'http_endpoint_ref': path
,
698 'json_query_method': "NAMEKEY",
700 'description': 'no of ping responses',
701 'group_tag': 'Group1',
702 'widget_type': 'COUNTER',
708 class ScaleGroup(object):
709 def __init__(self
, name
, min_count
=1, max_count
=1):
711 self
.min_count
= min_count
712 self
.max_count
= max_count
713 self
.vnfd_count_map
= {}
714 self
.config_action
= {}
716 def add_vnfd(self
, vnfd
, vnfd_count
):
717 self
.vnfd_count_map
[vnfd
] = vnfd_count
719 def add_config(self
):
720 self
.config_action
['post_scale_out']= {'ns-config-primitive-name-ref':
723 class PlacementGroup(object):
724 def __init__(self
, name
):
727 self
.requirement
= ''
729 def add_strategy(self
, strategy
):
730 self
.strategy
= strategy
732 def add_requirement(self
, requirement
):
733 self
.requirement
= requirement
735 class NsdPlacementGroup(PlacementGroup
):
736 def __init__(self
, name
):
738 super(NsdPlacementGroup
, self
).__init
__(name
)
740 def add_member(self
, vnfd
):
741 self
.vnfd_list
.append(vnfd
)
744 class VnfdPlacementGroup(PlacementGroup
):
745 def __init__(self
, name
):
747 super(VnfdPlacementGroup
, self
).__init
__(name
)
749 def add_member(self
, vdu
):
750 self
.vdu_list
.append(vdu
)
755 def generate_ping_pong_descriptors(fmt
="json",
758 pingcount
=NUM_PING_INSTANCES
,
759 external_vlr_count
=1,
760 internal_vlr_count
=1,
765 use_scale_group
=False,
772 ex_ping_userdata
=None,
773 ex_pong_userdata
=None,
774 use_placement_group
=True,
775 use_ns_init_conf
=True,
776 use_vnf_init_conf
=True,
778 # List of connection point groups
779 # Each connection point group refers to a virtual link
780 # the CP group consists of tuples of connection points
782 for i
in range(external_vlr_count
):
783 cpgroup_list
.append([])
786 ping
= VirtualNetworkFunction("ping_vnfd%s" % (suffix
), pingcount
)
787 ping
.use_vnf_init_conf
= use_vnf_init_conf
789 if use_placement_group
:
790 ### Add group name Eris
791 group
= VnfdPlacementGroup('Eris')
792 group
.add_strategy('COLOCATION')
793 group
.add_requirement('''Place this VM on the Kuiper belt object Eris''')
794 ping
.add_placement_group(group
)
796 # ping = VirtualNetworkFunction("ping_vnfd", pingcount)
797 if not ping_userdata
:
798 ping_userdata
= PING_USERDATA_FILE
805 ping_userdata
=ping_userdata
,
806 ex_ping_userdata
=ex_ping_userdata
810 "Fedora-x86_64-20-20131211.1-sda-ping.qcow2",
812 use_ping_cloud_init_file
,
814 get_ping_mon_params("api/v1/ping/stats") if use_mon_params
else [],
817 num_vlr_count
=external_vlr_count
,
818 num_ivlr_count
=internal_vlr_count
,
820 image_md5sum
=ping_md5sum
,
824 pong
= VirtualNetworkFunction("pong_vnfd%s" % (suffix
))
826 if use_placement_group
:
827 ### Add group name Weywot
828 group
= VnfdPlacementGroup('Weywot')
829 group
.add_strategy('COLOCATION')
830 group
.add_requirement('''Place this VM on the Kuiper belt object Weywot''')
831 pong
.add_placement_group(group
)
834 # pong = VirtualNetworkFunction("pong_vnfd")
836 if not pong_userdata
:
837 pong_userdata
= PONG_USERDATA_FILE
844 pong_userdata
=pong_userdata
,
845 ex_pong_userdata
=ex_pong_userdata
850 "Fedora-x86_64-20-20131211.1-sda-pong.qcow2",
852 use_pong_cloud_init_file
,
854 get_pong_mon_params("api/v1/pong/stats") if use_mon_params
else [],
857 num_vlr_count
=external_vlr_count
,
858 num_ivlr_count
=internal_vlr_count
,
860 image_md5sum
=pong_md5sum
,
864 # Initialize the member VNF index
867 # define the connection point groups
868 for index
, cp_group
in enumerate(cpgroup_list
):
869 desc_id
= ping
.descriptor
.vnfd
[0].id
870 filename
= 'ping_vnfd{}/cp{}'.format(suffix
, index
)
872 for idx
in range(pingcount
):
879 member_vnf_index
+= 1
881 desc_id
= pong
.descriptor
.vnfd
[0].id
882 filename
= 'pong_vnfd{}/cp{}'.format(suffix
, index
)
890 member_vnf_index
+= 1
892 vnfd_list
= [ping
, pong
]
894 nsd_catalog
= NetworkService("ping_pong_nsd%s" % (suffix
))
897 group
= ScaleGroup("ping_group", max_count
=10)
898 group
.add_vnfd(ping
, 1)
900 nsd_catalog
.add_scale_group(group
)
902 if use_placement_group
:
903 ### Add group name Orcus
904 group
= NsdPlacementGroup('Orcus')
905 group
.add_strategy('COLOCATION')
906 group
.add_requirement('''Place this VM on the Kuiper belt object Orcus''')
908 for member_vnfd
in vnfd_list
:
909 group
.add_member(member_vnfd
)
911 nsd_catalog
.add_placement_group(group
)
913 ### Add group name Quaoar
914 group
= NsdPlacementGroup('Quaoar')
915 group
.add_strategy('COLOCATION')
916 group
.add_requirement('''Place this VM on the Kuiper belt object Quaoar''')
918 for member_vnfd
in vnfd_list
:
919 group
.add_member(member_vnfd
)
921 nsd_catalog
.add_placement_group(group
)
924 nsd_catalog
.compose(vnfd_list
,
927 use_ns_init_conf
=use_ns_init_conf
,
928 use_vnf_init_conf
=use_vnf_init_conf
,)
931 ping
.write_to_file(out_dir
, ping_fmt
if ping_fmt
is not None else fmt
)
932 pong
.write_to_file(out_dir
, pong_fmt
if ping_fmt
is not None else fmt
)
933 nsd_catalog
.write_config(out_dir
, vnfd_list
)
934 nsd_catalog
.write_to_file(out_dir
, ping_fmt
if nsd_fmt
is not None else fmt
)
936 return (ping
, pong
, nsd_catalog
)
939 def main(argv
=sys
.argv
[1:]):
940 global outdir
, output_format
, use_epa
, aws
, use_ping_cloud_init_file
, use_pong_cloud_init_file
941 parser
= argparse
.ArgumentParser()
942 parser
.add_argument('-o', '--outdir', default
='.')
943 parser
.add_argument('-f', '--format', default
='json')
944 parser
.add_argument('-e', '--epa', action
="store_true", default
=False)
945 parser
.add_argument('-a', '--aws', action
="store_true", default
=False)
946 parser
.add_argument('-n', '--pingcount', default
=NUM_PING_INSTANCES
)
947 parser
.add_argument('--ping-image-md5')
948 parser
.add_argument('--pong-image-md5')
949 parser
.add_argument('--ping-cloud-init', default
=None)
950 parser
.add_argument('--pong-cloud-init', default
=None)
951 args
= parser
.parse_args()
953 output_format
= args
.format
956 pingcount
= args
.pingcount
957 use_ping_cloud_init_file
= args
.ping_cloud_init
958 use_pong_cloud_init_file
= args
.pong_cloud_init
960 generate_ping_pong_descriptors(args
.format
, True, args
.outdir
, pingcount
,
961 ping_md5sum
=args
.ping_image_md5
, pong_md5sum
=args
.pong_image_md5
,
963 use_scale_group
=False,)
965 if __name__
== "__main__":