4 # Copyright 2016-2017 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.
29 from xml
.dom
.minidom
import parseString
32 gi
.require_version('RwYang', '1.0')
33 gi
.require_version('RwVnfdYang', '1.0')
34 gi
.require_version('VnfdYang', '1.0')
35 gi
.require_version('RwNsdYang', '1.0')
37 from gi
.repository
import (
38 RwNsdYang
as RwNsdYang
,
40 RwVnfdYang
as RwVnfdYang
,
47 import rift
.mano
.config_data
.config
as config_data
49 # Load modules from common which are not yet installed
50 path
= os
.path
.abspath(os
.path
.dirname(os
.path
.abspath(__file__
)) + "../../../common/python/rift/mano")
53 import config_data
.config
as config_data
56 NUM_PING_INSTANCES
= 1
57 MAX_VNF_INSTANCES_PER_NS
= 10
60 pingcount
= NUM_PING_INSTANCES
61 use_ping_cloud_init_file
= ""
62 use_pong_cloud_init_file
= ""
64 PING_USERDATA_FILE
= '''#cloud-config
66 chpasswd: { expire: False }
69 - [ systemctl, daemon-reload ]
70 - [ systemctl, enable, ping.service ]
71 - [ systemctl, start, --no-block, ping.service ]
75 PONG_USERDATA_FILE
= '''#cloud-config
77 chpasswd: { expire: False }
80 - [ systemctl, daemon-reload ]
81 - [ systemctl, enable, pong.service ]
82 - [ systemctl, start, --no-block, pong.service ]
87 class UnknownVNFError(Exception):
91 class ManoDescriptor(object):
92 def __init__(self
, name
):
94 self
.descriptor
= None
96 def write_to_file(self
, module_list
, outdir
, output_format
):
97 model
= RwYang
.Model
.create_libyang()
98 for module
in module_list
:
99 model
.load_module(module
)
101 if output_format
== 'json':
102 with
open('%s/%s.json' % (outdir
, self
.name
), "w") as fh
:
103 fh
.write(self
.descriptor
.to_json(model
))
104 elif output_format
.strip() == 'xml':
105 with
open('%s/%s.xml' % (outdir
, self
.name
), "w") as fh
:
106 fh
.write(self
.descriptor
.to_xml_v2(model
))
107 elif output_format
.strip() == 'yaml':
108 with
open('%s/%s.yaml' % (outdir
, self
.name
), "w") as fh
:
109 fh
.write(self
.descriptor
.to_yaml(model
))
111 raise Exception("Invalid output format for the descriptor")
114 class VirtualNetworkFunction(ManoDescriptor
):
115 def __init__(self
, name
, instance_count
=1):
116 self
.vnfd_catalog
= None
119 self
.use_ns_init_conf
= False
120 self
.use_vca_conf
= False
121 self
.use_charm
= False
122 self
.instance_count
= instance_count
123 self
._placement
_groups
= []
124 self
.config_files
= []
125 self
.use_vnf_init_conf
= False
126 super(VirtualNetworkFunction
, self
).__init
__(name
)
128 def add_placement_group(self
, group
):
129 self
._placement
_groups
.append(group
)
131 def add_vnf_conf_param_charm(self
):
132 vnfd
= self
.descriptor
.vnfd
[0]
133 confparam
= vnfd
.config_parameter
135 src
= confparam
.create_config_parameter_source()
138 "description": "Management IP address",
139 "attribute": "../../../mgmt-interface, ip-address",
141 "config_primitive_name_ref": "config",
142 "config_primitive_parameter_ref": "ssh-hostname"
145 confparam
.config_parameter_source
.append(src
)
147 src
= confparam
.create_config_parameter_source()
150 "description": "SSH username",
153 "config_primitive_name_ref": "config",
154 "config_primitive_parameter_ref": "ssh-username"
157 confparam
.config_parameter_source
.append(src
)
159 src
= confparam
.create_config_parameter_source()
162 "description": "SSH private key file",
163 "attribute": "../../../mgmt-interface/ssh-key, private-key-file",
165 "config_primitive_name_ref": "config",
166 "config_primitive_parameter_ref": "ssh-private-key"
169 confparam
.config_parameter_source
.append(src
)
172 if 'pong_' in self
.name
:
173 src
= confparam
.create_config_parameter_source()
175 "name": "service_ip",
176 "description": "IP on which Pong service is listening",
177 "attribute": "../../../connection-point[name='pong_vnfd/cp0'], ip-address",
180 "config_primitive_name_ref": "set-server",
181 "config_primitive_parameter_ref": "server-ip"
185 confparam
.config_parameter_source
.append(src
)
186 src
= confparam
.create_config_parameter_source()
188 "name": "service_port",
189 "description": "Port on which server listens for incoming data packets",
193 "config_primitive_name_ref": "set-server",
194 "config_primitive_parameter_ref": "server-port"
198 confparam
.config_parameter_source
.append(src
)
201 src
= confparam
.create_config_parameter_source()
204 "description": "Rate of packet generation",
208 "config_primitive_name_ref": "set-rate",
209 "config_primitive_parameter_ref": "rate"
213 confparam
.config_parameter_source
.append(src
)
215 req
= confparam
.create_config_parameter_request()
218 "description": "IP on which Pong service is listening",
221 "config_primitive_name_ref": "set-server",
222 "config_primitive_parameter_ref": "server-ip"
226 confparam
.config_parameter_request
.append(req
)
227 req
= confparam
.create_config_parameter_request()
230 "description": "Port on which Pong service is listening",
233 "config_primitive_name_ref": "set-server",
234 "config_primitive_parameter_ref": "server-port"
238 confparam
.config_parameter_request
.append(req
)
240 def add_vnf_conf_param(self
):
241 vnfd
= self
.descriptor
.vnfd
[0]
242 confparam
= vnfd
.config_parameter
244 def get_params(param
):
246 if 'pong_' in self
.name
:
249 "config_primitive_name_ref": "config",
250 "config_primitive_parameter_ref": param
253 "config_primitive_name_ref": "start-stop",
254 "config_primitive_parameter_ref": param
260 "config_primitive_name_ref": "config",
261 "config_primitive_parameter_ref": param
264 "config_primitive_name_ref": "set-rate",
265 "config_primitive_parameter_ref": param
268 "config_primitive_name_ref": "start-stop",
269 "config_primitive_parameter_ref": param
274 src
= confparam
.create_config_parameter_source()
277 "description": "Management address",
278 "attribute": "../../../mgmt-interface, ip-address",
279 "parameter" : get_params("mgmt_ip")
281 confparam
.config_parameter_source
.append(src
)
282 src
= confparam
.create_config_parameter_source()
285 "description": "Management port",
286 "descriptor": "../../../mgmt-interface/port",
287 "parameter" : get_params("mgmt_port")
289 confparam
.config_parameter_source
.append(src
)
290 src
= confparam
.create_config_parameter_source()
293 "description": "Management username",
295 "parameter" : get_params("username")
297 confparam
.config_parameter_source
.append(src
)
298 src
= confparam
.create_config_parameter_source()
301 "description": "Management password",
303 "parameter" : get_params("password")
305 confparam
.config_parameter_source
.append(src
)
308 if 'pong_' in self
.name
:
309 src
= confparam
.create_config_parameter_source()
311 "name": "service_ip",
312 "description": "IP on which Pong service is listening",
313 "attribute": "../../../connection-point[name='pong_vnfd/cp0'], ip-address",
316 "config_primitive_name_ref": "config",
317 "config_primitive_parameter_ref": "service_ip"
321 confparam
.config_parameter_source
.append(src
)
322 src
= confparam
.create_config_parameter_source()
324 "name": "service_port",
325 "description": "Port on which server listens for incoming data packets",
329 "config_primitive_name_ref": "config",
330 "config_primitive_parameter_ref": "service_port"
334 confparam
.config_parameter_source
.append(src
)
337 src
= confparam
.create_config_parameter_source()
340 "description": "Rate of packet generation",
344 "config_primitive_name_ref": "set-rate",
345 "config_primitive_parameter_ref": "rate"
349 confparam
.config_parameter_source
.append(src
)
351 req
= confparam
.create_config_parameter_request()
354 "description": "IP on which Pong service is listening",
357 "config_primitive_name_ref": "config",
358 "config_primitive_parameter_ref": "pong_ip"
362 confparam
.config_parameter_request
.append(req
)
363 req
= confparam
.create_config_parameter_request()
366 "description": "Port on which Pong service is listening",
369 "config_primitive_name_ref": "config",
370 "config_primitive_parameter_ref": "pong_port"
374 confparam
.config_parameter_request
.append(req
)
376 def add_ping_vca_config(self
):
377 vnfd
= self
.descriptor
.vnfd
[0]
378 # Add vnf configuration
379 vnf_config
= vnfd
.vnf_configuration
381 # vnf_config.config_attributes.config_delay = 10
383 # Select "script" configuration
384 vnf_config
.script
.script_type
= 'rift'
386 # Add config primitive
387 prim
= RwVnfdYang
.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_ConfigPrimitive
.from_dict({
390 {"name": "mgmt_ip", "data_type": "STRING", "read_only": "true"},
391 {"name": "mgmt_port", "data_type": "INTEGER", "read_only": "true"},
392 {"name": "username", "data_type": "STRING", "read_only": "true"},
393 {"name": "password", "data_type": "STRING", "read_only": "true"},
394 {"name": "pong_ip", "data_type": "STRING", "read_only": "true"},
395 {"name": "pong_port", "data_type": "INTEGER","read_only": "true",
396 "default_value": "5555"},
398 "user_defined_script": "ping_setup.py",
400 vnf_config
.config_primitive
.append(prim
)
402 prim
= RwVnfdYang
.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_ConfigPrimitive
.from_dict({
405 {"name": "mgmt_ip", "data_type": "STRING", "read_only": "true"},
406 {"name": "mgmt_port", "data_type": "INTEGER", "read_only": "true"},
407 {"name": "username", "data_type": "STRING", "read_only": "true"},
408 {"name": "password", "data_type": "STRING", "read_only": "true"},
409 {"name": "rate", "data_type": "INTEGER",
410 "default_value": "5"},
412 "user_defined_script": "ping_rate.py",
414 vnf_config
.config_primitive
.append(prim
)
416 prim
= RwVnfdYang
.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_ConfigPrimitive
.from_dict({
417 "name": "start-stop",
419 {"name": "mgmt_ip", "data_type": "STRING", "read_only": "true"},
420 {"name": "mgmt_port", "data_type": "INTEGER", "read_only": "true"},
421 {"name": "username", "data_type": "STRING", "read_only": "true"},
422 {"name": "password", "data_type": "STRING", "read_only": "true"},
423 {"name": "start", "data_type": "BOOLEAN",
424 "default_value": "true"}
426 "user_defined_script": "ping_start_stop.py",
428 vnf_config
.config_primitive
.append(prim
)
430 # Add initial config primitive
431 init_config
= RwVnfdYang
.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_InitialConfigPrimitive
.from_dict(
434 "config_primitive_ref": "config",
437 vnf_config
.initial_config_primitive
.append(init_config
)
439 init_config
= RwVnfdYang
.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_InitialConfigPrimitive
.from_dict(
442 "config_primitive_ref": "set-rate",
445 vnf_config
.initial_config_primitive
.append(init_config
)
447 if self
.use_ns_init_conf
is False:
448 init_config
= RwVnfdYang
.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_InitialConfigPrimitive
.from_dict(
451 "config_primitive_ref": "start-stop",
454 vnf_config
.initial_config_primitive
.append(init_config
)
456 def add_pong_vca_config(self
):
457 vnfd
= self
.descriptor
.vnfd
[0]
458 # Add vnf configuration
459 vnf_config
= vnfd
.vnf_configuration
461 # Select "script" configuration
462 vnf_config
.script
.script_type
= 'rift'
464 # Add config primitive
465 prim
= RwVnfdYang
.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_ConfigPrimitive
.from_dict({
468 {"name": "mgmt_ip", "data_type": "STRING", "read_only": "true"},
469 {"name": "mgmt_port", "data_type": "INTEGER", "read_only": "true"},
470 {"name": "username", "data_type": "STRING", "read_only": "true"},
471 {"name": "password", "data_type": "STRING", "read_only": "true"},
472 {"name": "service_ip", "data_type": "STRING", "read_only": "true"},
473 {"name": "service_port", "data_type": "INTEGER", "read_only": "true"},
475 "user_defined_script": "pong_setup.py",
477 vnf_config
.config_primitive
.append(prim
)
479 prim
= RwVnfdYang
.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_ConfigPrimitive
.from_dict({
480 "name": "start-stop",
482 {"name": "mgmt_ip", "data_type": "STRING", "read_only": "true"},
483 {"name": "mgmt_port", "data_type": "INTEGER", "read_only": "true"},
484 {"name": "username", "data_type": "STRING", "read_only": "true"},
485 {"name": "password", "data_type": "STRING", "read_only": "true"},
486 {"name": "start", "data_type": "BOOLEAN",
487 "default_value": "true"}
489 "user_defined_script": "pong_start_stop.py",
491 vnf_config
.config_primitive
.append(prim
)
493 # Add initial config primitive
494 init_config
= RwVnfdYang
.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_InitialConfigPrimitive
.from_dict(
497 "config_primitive_ref": "config",
500 vnf_config
.initial_config_primitive
.append(init_config
)
502 if self
.use_ns_init_conf
is False:
503 init_config
= RwVnfdYang
.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_InitialConfigPrimitive
.from_dict(
506 "config_primitive_ref": "start-stop",
509 vnf_config
.initial_config_primitive
.append(init_config
)
511 def add_charm_config(self
):
512 vnfd
= self
.descriptor
.vnfd
[0]
513 # Add vnf configuration
514 vnf_config
= vnfd
.vnf_configuration
516 if 'pong_' in self
.name
:
521 # Select "script" configuration
522 vnf_config
.juju
.charm
= 'pingpong'
524 # Add config primitive
525 vnf_config
.create_config_primitive()
526 prim
= VnfdYang
.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_ConfigPrimitive
.from_dict({
529 vnf_config
.config_primitive
.append(prim
)
531 prim
= VnfdYang
.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_ConfigPrimitive
.from_dict({
534 vnf_config
.config_primitive
.append(prim
)
536 prim
= VnfdYang
.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_ConfigPrimitive
.from_dict({
539 vnf_config
.config_primitive
.append(prim
)
541 prim
= VnfdYang
.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_ConfigPrimitive
.from_dict({
544 {"name": "ssh-hostname", "data_type": "STRING"},
545 {"name": "ssh-username", "data_type": "STRING"},
546 {"name": "ssh-private-key", "data_type": "STRING"},
547 {"name": "mode", "data_type": "STRING",
548 "default_value": "{}".format(mode
),
549 "read_only": "true"},
552 vnf_config
.config_primitive
.append(prim
)
554 prim
= VnfdYang
.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_ConfigPrimitive
.from_dict({
555 "name": "set-server",
557 {"name": "server-ip", "data_type": "STRING"},
558 {"name": "server-port", "data_type": "INTEGER"},
561 vnf_config
.config_primitive
.append(prim
)
564 prim
= VnfdYang
.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_ConfigPrimitive
.from_dict({
567 {"name": "rate", "data_type": "INTEGER",
568 "default_value": "5"},
571 vnf_config
.config_primitive
.append(prim
)
573 prim
= VnfdYang
.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_ConfigPrimitive
.from_dict({
574 "name": "start-traffic",
576 vnf_config
.config_primitive
.append(prim
)
578 prim
= VnfdYang
.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_ConfigPrimitive
.from_dict({
579 "name": "stop-traffic",
581 vnf_config
.config_primitive
.append(prim
)
583 # Add initial config primitive
584 vnf_config
.create_initial_config_primitive()
585 init_config
= RwVnfdYang
.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_InitialConfigPrimitive
.from_dict(
588 "config_primitive_ref": "config",
591 vnf_config
.initial_config_primitive
.append(init_config
)
593 init_config
= RwVnfdYang
.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_InitialConfigPrimitive
.from_dict(
596 "config_primitive_ref": "start",
599 vnf_config
.initial_config_primitive
.append(init_config
)
601 init_config
= RwVnfdYang
.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_InitialConfigPrimitive
.from_dict(
604 "config_primitive_ref": "set-server",
607 vnf_config
.initial_config_primitive
.append(init_config
)
610 init_config
= RwVnfdYang
.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_InitialConfigPrimitive
.from_dict(
613 "config_primitive_ref": "set-rate",
616 vnf_config
.initial_config_primitive
.append(init_config
)
618 if self
.use_ns_init_conf
is False:
619 init_config
= RwVnfdYang
.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_InitialConfigPrimitive
.from_dict(
622 "config_primitive_ref": "start-traffic",
625 vnf_config
.initial_config_primitive
.append(init_config
)
627 def compose(self
, image_name
, vnf_descriptor_message
, cloud_init
="", cloud_init_file
="",
628 endpoint
=None, mon_params
=[], mon_port
=8888, mgmt_port
=8888, num_vlr_count
=1,
629 num_ivlr_count
=1, num_vms
=1, image_md5sum
=None, mano_ut
=False,
630 use_ns_init_conf
=False, use_vca_conf
=False, use_charm
=False, use_static_ip
=False,
631 multidisk
=None, port_security
=None, metadata_vdud
=None, use_ipv6
=False,
632 use_virtual_ip
=False, vnfd_input_params
=None, script_input_params
=None, explicit_port_seq
=False, mgmt_net
=True):
634 self
.mano_ut
= mano_ut
635 self
.use_ns_init_conf
= use_ns_init_conf
636 self
.use_vca_conf
= use_vca_conf
637 self
.use_charm
= use_charm
639 self
.descriptor
= RwVnfdYang
.YangData_Vnfd_VnfdCatalog()
640 self
.id = str(uuid
.uuid1())
641 vnfd
= self
.descriptor
.vnfd
.add()
643 vnfd
.name
= self
.name
644 vnfd
.short_name
= self
.name
645 vnfd
.vendor
= 'RIFT.io'
646 vnfd
.logo
= 'rift_logo.png'
647 vnfd
.description
= vnf_descriptor_message
652 if explicit_port_seq
:
653 # ping and pong vnfds will have 2 and 5 internal interfaces respectively
655 if 'pong' in vnfd
.name
:
658 if mano_ut
or use_virtual_ip
or explicit_port_seq
:
660 for i
in range(num_ivlr_count
):
661 internal_vld
= vnfd
.internal_vld
.add()
662 internal_vld
.id = 'ivld%s' % i
663 internal_vld
.name
= 'fabric%s' % i
664 internal_vld
.short_name
= 'fabric%s' % i
665 internal_vld
.description
= 'Virtual link for internal fabric%s' % i
666 internal_vld
.type_yang
= 'ELAN'
667 internal_vlds
.append(internal_vld
)
669 for i
in range(num_vlr_count
):
670 index
= i
+1 if mgmt_net
else i
671 cp
= vnfd
.connection_point
.add()
672 cp
.type_yang
= 'VPORT'
673 cp
.name
= '%s/cp%d' % (self
.name
, index
)
674 if port_security
is not None:
675 cp
.port_security_enabled
= port_security
678 cp
= vnfd
.connection_point
.add()
679 cp
.type_yang
= 'VPORT'
680 cp
.name
= '%s/cp0' % (self
.name
)
682 if endpoint
is not None:
683 endp
= RwVnfdYang
.YangData_Vnfd_VnfdCatalog_Vnfd_HttpEndpoint(
684 path
=endpoint
, port
=mon_port
, polling_interval_secs
=2
686 vnfd
.http_endpoint
.append(endp
)
689 for monp_dict
in mon_params
:
690 monp
= VnfdYang
.YangData_Vnfd_VnfdCatalog_Vnfd_MonitoringParam
.from_dict(monp_dict
)
691 monp
.http_endpoint_ref
= endpoint
692 vnfd
.monitoring_param
.append(monp
)
694 for i
in range(num_vms
):
697 vdu
.id = 'iovdu_%s' % i
698 vdu
.name
= 'iovdu_%s' % i
700 # vdu.mgmt_vpci = '0000:00:20.0'
702 # specify the VM flavor
704 vdu
.vm_flavor
.vcpu_count
= 4
705 vdu
.vm_flavor
.memory_mb
= 1024
706 vdu
.vm_flavor
.storage_gb
= 4
708 vdu
.vm_flavor
.vcpu_count
= 1
709 vdu
.vm_flavor
.memory_mb
= 512
710 vdu
.vm_flavor
.storage_gb
= 4
712 # Management interface
713 mgmt_intf
= vnfd
.mgmt_interface
714 mgmt_intf
.vdu_id
= vdu
.id
715 mgmt_intf
.port
= mgmt_port
716 mgmt_intf
.dashboard_params
.path
= endpoint
717 mgmt_intf
.dashboard_params
.port
= mgmt_port
720 mgmt_intf
.ssh_key
= True
722 if not self
.use_charm
:
723 if cloud_init_file
and len(cloud_init_file
):
724 vdu
.cloud_init_file
= cloud_init_file
726 vdu
.cloud_init
= cloud_init
728 vdu
.cloud_init
+= " - [ systemctl, restart, --no-block, elastic-network-interfaces.service ]\n"
730 # sepcify the guest EPA
732 vdu
.guest_epa
.trusted_execution
= False
733 vdu
.guest_epa
.mempage_size
= 'LARGE'
734 vdu
.guest_epa
.cpu_pinning_policy
= 'DEDICATED'
735 vdu
.guest_epa
.cpu_thread_pinning_policy
= 'PREFER'
736 vdu
.guest_epa
.numa_node_policy
.node_cnt
= 2
737 vdu
.guest_epa
.numa_node_policy
.mem_policy
= 'STRICT'
739 node
= vdu
.guest_epa
.numa_node_policy
.node
.add()
742 vcpu
= node
.vcpu
.add()
744 vcpu
= node
.vcpu
.add()
747 node
= vdu
.guest_epa
.numa_node_policy
.node
.add()
750 vcpu
= node
.vcpu
.add()
752 vcpu
= node
.vcpu
.add()
755 # specify the vswitch EPA
756 vdu
.vswitch_epa
.ovs_acceleration
= 'DISABLED'
757 vdu
.vswitch_epa
.ovs_offload
= 'DISABLED'
759 # Specify the hypervisor EPA
760 vdu
.hypervisor_epa
.type_yang
= 'PREFER_KVM'
762 # Specify the host EPA
763 # vdu.host_epa.cpu_model = 'PREFER_SANDYBRIDGE'
764 # vdu.host_epa.cpu_arch = 'PREFER_X86_64'
765 # vdu.host_epa.cpu_vendor = 'PREFER_INTEL'
766 # vdu.host_epa.cpu_socket_count = 2
767 # vdu.host_epa.cpu_core_count = 8
768 # vdu.host_epa.cpu_core_thread_count = 2
769 # vdu.host_epa.cpu_feature = ['PREFER_AES', 'REQUIRE_VME', 'PREFER_MMX','REQUIRE_SSE2']
772 vdu
.image
= 'rift-ping-pong'
774 ping_test_data
, pong_test_data
= multidisk
775 test_data
= ping_test_data
776 if 'pong' in vnfd
.name
:
777 test_data
= pong_test_data
778 for vol_name
, vol_attrs
in test_data
.items():
779 vol
= vdu
.volumes
.add()
781 vol
.device_type
= vol_attrs
[0]
782 vol
.device_bus
= vol_attrs
[1]
783 vol
.size
= vol_attrs
[2]
785 vol
.image
= vol_attrs
[3]
786 # Bug RIFT-15165. Will comment out later once the bug is fixed
788 # vol.ephemeral = True
790 if vol_attrs
[4] is not None:
791 vol
.boot_priority
= vol_attrs
[4]
793 vdu
.image
= image_name
794 if image_md5sum
is not None:
795 vdu
.image_checksum
= image_md5sum
797 if explicit_port_seq
:
798 # pong vnfd will have 3 ordered interfaces out of 7 and all interfaces of ping vnfd are ordered
799 ordered_interfaces_count
= num_vlr_count
+ num_ivlr_count
800 if 'pong' in vnfd
.name
:
801 ordered_interfaces_count
= 3
802 interface_positions_list
= random
.sample(range(1, 2**32-1), ordered_interfaces_count
-1)
803 random
.shuffle(interface_positions_list
)
805 if mano_ut
or use_virtual_ip
or explicit_port_seq
:
806 vip_internal_intf_pool_start
= 51
807 for i
in range(num_ivlr_count
):
808 internal_cp
= vdu
.internal_connection_point
.add()
809 if vnfd
.name
.find("ping") >= 0:
810 cp_name
= "ping_vnfd"
812 cp_name
= "pong_vnfd"
813 internal_cp
.name
= cp_name
+ "/icp{}".format(i
)
814 internal_cp
.id = cp_name
+ "/icp{}".format(i
)
815 internal_cp
.type_yang
= 'VPORT'
816 ivld_cp
= internal_vlds
[i
].internal_connection_point
.add()
817 ivld_cp
.id_ref
= internal_cp
.id
819 vcp
= internal_vlds
[i
].virtual_connection_points
.add()
820 if 'ping' in vnfd
.name
:
824 vcp
.type_yang
= 'VPORT'
825 vcp
.associated_cps
.append(internal_cp
.id)
826 int_interface_positon_set
= False
827 internal_interface
= vdu
.interface
.add()
828 internal_interface
.name
= 'fab%d' % i
829 internal_interface
.type_yang
= 'INTERNAL'
830 internal_interface
.internal_connection_point_ref
= internal_cp
.id
831 internal_interface
.virtual_interface
.type_yang
= 'VIRTIO'
832 if explicit_port_seq
and interface_positions_list
:
833 internal_interface
.position
= interface_positions_list
.pop()
834 int_interface_positon_set
= True
835 # internal_interface.virtual_interface.vpci = '0000:00:1%d.0'%i
836 if use_virtual_ip
and int_interface_positon_set
is False:
837 internal_interface
.position
= vip_internal_intf_pool_start
838 vip_internal_intf_pool_start
+= 1
841 #adding a vlr for management network
842 num_vlr_count
= num_vlr_count
+ 1
844 vip_external_intf_pool_start
= 1
845 for i
in range(num_vlr_count
):
846 ext_interface_positon_set
= False
847 external_interface
= vdu
.interface
.add()
848 external_interface
.name
= 'eth%d' % (i
)
849 external_interface
.type_yang
= 'EXTERNAL'
850 external_interface
.external_connection_point_ref
= '%s/cp%d' % (self
.name
, i
)
851 # The first external interface need to be set as the packets use this
852 # and we bring up only the eth0 (mgmt interface) and eth1 in the ping and
854 if explicit_port_seq
and (i
== 0):
855 external_interface
.position
= 1
856 elif explicit_port_seq
and interface_positions_list
:
857 external_interface
.position
= interface_positions_list
.pop()
858 ext_interface_positon_set
= True
860 external_interface
.virtual_interface
.type_yang
= 'VIRTIO'
861 # external_interface.virtual_interface.vpci = '0000:00:2%d.0'%i
862 if use_virtual_ip
and ext_interface_positon_set
is False:
863 external_interface
.position
= vip_external_intf_pool_start
864 vip_external_intf_pool_start
+= 1
866 if use_static_ip
and not(mgmt_net
and i
== 0):
867 if 'pong_' in self
.name
:
868 external_interface
.static_ip_address
= '31.31.31.31'
870 external_interface
.static_ip_address
= '3fee:1111:1111::1234'
872 external_interface
.static_ip_address
= '31.31.31.32'
874 external_interface
.static_ip_address
= '3fee:1111:1111::1235'
879 # Add config files, custom-meta-data for both ping, pong VNFs. Enable 'boot data drive' only for ping VNF
880 meta_data
= {'EMS_IP':'10.1.2.3', 'Licenseserver_IP':'192.168.1.1'}
882 self
.config_files
.append('test_cfg_file_{}.txt'.format(random
.randint(1,1000)))
884 supplemental_boot_data
= RwVnfdYang
.YangData_Vnfd_VnfdCatalog_Vnfd_Vdu_SupplementalBootData()
887 for cfg_file
in self
.config_files
:
888 config_file
= supplemental_boot_data
.config_file
.add()
889 config_file
.source
= cfg_file
890 config_file
.dest
= os
.path
.join('/tmp',cfg_file
)
892 # enable 'boot data drive' only for ping VNF
893 if 'ping_' in vnfd
.name
:
894 supplemental_boot_data
.boot_data_drive
= True
895 # Add custom metadata
896 for name
, value
in meta_data
.items():
897 custom_meta_data
= supplemental_boot_data
.custom_meta_data
.add()
898 custom_meta_data
.name
= name
899 custom_meta_data
.value
= value
901 vdu
.supplemental_boot_data
= supplemental_boot_data
903 if vnfd_input_params
:
904 # Input parameters for vnfd
905 supplemental_boot_data
= RwVnfdYang
.YangData_Vnfd_VnfdCatalog_Vnfd_Vdu_SupplementalBootData()
907 if 'ping_' in vnfd
.name
or 'pong_' in vnfd
.name
:
908 cloud_init_data
= supplemental_boot_data
.custom_meta_data
.add()
909 cloud_init_data
.destination
= 'CLOUD_INIT'
910 cloud_init_data
.name
= 'custom_cloud_init_data'
911 cloud_init_data
.value
= 'cc_init_data'
912 cloud_init_data
.data_type
= 'STRING'
914 cloud_meta_data
= supplemental_boot_data
.custom_meta_data
.add()
915 cloud_meta_data
.destination
= 'CLOUD_METADATA'
916 cloud_meta_data
.name
= 'custom_cloud_meta_data'
917 cloud_meta_data
.value
= 'cc_meta_data'
918 cloud_meta_data
.data_type
= 'STRING'
920 vdu
.supplemental_boot_data
= supplemental_boot_data
922 if script_input_params
:
923 # Input parameters for vnfd
924 supplemental_boot_data
= RwVnfdYang
.YangData_Vnfd_VnfdCatalog_Vnfd_Vdu_SupplementalBootData()
926 if 'ping_' in vnfd
.name
or 'pong_' in vnfd
.name
:
927 cloud_init_data
= supplemental_boot_data
.custom_meta_data
.add()
928 cloud_init_data
.destination
= 'CLOUD_METADATA'
929 cloud_init_data
.name
= 'CI-script-init-data'
930 cloud_init_data
.value
= 'default_script_init_data'
931 cloud_init_data
.data_type
= 'STRING'
933 vdu
.supplemental_boot_data
= supplemental_boot_data
935 for group
in self
._placement
_groups
:
936 placement_group
= vnfd
.placement_groups
.add()
937 placement_group
.name
= group
.name
938 placement_group
.requirement
= group
.requirement
939 placement_group
.strategy
= group
.strategy
941 ### Add specific VDUs to placement group
942 for vdu
in group
.vdu_list
:
943 member_vdu
= placement_group
.member_vdus
.add()
944 member_vdu
.member_vdu_ref
= vdu
.id
946 ### Add all VDUs to placement group
948 member_vdu
= placement_group
.member_vdus
.add()
949 member_vdu
.member_vdu_ref
= vdu
.id
951 # Add VNF access point
954 self
.add_vnf_conf_param_charm()
955 self
.add_charm_config()
957 self
.add_vnf_conf_param()
958 if 'pong_' in self
.name
:
959 self
.add_pong_vca_config()
961 self
.add_ping_vca_config()
963 if 'pong_' in self
.name
:
964 self
.add_pong_config()
966 self
.add_ping_config()
968 def add_ping_config(self
):
969 vnfd
= self
.descriptor
.vnfd
[0]
970 # Add vnf configuration
971 vnf_config
= vnfd
.vnf_configuration
972 vnf_config
.script
.script_type
= 'rift'
974 # Add initial config primitive
975 init_config
= RwVnfdYang
.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_InitialConfigPrimitive
.from_dict(
978 "name": "Ping config",
979 "user_defined_script": "ping_initial_config.py",
982 vnf_config
.initial_config_primitive
.append(init_config
)
984 def add_pong_config(self
):
985 vnfd
= self
.descriptor
.vnfd
[0]
986 # Add vnf configuration
987 vnf_config
= vnfd
.vnf_configuration
988 vnf_config
.script
.script_type
= 'rift'
990 # Add initial config primitive
991 init_config
=RwVnfdYang
.YangData_Vnfd_VnfdCatalog_Vnfd_VnfConfiguration_InitialConfigPrimitive
.from_dict(
994 "name": "Pong config",
995 "user_defined_script": "pong_initial_config.py",
998 vnf_config
.initial_config_primitive
.append(init_config
)
1000 def write_to_file(self
, outdir
, output_format
):
1001 dirpath
= "%s/%s" % (outdir
, self
.name
)
1002 if not os
.path
.exists(dirpath
):
1003 os
.makedirs(dirpath
)
1004 super(VirtualNetworkFunction
, self
).write_to_file(['vnfd', 'rw-vnfd'],
1007 self
.add_scripts(outdir
)
1009 def add_cloud_init(self
, outdir
):
1010 script_dir
= os
.path
.join(outdir
, self
.name
, 'cloud_init')
1012 os
.makedirs(script_dir
)
1014 if not os
.path
.isdir(script_dir
):
1017 if 'ping_' in self
.name
:
1018 script_file
= os
.path
.join(script_dir
, 'ping_cloud_init.cfg')
1019 cfg
= PING_USERDATA_FILE
1021 script_file
= os
.path
.join(script_dir
, 'pong_cloud_init.cfg')
1022 cfg
= PONG_USERDATA_FILE
1024 with
open(script_file
, "w") as f
:
1025 f
.write("{}".format(cfg
))
1027 # Create the config files in script_dir
1028 for cfg_file
in self
.config_files
:
1029 with
open(os
.path
.join(script_dir
, cfg_file
), 'w') as f
:
1030 f
.write('metadata-vdud test')
1032 def add_scripts(self
, outdir
):
1033 if not self
.use_charm
:
1034 self
.add_cloud_init(outdir
)
1036 if not self
.use_charm
:
1037 if self
.use_vca_conf
:
1038 self
.add_vca_scripts(outdir
)
1040 self
.add_config_scripts(outdir
)
1042 def add_config_scripts(self
, outdir
):
1043 dest_path
= os
.path
.join(outdir
, self
.name
, 'scripts')
1045 os
.makedirs(dest_path
)
1047 if not os
.path
.isdir(dest_path
):
1050 if 'pong_' in self
.name
:
1051 scripts
= ['pong_initial_config.py']
1053 scripts
= ['ping_initial_config.py']
1055 for script_name
in scripts
:
1056 src_path
= os
.path
.dirname(os
.path
.abspath(
1057 os
.path
.realpath(__file__
)))
1058 script_src
= os
.path
.join(src_path
, script_name
)
1059 if not os
.path
.exists(script_src
):
1060 src_path
= os
.path
.join(os
.environ
['RIFT_ROOT'],
1061 'modules/core/mano/examples/'
1062 'ping_pong_ns/rift/mano/examples')
1063 script_src
= os
.path
.join(src_path
, script_name
)
1065 shutil
.copy2(script_src
, dest_path
)
1067 def add_vca_scripts(self
, outdir
):
1068 dest_path
= os
.path
.join(outdir
, self
.name
, 'scripts')
1070 os
.makedirs(dest_path
)
1072 if not os
.path
.isdir(dest_path
):
1075 if 'pong_' in self
.name
:
1076 scripts
= ['pong_setup.py', 'pong_start_stop.py']
1078 scripts
= ['ping_setup.py', 'ping_rate.py', 'ping_start_stop.py']
1080 for script_name
in scripts
:
1081 src_path
= os
.path
.dirname(os
.path
.abspath(
1082 os
.path
.realpath(__file__
)))
1083 script_src
= os
.path
.join(src_path
, script_name
)
1084 if not os
.path
.exists(script_src
):
1085 src_path
= os
.path
.join(os
.environ
['RIFT_ROOT'],
1086 'modules/core/mano/examples/'
1087 'ping_pong_ns/rift/mano/examples')
1088 script_src
= os
.path
.join(src_path
, script_name
)
1090 shutil
.copy2(script_src
, dest_path
)
1093 class NetworkService(ManoDescriptor
):
1094 def __init__(self
, name
):
1095 super(NetworkService
, self
).__init
__(name
)
1096 self
._scale
_groups
= []
1097 self
.vnfd_config
= {}
1098 self
._placement
_groups
= []
1100 def default_config(self
, constituent_vnfd
, vnfd
, mano_ut
, use_ns_init_conf
, use_vnf_init_conf
):
1101 vnf_config
= vnfd
.vnfd
.vnf_configuration
1104 def ns_config(self
, nsd
, vnfd_list
, mano_ut
):
1105 # Used by scale group
1107 nsd
.service_primitive
.add().from_dict(
1109 "name": "ping scale",
1110 "user_defined_script": "{}".format(os
.path
.join(
1111 os
.environ
['RIFT_ROOT'],
1112 'modules/core/mano',
1113 'examples/ping_pong_ns/rift/mano/examples',
1114 'ping_config_ut.sh'))
1117 nsd
.service_primitive
.add().from_dict(
1119 "name": "ping scale",
1120 "user_defined_script": "ping_scale.py"
1123 def ns_xconfig(self
, nsd
):
1124 """Used for a testcase."""
1125 nsd
.service_primitive
.add().from_dict(
1127 "name": "primitive_test",
1128 "user_defined_script": "primitive_test.py"
1132 def ns_initial_config(self
, nsd
):
1133 nsd
.initial_service_primitive
.add().from_dict(
1136 "name": "start traffic",
1137 "user_defined_script": "start_traffic.py",
1146 nsd
.terminate_service_primitive
.add().from_dict(
1149 "name": "stop traffic",
1150 "user_defined_script": "stop_traffic.py",
1160 def add_scale_group(self
, scale_group
):
1161 self
._scale
_groups
.append(scale_group
)
1163 def add_placement_group(self
, placement_group
):
1164 self
._placement
_groups
.append(placement_group
)
1166 def create_mon_params(self
, vnfds
):
1167 NsdMonParam
= NsdYang
.YangData_Nsd_NsdCatalog_Nsd_MonitoringParam
1169 for vnfd_obj
in vnfds
:
1170 for mon_param
in vnfd_obj
.vnfd
.monitoring_param
:
1171 nsd_monp
= NsdMonParam
.from_dict({
1172 'id': str(param_id
),
1173 'name': mon_param
.name
,
1174 'aggregation_type': "AVERAGE",
1175 'value_type': mon_param
.value_type
,
1176 'vnfd_monitoring_param': [
1177 {'vnfd_id_ref': vnfd_obj
.vnfd
.id,
1178 'vnfd_monitoring_param_ref': mon_param
.id,
1179 'member_vnf_index_ref': self
.get_member_vnf_index(vnfd_obj
.vnfd
.id)}],
1182 self
.nsd
.monitoring_param
.append(nsd_monp
)
1185 def get_vnfd_id(self
, index
):
1186 for cv
in self
.nsd
.constituent_vnfd
:
1187 if cv
.member_vnf_index
== index
:
1188 return cv
.vnfd_id_ref
1190 def get_member_vnf_index(self
, vnfd_id
):
1191 for cv
in self
.nsd
.constituent_vnfd
:
1192 if cv
.vnfd_id_ref
== vnfd_id
:
1193 return cv
.member_vnf_index
1195 def add_conf_param_map(self
):
1198 confparam_map
= nsd
.config_parameter_map
.add()
1199 confparam_map
.id = '1'
1200 confparam_map
.config_parameter_source
.member_vnf_index_ref
= 2
1201 confparam_map
.config_parameter_source
.vnfd_id_ref
= self
.get_vnfd_id(2)
1202 confparam_map
.config_parameter_source
.config_parameter_source_ref
= 'service_ip'
1203 confparam_map
.config_parameter_request
.member_vnf_index_ref
= 1
1204 confparam_map
.config_parameter_request
.vnfd_id_ref
= self
.get_vnfd_id(1)
1205 confparam_map
.config_parameter_request
.config_parameter_request_ref
= 'pong_ip'
1207 confparam_map
= nsd
.config_parameter_map
.add()
1208 confparam_map
.id = '2'
1209 confparam_map
.config_parameter_source
.member_vnf_index_ref
= 2
1210 confparam_map
.config_parameter_source
.vnfd_id_ref
= self
.get_vnfd_id(2)
1211 confparam_map
.config_parameter_source
.config_parameter_source_ref
= 'service_port'
1212 confparam_map
.config_parameter_request
.member_vnf_index_ref
= 1
1213 confparam_map
.config_parameter_request
.vnfd_id_ref
= self
.get_vnfd_id(1)
1214 confparam_map
.config_parameter_request
.config_parameter_request_ref
= 'pong_port'
1216 def compose(self
, vnfd_list
, cpgroup_list
, mano_ut
,
1217 ns_descriptor_message
,
1218 use_ns_init_conf
=True,
1219 use_vnf_init_conf
=True,
1222 port_security
= None,
1223 use_virtual_ip
=False,
1224 primitive_test
=False,
1225 vnfd_input_params
=False,
1226 script_input_params
=False,
1230 # Disable NS initial config primitive
1231 use_ns_init_conf
= False
1232 use_vnf_init_conf
= False
1234 self
.descriptor
= RwNsdYang
.YangData_Nsd_NsdCatalog()
1235 self
.id = str(uuid
.uuid1())
1236 nsd
= self
.descriptor
.nsd
.add()
1239 nsd
.name
= self
.name
1240 nsd
.short_name
= self
.name
1241 nsd
.vendor
= 'RIFT.io'
1242 nsd
.logo
= 'rift_logo.png'
1243 nsd
.description
= ns_descriptor_message
1245 nsd
.input_parameter_xpath
.append(
1246 NsdYang
.YangData_Nsd_NsdCatalog_Nsd_InputParameterXpath(
1247 xpath
="/nsd-catalog/nsd/vendor",
1251 if vnfd_input_params
:
1252 nsd
.input_parameter_xpath
.append(
1253 NsdYang
.YangData_Nsd_NsdCatalog_Nsd_InputParameterXpath(
1254 xpath
="/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:vendor",
1258 ip_profile
= nsd
.ip_profiles
.add()
1259 ip_profile
.name
= "InterVNFLink"
1260 ip_profile
.description
= "Inter VNF Link"
1261 ip_profile
.ip_profile_params
.ip_version
= "ipv4"
1262 ip_profile
.ip_profile_params
.subnet_address
= "31.31.31.0/24"
1263 ip_profile
.ip_profile_params
.gateway_address
= "31.31.31.210"
1265 ip_profile
.ip_profile_params
.ip_version
= "ipv6"
1266 ip_profile
.ip_profile_params
.subnet_address
= "3fee:1111:1111::/64"
1267 ip_profile
.ip_profile_params
.gateway_address
= "3fee:1111:1111::1"
1270 for cpgroup
in cpgroup_list
:
1272 vld
.id = 'ping_pong_vld%s' % vld_id
1274 vld
.name
= 'ping_pong_vld' # hard coded
1275 vld
.short_name
= vld
.name
1276 vld
.vendor
= 'RIFT.io'
1277 vld
.description
= 'Toy VL'
1279 vld
.type_yang
= 'ELAN'
1280 vld
.ip_profile_ref
= 'InterVNFLink'
1281 for i
, cp
in enumerate(cpgroup
):
1282 cpref
= vld
.vnfd_connection_point_ref
.add()
1283 cpref
.member_vnf_index_ref
= cp
[0]
1284 cpref
.vnfd_id_ref
= cp
[1]
1285 cpref
.vnfd_connection_point_ref
= cp
[2]
1287 vcp
= vld
.virtual_connection_points
.add()
1288 vcp
.name
= 'vcp-{}'.format(i
)
1289 vcp
.type_yang
= 'VPORT'
1290 if port_security
is not None:
1291 vcp
.port_security_enabled
= port_security
1292 vcp
.associated_cps
.append(cpref
.vnfd_connection_point_ref
)
1295 member_vnf_index
= 1
1296 for vnfd
in vnfd_list
:
1297 for i
in range(vnfd
.instance_count
):
1298 constituent_vnfd
= nsd
.constituent_vnfd
.add()
1299 constituent_vnfd
.member_vnf_index
= member_vnf_index
1300 vnfd_index_map
[vnfd
] = member_vnf_index
1302 # Set the start by default to false for ping vnfd,
1303 # if scaling is enabled
1304 if (len(self
._scale
_groups
) and
1305 vnfd
.descriptor
.vnfd
[0].name
== 'ping_vnfd'):
1306 constituent_vnfd
.start_by_default
= False
1308 constituent_vnfd
.vnfd_id_ref
= vnfd
.descriptor
.vnfd
[0].id
1309 if use_vca_conf
is False:
1310 self
.default_config(constituent_vnfd
, vnfd
, mano_ut
,
1311 use_ns_init_conf
, use_vnf_init_conf
)
1312 member_vnf_index
+= 1
1314 if vnfd_input_params
:
1315 nsd
.input_parameter_xpath
.append(
1316 NsdYang
.YangData_Nsd_NsdCatalog_Nsd_InputParameterXpath(
1317 xpath
="/vnfd:vnfd-catalog/vnfd:vnfd[vnfd:id='%s']/vnfd:vendor" % (constituent_vnfd
.vnfd_id_ref
),
1320 nsd
.input_parameter_xpath
.append(
1321 NsdYang
.YangData_Nsd_NsdCatalog_Nsd_InputParameterXpath(
1323 "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:vdu"
1324 "/vnfd:supplemental-boot-data/vnfd:custom-meta-data[vnfd:name='custom_cloud_init_data']/vnfd:value"
1328 nsd
.input_parameter_xpath
.append(
1329 NsdYang
.YangData_Nsd_NsdCatalog_Nsd_InputParameterXpath(
1331 "/vnfd:vnfd-catalog/vnfd:vnfd[vnfd:id='%s']/vnfd:vdu[vnfd:id='%s']"
1332 "/vnfd:supplemental-boot-data/vnfd:custom-meta-data[vnfd:name='custom_cloud_init_data']/vnfd:value"
1333 ) % (constituent_vnfd
.vnfd_id_ref
, vnfd
.descriptor
.vnfd
[0].vdu
[0].id)
1336 nsd
.input_parameter_xpath
.append(
1337 NsdYang
.YangData_Nsd_NsdCatalog_Nsd_InputParameterXpath(
1339 "/vnfd:vnfd-catalog/vnfd:vnfd/vnfd:vdu"
1340 "/vnfd:supplemental-boot-data/vnfd:custom-meta-data[vnfd:name='custom_cloud_meta_data']/vnfd:value"
1344 nsd
.input_parameter_xpath
.append(
1345 NsdYang
.YangData_Nsd_NsdCatalog_Nsd_InputParameterXpath(
1347 "/vnfd:vnfd-catalog/vnfd:vnfd[vnfd:id='%s']/vnfd:vdu[vnfd:id='%s']"
1348 "/vnfd:supplemental-boot-data/vnfd:custom-meta-data[vnfd:name='custom_cloud_meta_data']/vnfd:value"
1349 ) % (constituent_vnfd
.vnfd_id_ref
, vnfd
.descriptor
.vnfd
[0].vdu
[0].id)
1353 if script_input_params
:
1354 nsd
.input_parameter_xpath
.append(
1355 NsdYang
.YangData_Nsd_NsdCatalog_Nsd_InputParameterXpath(
1357 "/vnfd:vnfd-catalog/vnfd:vnfd[vnfd:id='%s']/vnfd:vdu[vnfd:id='%s']"
1358 "/vnfd:supplemental-boot-data/vnfd:custom-meta-data[vnfd:name='CI-script-init-data']/vnfd:value"
1359 ) % (constituent_vnfd
.vnfd_id_ref
, vnfd
.descriptor
.vnfd
[0].vdu
[0].id)
1366 vld
.name
= 'mgmt_vld'
1367 vld
.type_yang
= 'ELAN'
1368 vld
.mgmt_network
= "true"
1369 vld
.vim_network_name
= "private"
1371 ping_cpref
= vld
.vnfd_connection_point_ref
.add()
1372 ping_cpref
.member_vnf_index_ref
= 1
1373 ping_cpref
.vnfd_id_ref
= nsd
.constituent_vnfd
[0].vnfd_id_ref
1374 ping_cpref
.vnfd_connection_point_ref
= 'ping_vnfd/cp0'
1376 pong_cpref
= vld
.vnfd_connection_point_ref
.add()
1377 pong_cpref
.member_vnf_index_ref
= 2
1378 pong_cpref
.vnfd_id_ref
= nsd
.constituent_vnfd
[1].vnfd_id_ref
1379 pong_cpref
.vnfd_connection_point_ref
= 'pong_vnfd/cp0'
1381 # Enable config primitives if either mano_ut or
1382 # scale groups are enabled
1383 if mano_ut
or len(self
._scale
_groups
):
1384 self
.ns_config(nsd
, vnfd_list
, mano_ut
)
1386 # Add NS initial config to start traffic
1387 if use_ns_init_conf
:
1388 self
.ns_initial_config(nsd
)
1391 self
.ns_xconfig(nsd
)
1393 for scale_group
in self
._scale
_groups
:
1394 group_desc
= nsd
.scaling_group_descriptor
.add()
1395 group_desc
.name
= scale_group
.name
1396 group_desc
.max_instance_count
= scale_group
.max_count
1397 group_desc
.min_instance_count
= scale_group
.min_count
1398 for vnfd
, count
in scale_group
.vnfd_count_map
.items():
1399 member
= group_desc
.vnfd_member
.add()
1400 member
.member_vnf_index_ref
= vnfd_index_map
[vnfd
]
1401 member
.count
= count
1403 for trigger
in scale_group
.config_action
:
1404 config_action
= group_desc
.scaling_config_action
.add()
1405 config_action
.trigger
= trigger
1406 config
= scale_group
.config_action
[trigger
]
1407 config_action
.ns_service_primitive_name_ref
= config
['ns-service-primitive-name-ref']
1409 for placement_group
in self
._placement
_groups
:
1410 group
= nsd
.placement_groups
.add()
1411 group
.name
= placement_group
.name
1412 group
.strategy
= placement_group
.strategy
1413 group
.requirement
= placement_group
.requirement
1414 for member_vnfd
in placement_group
.vnfd_list
:
1415 member
= group
.member_vnfd
.add()
1416 member
.vnfd_id_ref
= member_vnfd
.descriptor
.vnfd
[0].id
1417 member
.member_vnf_index_ref
= vnfd_index_map
[member_vnfd
]
1419 self
.create_mon_params(vnfd_list
)
1421 self
.add_conf_param_map()
1423 def write_config(self
, outdir
, vnfds
):
1425 converter
= config_data
.ConfigPrimitiveConvertor()
1426 yaml_data
= converter
.extract_nsd_config(self
.nsd
)
1428 ns_config_dir
= os
.path
.join(outdir
, self
.name
, "ns_config")
1429 os
.makedirs(ns_config_dir
, exist_ok
=True)
1430 vnf_config_dir
= os
.path
.join(outdir
, self
.name
, "vnf_config")
1431 os
.makedirs(vnf_config_dir
, exist_ok
=True)
1434 with
open('%s/%s.yaml' % (ns_config_dir
, self
.id), "w") as fh
:
1437 for i
, vnfd
in enumerate(vnfds
, start
=1):
1438 yaml_data
= converter
.extract_vnfd_config(vnfd
)
1441 with
open('%s/%s__%s.yaml' % (vnf_config_dir
, vnfd
.id, i
), "w") as fh
:
1444 def write_config_scripts(self
, outdir
, script_name
):
1445 src_path
= os
.path
.dirname(os
.path
.abspath(os
.path
.realpath(__file__
)))
1446 script_src
= os
.path
.join(src_path
, script_name
)
1447 if not os
.path
.exists(script_src
):
1448 src_path
= os
.path
.join(os
.environ
['RIFT_ROOT'],
1449 'modules/core/mano/examples/ping_pong_ns/rift/mano/examples')
1450 script_src
= os
.path
.join(src_path
, script_name
)
1452 dest_path
= os
.path
.join(outdir
, 'scripts')
1453 os
.makedirs(dest_path
, exist_ok
=True)
1455 shutil
.copy2(script_src
, dest_path
)
1457 def write_to_file(self
, outdir
, output_format
):
1458 dirpath
= os
.path
.join(outdir
, self
.name
)
1459 if not os
.path
.exists(dirpath
):
1460 os
.makedirs(dirpath
)
1462 super(NetworkService
, self
).write_to_file(["nsd", "rw-nsd"],
1466 # Write the config scripts
1467 self
.write_config_scripts(dirpath
, 'start_traffic.py')
1468 self
.write_config_scripts(dirpath
, 'stop_traffic.py')
1469 self
.write_config_scripts(dirpath
, 'primitive_test.py')
1471 if len(self
._scale
_groups
):
1472 self
.write_config_scripts(dirpath
, 'ping_scale.py')
1475 def get_ping_mon_params(path
):
1479 'name': 'ping-request-tx-count',
1480 'http_endpoint_ref': path
,
1481 'json_query_method': "NAMEKEY",
1482 'value_type': "INT",
1483 'description': 'no of ping requests',
1484 'group_tag': 'Group1',
1485 'widget_type': 'COUNTER',
1491 'name': 'ping-response-rx-count',
1492 'http_endpoint_ref': path
,
1493 'json_query_method': "NAMEKEY",
1494 'value_type': "INT",
1495 'description': 'no of ping responses',
1496 'group_tag': 'Group1',
1497 'widget_type': 'COUNTER',
1503 def get_pong_mon_params(path
):
1507 'name': 'ping-request-rx-count',
1508 'http_endpoint_ref': path
,
1509 'json_query_method': "NAMEKEY",
1510 'value_type': "INT",
1511 'description': 'no of ping requests',
1512 'group_tag': 'Group1',
1513 'widget_type': 'COUNTER',
1519 'name': 'ping-response-tx-count',
1520 'http_endpoint_ref': path
,
1521 'json_query_method': "NAMEKEY",
1522 'value_type': "INT",
1523 'description': 'no of ping responses',
1524 'group_tag': 'Group1',
1525 'widget_type': 'COUNTER',
1531 class ScaleGroup(object):
1532 def __init__(self
, name
, min_count
=1, max_count
=1):
1534 self
.min_count
= min_count
1535 self
.max_count
= max_count
1536 self
.vnfd_count_map
= {}
1537 self
.config_action
= {}
1539 def add_vnfd(self
, vnfd
, vnfd_count
):
1540 self
.vnfd_count_map
[vnfd
] = vnfd_count
1542 def add_config(self
):
1543 self
.config_action
['post_scale_out']= {'ns-service-primitive-name-ref':
1546 class PlacementGroup(object):
1547 def __init__(self
, name
):
1550 self
.requirement
= ''
1552 def add_strategy(self
, strategy
):
1553 self
.strategy
= strategy
1555 def add_requirement(self
, requirement
):
1556 self
.requirement
= requirement
1558 class NsdPlacementGroup(PlacementGroup
):
1559 def __init__(self
, name
):
1561 super(NsdPlacementGroup
, self
).__init
__(name
)
1563 def add_member(self
, vnfd
):
1564 self
.vnfd_list
.append(vnfd
)
1567 class VnfdPlacementGroup(PlacementGroup
):
1568 def __init__(self
, name
):
1570 super(VnfdPlacementGroup
, self
).__init
__(name
)
1572 def add_member(self
, vdu
):
1573 self
.vdu_list
.append(vdu
)
1575 def generate_vnf_and_ns_description_message(descriptor_type
,
1581 # Helper Function to generate a description message for
1582 # VNFD/NSD based on type
1586 suffix_list
.append(" for AWS ")
1588 suffix_list
.append(' ')
1591 suffix_list
.append("EPA")
1593 suffix_list
.append("Charm")
1595 suffix_list
.append("VCA Conf")
1597 suffix_list
.append("VIP")
1598 message
= "Toy Rift.ware " + descriptor_type
+ 'with '.join(filter(None, [suffix_list
[0], ', '.join(suffix_list
[1:])]))
1601 def generate_ping_pong_descriptors(fmt
="json",
1602 write_to_file
=False,
1604 pingcount
=NUM_PING_INSTANCES
,
1605 external_vlr_count
=1,
1606 internal_vlr_count
=1,
1611 use_scale_group
=False,
1615 use_mon_params
=True,
1618 ex_ping_userdata
=None,
1619 ex_pong_userdata
=None,
1620 use_placement_group
=True,
1621 use_ns_init_conf
=True,
1622 use_vnf_init_conf
=True,
1625 use_static_ip
=False,
1628 vnfd_input_params
=None,
1629 script_input_params
=None,
1631 explicit_port_seq
=False,
1633 primitive_test
=False,
1634 use_virtual_ip
=False,
1638 # List of connection point groups
1639 # Each connection point group refers to a virtual link
1640 # the CP group consists of tuples of connection points
1641 if explicit_port_seq
:
1642 # ping and pong each will have two external interfaces.
1643 external_vlr_count
= 2
1645 for i
in range(external_vlr_count
):
1646 cpgroup_list
.append([])
1652 use_ns_init_conf
= True
1653 use_vnf_init_conf
= False
1656 ping
= VirtualNetworkFunction("ping_vnfd%s" % (suffix
), pingcount
)
1657 ping
.use_vnf_init_conf
= use_vnf_init_conf
1659 if use_placement_group
:
1660 ### Add group name Eris
1661 group
= VnfdPlacementGroup('Eris')
1662 group
.add_strategy('COLOCATION')
1663 group
.add_requirement('''Place this VM on the Kuiper belt object Eris''')
1664 ping
.add_placement_group(group
)
1666 # ping = VirtualNetworkFunction("ping_vnfd", pingcount)
1667 if not ping_userdata
:
1668 ping_userdata
= PING_USERDATA_FILE
1670 if ex_ping_userdata
:
1671 ping_userdata
= '''\
1675 ping_userdata
=ping_userdata
,
1676 ex_ping_userdata
=ex_ping_userdata
1678 ns_descriptor_message
= generate_vnf_and_ns_description_message("NS", aws
, use_epa
,
1679 use_charm
, use_vca_conf
,
1682 vnf_descriptor_message
= generate_vnf_and_ns_description_message("VNF", aws
, use_epa
,
1683 use_charm
, use_vca_conf
,
1686 "Fedora-x86_64-20-20131211.1-sda-ping.qcow2",
1687 vnf_descriptor_message
,
1689 use_ping_cloud_init_file
,
1690 "api/v1/ping/stats",
1691 get_ping_mon_params("api/v1/ping/stats") if use_mon_params
else [],
1694 num_vlr_count
=external_vlr_count
,
1695 num_ivlr_count
=internal_vlr_count
,
1696 num_vms
=num_vnf_vms
,
1697 image_md5sum
=ping_md5sum
,
1699 use_ns_init_conf
=use_ns_init_conf
,
1700 use_vca_conf
=use_vca_conf
,
1701 use_charm
=use_charm
,
1702 use_static_ip
=use_static_ip
,
1703 port_security
=port_security
,
1704 metadata_vdud
=metadata_vdud
,
1705 vnfd_input_params
=vnfd_input_params
,
1706 script_input_params
=script_input_params
,
1707 multidisk
=multidisk
,
1708 explicit_port_seq
=explicit_port_seq
,
1710 use_virtual_ip
=use_virtual_ip
,
1713 pong
= VirtualNetworkFunction("pong_vnfd%s" % (suffix
))
1715 if use_placement_group
:
1716 ### Add group name Weywot
1717 group
= VnfdPlacementGroup('Weywot')
1718 group
.add_strategy('COLOCATION')
1719 group
.add_requirement('''Place this VM on the Kuiper belt object Weywot''')
1720 pong
.add_placement_group(group
)
1723 # pong = VirtualNetworkFunction("pong_vnfd")
1725 if not pong_userdata
:
1726 pong_userdata
= PONG_USERDATA_FILE
1728 if ex_pong_userdata
:
1729 pong_userdata
= '''\
1733 pong_userdata
=pong_userdata
,
1734 ex_pong_userdata
=ex_pong_userdata
1739 "Fedora-x86_64-20-20131211.1-sda-pong.qcow2",
1740 vnf_descriptor_message
,
1742 use_pong_cloud_init_file
,
1743 "api/v1/pong/stats",
1744 get_pong_mon_params("api/v1/pong/stats") if use_mon_params
else [],
1747 num_vlr_count
=external_vlr_count
,
1748 num_ivlr_count
=internal_vlr_count
,
1749 num_vms
=num_vnf_vms
,
1750 image_md5sum
=pong_md5sum
,
1752 use_ns_init_conf
=use_ns_init_conf
,
1753 use_vca_conf
=use_vca_conf
,
1754 use_charm
=use_charm
,
1755 use_static_ip
=use_static_ip
,
1756 port_security
=False if port_security
else port_security
,
1757 metadata_vdud
=metadata_vdud
,
1758 vnfd_input_params
=vnfd_input_params
,
1759 script_input_params
=script_input_params
,
1760 multidisk
=multidisk
,
1761 explicit_port_seq
=explicit_port_seq
,
1763 use_virtual_ip
=use_virtual_ip
,
1766 # Initialize the member VNF index
1767 member_vnf_index
= 1
1769 # define the connection point groups
1770 for index
, cp_group
in enumerate(cpgroup_list
):
1771 if explicit_port_seq
:
1772 member_vnf_index
= 1
1773 desc_id
= ping
.descriptor
.vnfd
[0].id
1774 filename
= 'ping_vnfd{}/cp{}'.format(suffix
, index
+1)
1776 for idx
in range(pingcount
):
1783 member_vnf_index
+= 1
1785 desc_id
= pong
.descriptor
.vnfd
[0].id
1786 filename
= 'pong_vnfd{}/cp{}'.format(suffix
, index
+1)
1794 member_vnf_index
+= 1
1796 vnfd_list
= [ping
, pong
]
1798 if nsd_name
is None:
1799 nsd_name
= "ping_pong_nsd%s" % (suffix
)
1801 nsd_catalog
= NetworkService(nsd_name
)
1804 group
= ScaleGroup("ping_group", max_count
=10)
1805 group
.add_vnfd(ping
, 1)
1807 nsd_catalog
.add_scale_group(group
)
1809 if use_placement_group
:
1810 ### Add group name Orcus
1811 group
= NsdPlacementGroup('Orcus')
1812 group
.add_strategy('COLOCATION')
1813 group
.add_requirement('''Place this VM on the Kuiper belt object Orcus''')
1815 for member_vnfd
in vnfd_list
:
1816 group
.add_member(member_vnfd
)
1818 nsd_catalog
.add_placement_group(group
)
1820 ### Add group name Quaoar
1821 group
= NsdPlacementGroup('Quaoar')
1822 group
.add_strategy('COLOCATION')
1823 group
.add_requirement('''Place this VM on the Kuiper belt object Quaoar''')
1825 for member_vnfd
in vnfd_list
:
1826 group
.add_member(member_vnfd
)
1828 nsd_catalog
.add_placement_group(group
)
1831 nsd_catalog
.compose(vnfd_list
,
1834 ns_descriptor_message
,
1835 use_ns_init_conf
=use_ns_init_conf
,
1836 use_vnf_init_conf
=use_vnf_init_conf
,
1837 use_vca_conf
=use_vca_conf
,
1839 port_security
=port_security
,
1840 use_virtual_ip
=use_virtual_ip
,
1841 primitive_test
=primitive_test
,
1842 vnfd_input_params
=vnfd_input_params
,
1843 script_input_params
=script_input_params
)
1846 ping
.write_to_file(out_dir
, ping_fmt
if ping_fmt
is not None else fmt
)
1847 pong
.write_to_file(out_dir
, pong_fmt
if ping_fmt
is not None else fmt
)
1848 nsd_catalog
.write_config(out_dir
, vnfd_list
)
1849 nsd_catalog
.write_to_file(out_dir
, ping_fmt
if nsd_fmt
is not None else fmt
)
1850 return (ping
, pong
, nsd_catalog
)
1853 def main(argv
=sys
.argv
[1:]):
1854 global outdir
, output_format
, use_epa
, aws
, use_ping_cloud_init_file
, use_pong_cloud_init_file
1855 parser
= argparse
.ArgumentParser()
1856 parser
.add_argument('-o', '--outdir', default
='.')
1857 parser
.add_argument('-f', '--format', default
='json')
1858 parser
.add_argument('-e', '--epa', action
="store_true", default
=False)
1859 parser
.add_argument('-a', '--aws', action
="store_true", default
=False)
1860 parser
.add_argument('--vnf-input-parameter', action
="store_true", default
=False)
1861 parser
.add_argument('-n', '--pingcount', default
=NUM_PING_INSTANCES
)
1862 parser
.add_argument('--ping-image-md5')
1863 parser
.add_argument('--pong-image-md5')
1864 parser
.add_argument('--ping-cloud-init', default
=None)
1865 parser
.add_argument('--pong-cloud-init', default
=None)
1866 parser
.add_argument('--charm', action
="store_true", default
=False)
1867 parser
.add_argument('-v', '--vca_conf', action
="store_true", default
=False)
1868 parser
.add_argument('--virtual-ip', action
="store_true", default
=False)
1869 parser
.add_argument('--static-ip', action
="store_true", default
=False)
1870 parser
.add_argument('--scale', action
="store_true", default
=False)
1871 parser
.add_argument('--primitive-test', action
="store_true", default
=False)
1873 args
= parser
.parse_args()
1874 outdir
= args
.outdir
1875 output_format
= args
.format
1877 use_vnf_input_params
= args
.vnf_input_parameter
1879 pingcount
= int(args
.pingcount
)
1880 use_ping_cloud_init_file
= args
.ping_cloud_init
1881 use_pong_cloud_init_file
= args
.pong_cloud_init
1883 generate_ping_pong_descriptors(args
.format
, True, args
.outdir
, pingcount
,
1884 ping_md5sum
=args
.ping_image_md5
,
1885 pong_md5sum
=args
.pong_image_md5
,
1887 use_scale_group
=args
.scale
,
1888 use_charm
=args
.charm
,
1889 use_vca_conf
=args
.vca_conf
,
1890 use_virtual_ip
=args
.virtual_ip
,
1891 use_static_ip
=args
.static_ip
,
1892 primitive_test
=args
.primitive_test
,
1893 vnfd_input_params
=use_vnf_input_params
1896 if __name__
== "__main__":