[VVP] Adding preload generation functionality
[vvp/validation-scripts.git] / ice_validator / preload_grapi / grapi_generator.py
1 # -*- coding: utf8 -*-
2 # ============LICENSE_START====================================================
3 # org.onap.vvp/validation-scripts
4 # ===================================================================
5 # Copyright © 2019 AT&T Intellectual Property. All rights reserved.
6 # ===================================================================
7 #
8 # Unless otherwise specified, all software contained herein is licensed
9 # under the Apache License, Version 2.0 (the "License");
10 # you may not use this software except in compliance with the License.
11 # You may obtain a copy of the License at
12 #
13 #             http://www.apache.org/licenses/LICENSE-2.0
14 #
15 # Unless required by applicable law or agreed to in writing, software
16 # distributed under the License is distributed on an "AS IS" BASIS,
17 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 # See the License for the specific language governing permissions and
19 # limitations under the License.
20 #
21 #
22 #
23 # Unless otherwise specified, all documentation contained herein is licensed
24 # under the Creative Commons License, Attribution 4.0 Intl. (the "License");
25 # you may not use this documentation except in compliance with the License.
26 # You may obtain a copy of the License at
27 #
28 #             https://creativecommons.org/licenses/by/4.0/
29 #
30 # Unless required by applicable law or agreed to in writing, documentation
31 # distributed under the License is distributed on an "AS IS" BASIS,
32 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
33 # See the License for the specific language governing permissions and
34 # limitations under the License.
35 #
36 # ============LICENSE_END============================================
37 import json
38 import os
39
40 from preload import (
41     AbstractPreloadGenerator,
42     get_or_create_template,
43     get_json_template,
44     replace,
45 )
46
47 THIS_DIR = os.path.dirname(os.path.abspath(__file__))
48 DATA_DIR = os.path.join(THIS_DIR, "grapi_data")
49
50
51 def get_or_create_network_template(network, vm_networks):
52     """
53     If the network role already exists in vm_networks, then
54     return that otherwise create a blank template and return that
55     """
56     return get_or_create_template(
57         DATA_DIR, "network-role", network, vm_networks, "vm-network"
58     )
59
60
61 def add_fixed_ips(network_template, fixed_ips, uses_dhcp):
62     items = network_template["network-information-items"]["network-information-item"]
63     ipv4s = next(item for item in items if item["ip-version"] == "4")
64     ipv6s = next(item for item in items if item["ip-version"] == "6")
65     if uses_dhcp:
66         ipv4s["use-dhcp"] = "Y"
67         ipv6s["use-dhcp"] = "Y"
68     for ip in fixed_ips:
69         target = ipv4s if ip.ip_version == 4 else ipv6s
70         ips = target["network-ips"]["network-ip"]
71         if ip.param not in ips:
72             ips.append(replace(ip.param))
73         target["ip-count"] += 1
74
75
76 def add_floating_ips(network_template, floating_ips):
77     for ip in floating_ips:
78         key = "floating-ip-v4" if ip.ip_version == 4 else "floating-ip-v6"
79         ips = network_template["floating-ips"][key]
80         value = replace(ip.param)
81         if value not in ips:
82             ips.append(value)
83
84
85 class GrApiPreloadGenerator(AbstractPreloadGenerator):
86     @classmethod
87     def supports_output_passing(cls):
88         return True
89
90     @classmethod
91     def format_name(cls):
92         return "GR-API"
93
94     @classmethod
95     def output_sub_dir(cls):
96         return "grapi"
97
98     def generate_module(self, vnf_module):
99         template = get_json_template(DATA_DIR, "preload_template")
100         self._populate(template, vnf_module)
101         vnf_name = vnf_module.vnf_name
102         outfile = "{}/{}.json".format(self.output_dir, vnf_name)
103         with open(outfile, "w") as f:
104             json.dump(template, f, indent=4)
105
106     def _populate(self, preload, vnf_module):
107         self._add_vnf_metadata(preload)
108         self._add_vms(preload, vnf_module)
109         self._add_availability_zones(preload, vnf_module)
110         self._add_parameters(preload, vnf_module)
111         self._add_vnf_networks(preload, vnf_module)
112
113     @staticmethod
114     def _add_vms(preload, vnf_module):
115         vms = preload["input"]["preload-vf-module-topology-information"][
116             "vf-module-topology"
117         ]["vf-module-assignments"]["vms"]["vm"]
118         for vm in vnf_module.virtual_machine_types:
119             vm_template = get_json_template(DATA_DIR, "vm")
120             vms.append(vm_template)
121             vm_template["vm-type"] = vm.vm_type
122             vm_template["vm-names"]["vm-name"].extend(map(replace, vm.names))
123             vm_template["vm-count"] = vm.vm_count
124             vm_networks = vm_template["vm-networks"]["vm-network"]
125             for port in vm.ports:
126                 role = port.network.network_role
127                 network_template = get_or_create_network_template(role, vm_networks)
128                 network_template["network-role"] = role
129                 add_fixed_ips(network_template, port.fixed_ips, port.uses_dhcp)
130                 add_floating_ips(network_template, port.floating_ips)
131
132     @staticmethod
133     def _add_availability_zones(preload, vnf_module):
134         zones = preload["input"]["preload-vf-module-topology-information"][
135             "vnf-resource-assignments"
136         ]["availability-zones"]["availability-zone"]
137         zones.extend(map(replace, vnf_module.availability_zones))
138
139     @staticmethod
140     def _add_parameters(preload, vnf_module):
141         params = [
142             {"name": key, "value": value}
143             for key, value in vnf_module.preload_parameters.items()
144         ]
145         preload["input"]["preload-vf-module-topology-information"][
146             "vf-module-topology"
147         ]["vf-module-parameters"]["param"].extend(params)
148
149     @staticmethod
150     def _add_vnf_networks(preload, vnf_module):
151         networks = preload["input"]["preload-vf-module-topology-information"][
152             "vnf-resource-assignments"
153         ]["vnf-networks"]["vnf-network"]
154         for network in vnf_module.networks:
155             network_data = {
156                 "network-role": network.network_role,
157                 "network-name": replace("network name of {}".format(network.name_param)),
158             }
159             if network.subnet_params:
160                 network_data["subnets-data"] = {"subnet-data": []}
161                 subnet_data = network_data["subnets-data"]["subnet-data"]
162                 for subnet_param in network.subnet_params:
163                     subnet_data.append({"subnet-id": replace(subnet_param)})
164             networks.append(network_data)
165
166     @staticmethod
167     def _add_vnf_metadata(preload):
168         topology = preload["input"]["preload-vf-module-topology-information"]
169         vnf_meta = topology["vnf-topology-identifier-structure"]
170         vnf_meta["vnf-name"] = replace("vnf_name")
171         vnf_meta["vnf-type"] = replace("Concatenation of "
172                                        "<Service Name>/<VF Instance Name> "
173                                        "MUST MATCH SDC")
174         module_meta = topology["vf-module-topology"]["vf-module-topology-identifier"]
175         module_meta["vf-module-name"] = replace("vf_module_name")
176         module_meta["vf-module-type"] = replace("<vfModuleModelName> from CSAR or SDC")