2 # ============LICENSE_START====================================================
3 # org.onap.vvp/validation-scripts
4 # ===================================================================
5 # Copyright © 2017 AT&T Intellectual Property. All rights reserved.
6 # ===================================================================
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
13 # http://www.apache.org/licenses/LICENSE-2.0
15 # Unless required by applicable law or agreed to in writing, software
16 # distributed under the License is distributed on an "AS IS" BASIS,
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.
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
28 # https://creativecommons.org/licenses/by/4.0/
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.
36 # ============LICENSE_END============================================
48 from .structures import Heat
49 from .helpers import validates
53 RE_NETWORK_ROLE = re.compile(
54 r".+_" r"\d+_" r"(int_)?" r"(subint_)?" r"(?P<network_role>.+)" r"_vmi_" r"\d$"
58 def get_network_role(rid):
59 """return the network_role parsed from the rid.
61 match = RE_NETWORK_ROLE.match(rid)
62 return match.groupdict()["network_role"] if match else None
65 def run_test(heat_template, validate):
66 """call validate for each fixed_ips
68 heat = Heat(filepath=heat_template)
69 if not heat.resources:
70 pytest.skip("No resources found")
72 contrail_resources = heat.contrail_resources
73 if not contrail_resources:
74 pytest.skip("No Contrail resources found")
78 for rid, resource in contrail_resources.items():
79 network_role = get_network_role(rid)
80 if network_role is None:
82 virtual_network_refs = heat.nested_get(
83 resource, "properties", "virtual_network_refs"
85 if virtual_network_refs is None:
87 if not isinstance(virtual_network_refs, list):
88 bad[rid] = "properties.virtual_network_refs must be a list."
90 error = validate(heat, virtual_network_refs, network_role)
97 "Bad OS::ContrailV2::VirtualMachineInterface: %s"
98 % (", ".join("%s: %s" % (rid, error) for rid, error in bad.items()))
101 pytest.skip("No Contrail virtual_network_refs found")
104 def validate_virtual_network_refs(heat, virtual_network_refs, network_role):
105 """ensure there is a matching virtual_network_ref in the list.
106 Returns error message string or None.
108 expect = "%s_net_fqdn" % network_role
109 for vn_ref in virtual_network_refs:
110 param = heat.nested_get(vn_ref, "get_param")
112 param_type = heat.nested_get(heat.parameters, param, "type")
113 if param_type != "string":
115 'virtual_network_ref parameter "%s" '
116 'type "%s" must be "string"' % (param, param_type)
120 return "virtual_network_refs must include {get_param: %s}" % expect
123 # pylint: disable=invalid-name
126 @validates("R-02164")
127 def test_contrail_fqdn(heat_template):
129 When a VNF's Heat Orchestration Template's Contrail resource
131 references an external network that requires the network's
132 Fully Qualified Domain Name (FQDN), the property parameter
134 * **MUST** follow the format ``{network-role}_net_fqdn``
135 * **MUST** be declared as type ``string``
137 run_test(heat_template, validate_virtual_network_refs)