From 503041fb7ec395fe57e418d584c4a5d06f4c9877 Mon Sep 17 00:00:00 2001 From: "stark, steven" Date: Mon, 13 May 2019 14:41:55 -0700 Subject: [PATCH] [VVP] Adding tests for new reqs from VNFRQTS-630 Added tests for reqs: R-100010, R-100030, R-100050, R-100070, R-100090, R-100110, R-100130, R-100150, R-100200, R-100220, R-100240, R-100310, R-100330, R-100360, R-100370, R-100260, R-100000, R-100190, R-100350 Updated neutron param tests to re-use validation code for contrail tests Change-Id: I84af725ca9de176dc690fffda01ffcad453213ea Issue-ID: VVP-211 Signed-off-by: stark, steven --- .../fail/fail.yaml | 42 +++++ .../pass/pass.yaml | 42 +++++ .../fail/fail0.yaml | 2 +- .../test_contrail_vmi_parameters/fail/fail.yaml | 65 +++++++ .../test_contrail_vmi_parameters/pass/pass.yaml | 65 +++++++ .../fail/fail0.yaml | 20 +++ .../fail/fail1.yaml | 6 +- ice_validator/tests/helpers.py | 8 +- ice_validator/tests/structures.py | 82 ++------- ...d_address_pairs_include_vm_type_network_role.py | 11 +- .../tests/test_contrail_instance_ip_parameters.py | 133 +++++++++++++++ .../tests/test_contrail_instance_ip_resource_id.py | 11 +- .../tests/test_contrail_vmi_parameters.py | 99 +++++++++++ .../tests/test_contrail_vmi_resource_id.py | 4 +- .../test_fixed_ips_include_vm_type_network_role.py | 7 +- ice_validator/tests/test_nested_parameters.py | 3 +- .../tests/test_neutron_port_fixed_ips_subnet.py | 32 +--- ice_validator/tests/utils/ports.py | 186 ++++++++++----------- 18 files changed, 599 insertions(+), 219 deletions(-) create mode 100644 ice_validator/tests/fixtures/test_contrail_instance_ip_parameters/fail/fail.yaml create mode 100644 ice_validator/tests/fixtures/test_contrail_instance_ip_parameters/pass/pass.yaml create mode 100644 ice_validator/tests/fixtures/test_contrail_vmi_parameters/fail/fail.yaml create mode 100644 ice_validator/tests/fixtures/test_contrail_vmi_parameters/pass/pass.yaml create mode 100644 ice_validator/tests/test_contrail_instance_ip_parameters.py create mode 100644 ice_validator/tests/test_contrail_vmi_parameters.py diff --git a/ice_validator/tests/fixtures/test_contrail_instance_ip_parameters/fail/fail.yaml b/ice_validator/tests/fixtures/test_contrail_instance_ip_parameters/fail/fail.yaml new file mode 100644 index 0000000..d7770d7 --- /dev/null +++ b/ice_validator/tests/fixtures/test_contrail_instance_ip_parameters/fail/fail.yaml @@ -0,0 +1,42 @@ +heat_template_version: 2015-04-30 + +description: fdsafsfsa + +parameters: + + TESTDB_int_priav_ips: + type: comma_delimited_list + description: asnfjl + + TESTDB_private_ips: + type: string + description: asnfjl + + priv_subnet_id: + type: string + description: asnfjl + + privte_v6_subnet_id: + type: string + description: asnfjl + +resources: + + TESTDB_0_int_priv_vmi_0_IP_0: + type: OS::ContrailV2::InstanceIp + properties: + virtual_machine_interface_refs: { get_resource: TESTDB_0_priv_vmi_0 } + virtual_network_refs: [{ get_resource: int_priv_network }] + instance_ip_address: { get_param: [TESTDB_int_priav_ips, 0] } + subnet_uuid: { get_param: priv_subnet_id } + + TESTDB_0_private_vmi_1_IP_0: + type: OS::ContrailV2::InstanceIp + properties: + virtual_machine_interface_refs: { get_resource: TESTDB_1_priv_vmi_0 } + virtual_network_refs: [{ get_param: priv_net_fqdn }] + instance_ip_address: { get_param: [TESTDB_private_ips, 1] } + subnet_uuid: { get_param: privte_v6_subnet_id } + + #testnlksadf: + # type: http://www.google.com diff --git a/ice_validator/tests/fixtures/test_contrail_instance_ip_parameters/pass/pass.yaml b/ice_validator/tests/fixtures/test_contrail_instance_ip_parameters/pass/pass.yaml new file mode 100644 index 0000000..8645348 --- /dev/null +++ b/ice_validator/tests/fixtures/test_contrail_instance_ip_parameters/pass/pass.yaml @@ -0,0 +1,42 @@ +heat_template_version: 2015-04-30 + +description: fdsafsfsa + +parameters: + + TESTDB_int_priv_ips: + type: comma_delimited_list + description: asnfjl + + TESTDB_private_ips: + type: comma_delimited_list + description: asnfjl + + int_priv_subnet_id: + type: string + description: asnfjl + + private_v6_subnet_id: + type: string + description: asnfjl + +resources: + + TESTDB_0_int_priv_vmi_0_IP_0: + type: OS::ContrailV2::InstanceIp + properties: + virtual_machine_interface_refs: { get_resource: TESTDB_0_priv_vmi_0 } + virtual_network_refs: [{ get_resource: int_priv_network }] + instance_ip_address: { get_param: [TESTDB_int_priv_ips, 0] } + subnet_uuid: { get_param: int_priv_subnet_id } + + TESTDB_0_private_vmi_1_IP_0: + type: OS::ContrailV2::InstanceIp + properties: + virtual_machine_interface_refs: { get_resource: TESTDB_1_priv_vmi_0 } + virtual_network_refs: [{ get_param: priv_net_fqdn }] + instance_ip_address: { get_param: [TESTDB_private_ips, 1] } + subnet_uuid: { get_param: private_v6_subnet_id } + + #testnlksadf: + # type: http://www.google.com diff --git a/ice_validator/tests/fixtures/test_contrail_instance_ip_resource_id/fail/fail0.yaml b/ice_validator/tests/fixtures/test_contrail_instance_ip_resource_id/fail/fail0.yaml index a5f5e16..92bdb35 100644 --- a/ice_validator/tests/fixtures/test_contrail_instance_ip_resource_id/fail/fail0.yaml +++ b/ice_validator/tests/fixtures/test_contrail_instance_ip_resource_id/fail/fail0.yaml @@ -42,7 +42,7 @@ resources: - vm_typeS_0_bialy_port_0: + vm_typeS_0_int_bialy_port_0: type: OS::ContrailV2::InstanceIp properties: virtual_network_refs: diff --git a/ice_validator/tests/fixtures/test_contrail_vmi_parameters/fail/fail.yaml b/ice_validator/tests/fixtures/test_contrail_vmi_parameters/fail/fail.yaml new file mode 100644 index 0000000..248f9ec --- /dev/null +++ b/ice_validator/tests/fixtures/test_contrail_vmi_parameters/fail/fail.yaml @@ -0,0 +1,65 @@ +heat_template_version: 2015-04-30 + +description: fdsafsfsa + +parameters: + + TESTDB_priv_floating_ips: + type: comma_delimited_list + description: asnfjl + + TESTDB_int_priav_floating_ip: + type: string + description: asnfjl + +resources: + + TESTDB_0_priv_vmi_0: + type: OS::ContrailV2::VirtualMachineInterface + properties: + virtual_machine_interface_properties: + virtual_machine_interface_properties_service_interface_type: { + "priv_interface_type" + } + virtual_network_refs: + - get_param: priv_net_fqdn + virtual_machine_interface_allowed_address_pairs: + { + virtual_machine_interface_allowed_address_pairs_allowed_address_pair: + [{ + virtual_machine_interface_allowed_address_pairs_allowed_address_pair_ip: + { + virtual_machine_interface_allowed_address_pairs_allowed_address_pair_ip_ip_prefix: { get_param: [TESTDB_priv_floating_ip, 0] }, + virtual_machine_interface_allowed_address_pairs_allowed_address_pair_ip_ip_prefix_len: "dsafasdF", + }, + virtual_machine_interface_allowed_address_pairs_allowed_address_pair_mac: "sdnfjkas", + virtual_machine_interface_allowed_address_pairs_allowed_address_pair_address_mode: "sadfnjasdfknj", + }], + } + + + TESTDB_0_int_private_vmi_0: + type: OS::ContrailV2::VirtualMachineInterface + properties: + virtual_machine_interface_properties: + virtual_machine_interface_properties_service_interface_type: { + "priv_interface_type" + } + virtual_network_refs: + - get_param: priv_net_fqdn + virtual_machine_interface_allowed_address_pairs: + { + virtual_machine_interface_allowed_address_pairs_allowed_address_pair: + [{ + virtual_machine_interface_allowed_address_pairs_allowed_address_pair_ip: + { + virtual_machine_interface_allowed_address_pairs_allowed_address_pair_ip_ip_prefix: { get_param: TESTDB_int_priav_floating_ip }, + virtual_machine_interface_allowed_address_pairs_allowed_address_pair_ip_ip_prefix_len: "dsafasdF", + }, + virtual_machine_interface_allowed_address_pairs_allowed_address_pair_mac: "sdnfjkas", + virtual_machine_interface_allowed_address_pairs_allowed_address_pair_address_mode: "sadfnjasdfknj", + }], + } + + #testnlksadf: + # type: http://www.google.com diff --git a/ice_validator/tests/fixtures/test_contrail_vmi_parameters/pass/pass.yaml b/ice_validator/tests/fixtures/test_contrail_vmi_parameters/pass/pass.yaml new file mode 100644 index 0000000..df4ca00 --- /dev/null +++ b/ice_validator/tests/fixtures/test_contrail_vmi_parameters/pass/pass.yaml @@ -0,0 +1,65 @@ +heat_template_version: 2015-04-30 + +description: fdsafsfsa + +parameters: + + TESTDB_priv_floating_ip: + type: string + description: asnfjl + + TESTDB_int_private_floating_ips: + type: comma_delimited_list + description: asnfjl + +resources: + + TESTDB_0_priv_vmi_0: + type: OS::ContrailV2::VirtualMachineInterface + properties: + virtual_machine_interface_properties: + virtual_machine_interface_properties_service_interface_type: { + "priv_interface_type" + } + virtual_network_refs: + - get_param: priv_net_fqdn + virtual_machine_interface_allowed_address_pairs: + { + virtual_machine_interface_allowed_address_pairs_allowed_address_pair: + [{ + virtual_machine_interface_allowed_address_pairs_allowed_address_pair_ip: + { + virtual_machine_interface_allowed_address_pairs_allowed_address_pair_ip_ip_prefix: { get_param: TESTDB_priv_floating_ip }, + virtual_machine_interface_allowed_address_pairs_allowed_address_pair_ip_ip_prefix_len: "dsafasdF", + }, + virtual_machine_interface_allowed_address_pairs_allowed_address_pair_mac: "sdnfjkas", + virtual_machine_interface_allowed_address_pairs_allowed_address_pair_address_mode: "sadfnjasdfknj", + }], + } + + + TESTDB_0_int_private_vmi_0: + type: OS::ContrailV2::VirtualMachineInterface + properties: + virtual_machine_interface_properties: + virtual_machine_interface_properties_service_interface_type: { + "priv_interface_type" + } + virtual_network_refs: + - get_param: priv_net_fqdn + virtual_machine_interface_allowed_address_pairs: + { + virtual_machine_interface_allowed_address_pairs_allowed_address_pair: + [{ + virtual_machine_interface_allowed_address_pairs_allowed_address_pair_ip: + { + virtual_machine_interface_allowed_address_pairs_allowed_address_pair_ip_ip_prefix: { get_param: [TESTDB_int_private_floating_ips, 0] }, + virtual_machine_interface_allowed_address_pairs_allowed_address_pair_ip_ip_prefix_len: "dsafasdF", + }, + virtual_machine_interface_allowed_address_pairs_allowed_address_pair_mac: "sdnfjkas", + virtual_machine_interface_allowed_address_pairs_allowed_address_pair_address_mode: "sadfnjasdfknj", + }], + } + + #testnlksadf: + # type: http://www.google.com diff --git a/ice_validator/tests/fixtures/test_neutron_port_fixed_ips_subnet/fail/fail0.yaml b/ice_validator/tests/fixtures/test_neutron_port_fixed_ips_subnet/fail/fail0.yaml index 901072f..de509a2 100644 --- a/ice_validator/tests/fixtures/test_neutron_port_fixed_ips_subnet/fail/fail0.yaml +++ b/ice_validator/tests/fixtures/test_neutron_port_fixed_ips_subnet/fail/fail0.yaml @@ -51,6 +51,8 @@ parameters: type: comma_delimited_list subnet_param: type: comma_delimited_list + int_subnet_param: + type: comma_delimited_list subnet_id_param: type: comma_delimited_list @@ -92,3 +94,21 @@ resources: metadata: port_type: SR-IOV_Mirrored_Trunk + vm_typeX_3_int_bialy_port_2: + type: OS::Neutron::Port + properties: + network: { get_param: extnet_net_id } + fixed_ips: + - ip_address: { get_param: lb_2_extnet_floating_v6_ip } + subnet: { get_param: int_subnet_param } + binding:vnic_type: direct + value_specs: + vlan_filter: {get_param: vm_typeX_bialy_vlan_filter} + public_vlans: {get_param: vm_typeX_bialy_public_vlans} + private_vlans: {get_param: vm_typeX_bialy_private_vlans} + guest_vlans: {get_param: vm_typeX_bialy_guest_vlans} + vlan_mirror: + ATT_FABRIC_CONFIGURATION_REQUIRED: true + metadata: + port_type: SR-IOV_Mirrored_Trunk + diff --git a/ice_validator/tests/fixtures/test_neutron_port_fixed_ips_subnet/fail/fail1.yaml b/ice_validator/tests/fixtures/test_neutron_port_fixed_ips_subnet/fail/fail1.yaml index 60f9874..9233707 100644 --- a/ice_validator/tests/fixtures/test_neutron_port_fixed_ips_subnet/fail/fail1.yaml +++ b/ice_validator/tests/fixtures/test_neutron_port_fixed_ips_subnet/fail/fail1.yaml @@ -53,6 +53,8 @@ parameters: type: comma_delimited_list bialy_subnet_id: type: string + int_biay_subnet_id: + type: string resources: @@ -74,13 +76,13 @@ resources: metadata: port_type: SR-IOV_Trunk - vm_typeX_3_bialy_port_2: + vm_typeX_3_int_bialy_port_2: type: OS::Neutron::Port properties: network: { get_param: extnet_net_id } fixed_ips: - ip_address: { get_param: lb_2_extnet_floating_v6_ip } - subnet: { get_param: bialy_susbnet } + subnet: { get_param: int_biay_subnet_id } binding:vnic_type: direct value_specs: vlan_filter: {get_param: vm_typeX_bialy_vlan_filter} diff --git a/ice_validator/tests/helpers.py b/ice_validator/tests/helpers.py index afa8672..c73a118 100644 --- a/ice_validator/tests/helpers.py +++ b/ice_validator/tests/helpers.py @@ -310,17 +310,17 @@ def parameter_type_to_heat_type(parameter): def prop_iterator(resource, *props): - terminators = ["get_resource", "get_attr", "str_replace"] + terminators = ["get_resource", "get_attr", "str_replace", "get_param"] if "properties" in resource: resource = resource.get("properties") props = list(props) - if isinstance(resource, dict) and "get_param" in resource: - yield resource.get("get_param") + if isinstance(resource, dict) and any(x for x in terminators if x in resource): + yield resource else: prop = resource.get(props.pop(0)) if isinstance(prop, list): for x in prop: yield from prop_iterator(x, *props) - elif isinstance(prop, dict) and not any(x for x in terminators if x in prop): + elif isinstance(prop, dict): yield from prop_iterator(prop, *props) diff --git a/ice_validator/tests/structures.py b/ice_validator/tests/structures.py index a6b2015..8abe87b 100644 --- a/ice_validator/tests/structures.py +++ b/ice_validator/tests/structures.py @@ -229,7 +229,7 @@ class ContrailV2NetworkFlavorBaseProcessor(HeatProcessor): network_flavor_external = "external" network_flavor_internal = "internal" - network_flavor_subint = "subint" + network_flavor_subint = "subinterface" @classmethod def get_network_flavor(cls, resource): @@ -270,7 +270,7 @@ class ContrailV2InstanceIpProcessor(ContrailV2NetworkFlavorBaseProcessor): re_rids = collections.OrderedDict( [ ( - "int_ip", + "internal", _get_regex( r"(?P.+)" r"_(?P\d+)" @@ -278,27 +278,14 @@ class ContrailV2InstanceIpProcessor(ContrailV2NetworkFlavorBaseProcessor): r"_(?P.+)" r"_vmi" r"_(?P\d+)" + r"(_v6)?" r"_IP" r"_(?P\d+)" r"$" ), ), ( - "int_v6_ip", - _get_regex( - r"(?P.+)" - r"_(?P\d+)" - r"_int" - r"_(?P.+)" - r"_vmi" - r"_(?P\d+)" - r"_v6_IP" - r"_(?P\d+)" - r"$" - ), - ), - ( - "subint_ip", + "subinterface", _get_regex( r"(?P.+)" r"_(?P\d+)" @@ -306,51 +293,26 @@ class ContrailV2InstanceIpProcessor(ContrailV2NetworkFlavorBaseProcessor): r"_(?P.+)" r"_vmi" r"_(?P\d+)" + r"(_v6)?" r"_IP" r"_(?P\d+)" r"$" ), ), ( - "subint_v6_ip", - _get_regex( - r"(?P.+)" - r"_(?P\d+)" - r"_subint" - r"_(?P.+)" - r"_vmi" - r"_(?P\d+)" - r"_v6_IP" - r"_(?P\d+)" - r"$" - ), - ), - ( - "ip", + "external", _get_regex( r"(?P.+)" r"_(?P\d+)" r"_(?P.+)" r"_vmi" r"_(?P\d+)" + r"(_v6)?" r"_IP" r"_(?P\d+)" r"$" ), ), - ( - "v6_ip", - _get_regex( - r"(?P.+)" - r"_(?P\d+)" - r"_(?P.+)" - r"_vmi" - r"_(?P\d+)" - r"_v6_IP" - r"_(?P\d+)" - r"$" - ), - ), ] ) @@ -412,7 +374,7 @@ class ContrailV2VirtualMachineInterfaceProcessor(ContrailV2NetworkFlavorBaseProc re_rids = collections.OrderedDict( [ ( - "vmi_internal", + "internal", _get_regex( r"(?P.+)" r"_(?P\d+)" @@ -424,7 +386,7 @@ class ContrailV2VirtualMachineInterfaceProcessor(ContrailV2NetworkFlavorBaseProc ), ), ( - "vmi_subint", + "subinterface", _get_regex( r"(?P.+)" r"_(?P\d+)" @@ -436,7 +398,7 @@ class ContrailV2VirtualMachineInterfaceProcessor(ContrailV2NetworkFlavorBaseProc ), ), ( - "vmi_external", + "external", _get_regex( r"(?P.+)" r"_(?P\d+)" @@ -504,7 +466,7 @@ class NeutronPortProcessor(HeatProcessor): re_rids = collections.OrderedDict( [ ( - "internal_port", + "internal", _get_regex( r"(?P.+)" r"_(?P\d+)" @@ -515,7 +477,7 @@ class NeutronPortProcessor(HeatProcessor): ), ), ( - "port", + "external", _get_regex( r"(?P.+)" r"_(?P\d+)" @@ -524,26 +486,6 @@ class NeutronPortProcessor(HeatProcessor): r"$" ), ), - ( - "floating_ip", - _get_regex( - r"reserve_port" - r"_(?P.+)" - r"_(?P.+)" - r"_floating_ip_(?P\d+)" - r"$" - ), - ), - ( - "floating_v6_ip", - _get_regex( - r"reserve_port" - r"_(?P.+)" - r"_(?P.+)" - r"_floating_v6_ip_(?P\d+)" - r"$" - ), - ), ] ) diff --git a/ice_validator/tests/test_allowed_address_pairs_include_vm_type_network_role.py b/ice_validator/tests/test_allowed_address_pairs_include_vm_type_network_role.py index 4654333..76e5f18 100644 --- a/ice_validator/tests/test_allowed_address_pairs_include_vm_type_network_role.py +++ b/ice_validator/tests/test_allowed_address_pairs_include_vm_type_network_role.py @@ -39,7 +39,8 @@ import re from .helpers import validates -from .utils.ports import check_ip_format +from .utils.ports import check_parameter_format +from tests.structures import NeutronPortProcessor VERSION = "1.0.0" @@ -80,13 +81,13 @@ aap_regx_dict = { @validates("R-41492", "R-35735", "R-159016") def test_external_aap_format(yaml_file): - check_ip_format( - yaml_file, aap_regx_dict, "external", "allowed_address_pairs", "ip_address" + check_parameter_format( + yaml_file, aap_regx_dict, "external", NeutronPortProcessor, "allowed_address_pairs", "ip_address" ) @validates("R-717227", "R-805572") def test_internal_aap_format(yaml_file): - check_ip_format( - yaml_file, aap_regx_dict, "internal", "allowed_address_pairs", "ip_address" + check_parameter_format( + yaml_file, aap_regx_dict, "internal", NeutronPortProcessor, "allowed_address_pairs", "ip_address" ) diff --git a/ice_validator/tests/test_contrail_instance_ip_parameters.py b/ice_validator/tests/test_contrail_instance_ip_parameters.py new file mode 100644 index 0000000..a708a58 --- /dev/null +++ b/ice_validator/tests/test_contrail_instance_ip_parameters.py @@ -0,0 +1,133 @@ +# -*- coding: utf8 -*- +# ============LICENSE_START==================================================== +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2019 AT&T Intellectual Property. All rights reserved. +# =================================================================== +# +# Unless otherwise specified, all software contained herein is licensed +# under the Apache License, Version 2.0 (the "License"); +# you may not use this software except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# +# Unless otherwise specified, all documentation contained herein is licensed +# under the Creative Commons License, Attribution 4.0 Intl. (the "License"); +# you may not use this documentation except in compliance with the License. +# You may obtain a copy of the License at +# +# https://creativecommons.org/licenses/by/4.0/ +# +# Unless required by applicable law or agreed to in writing, documentation +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ============LICENSE_END============================================ +# +# +import re + +from tests.structures import ContrailV2InstanceIpProcessor +from tests.helpers import validates +from tests.utils.ports import check_parameter_format + +RE_EXTERNAL_PARAM_IIP = re.compile( # match pattern + r"(?P.+)_(?P.+?)(_v6)?_ip_(?P.+)$" +) + +RE_EXTERNAL_PARAM_IIPS = re.compile( # match pattern + r"(?P.+)_(?P.+?)(_v6)?_ips$" +) + +RE_INTERNAL_PARAM_IIP = re.compile( # match pattern + r"(?P.+)_int_(?P.+?)(_v6)?_ip_(?P.+)$" +) + +RE_INTERNAL_PARAM_IIPS = re.compile( # match pattern + r"(?P.+)_int_(?P.+?)(_v6)?_ips$" +) + +iip_regx_dict = { + "external": { + "string": { + "readable": "{vm-type}_{network-role}_ip_{ip-index} or {vm-type}_{network-role}_v6_ip_{ip-index}", + "machine": RE_EXTERNAL_PARAM_IIP, + }, + "comma_delimited_list": { + "readable": "{vm-type}_{network-role}_ips or {vm-type}_{network-role}_v6_ips", + "machine": RE_EXTERNAL_PARAM_IIPS, + }, + }, + "internal": { + "string": { + "readable": "{vm-type}_int_{network-role}_ip_{ip-index} or {vm-type}_int_{network-role}_v6_ip_{ip-index}", + "machine": RE_INTERNAL_PARAM_IIP, + }, + "comma_delimited_list": { + "readable": "{vm-type}_int_{network-role}_ips or {vm-type}_int_{network-role}_v6_ips", + "machine": RE_INTERNAL_PARAM_IIPS, + }, + }, + "parameter_to_resource_comparisons": ["vm_type", "network_role"], +} + + +RE_EXTERNAL_PARAM_SID = re.compile( # match pattern + r"(?P.+?)(_v6)?_subnet_id$" +) + +RE_INTERNAL_PARAM_SID = re.compile( # match pattern + r"int_(?P.+?)(_v6)?_subnet_id$" +) + +sid_regx_dict = { + "external": { + "string": { + "readable": "{network-role}_subnet_id or {network-role}_v6_subnet_id", + "machine": RE_EXTERNAL_PARAM_SID, + }, + }, + "internal": { + "string": { + "readable": "int_{network-role}_subnet_id or int_{network-role}_v6_subnet_id", + "machine": RE_INTERNAL_PARAM_SID, + }, + }, + "parameter_to_resource_comparisons": ["network_role"], +} + + +@validates("R-100000", "R-100010", "R-100030", "R-100150", "R-100070") +def test_contrail_external_instance_ip_address_parameter(yaml_file): + check_parameter_format(yaml_file, iip_regx_dict, "external", ContrailV2InstanceIpProcessor, "instance_ip_address") + + +@validates("R-100000", "R-100090", "R-100110", "R-100130", "R-100180") +def test_contrail_internal_instance_ip_address_parameter(yaml_file): + check_parameter_format(yaml_file, iip_regx_dict, "internal", ContrailV2InstanceIpProcessor, "instance_ip_address") + + +@validates("R-100190", "R-100200", "R-100220") +def test_contrail_external_instance_subnet_id_parameter(yaml_file): + check_parameter_format(yaml_file, sid_regx_dict, "external", ContrailV2InstanceIpProcessor, "subnet_uuid") + + +@validates("R-100190", "R-100240", "R-100260") +def test_contrail_internal_instance_subnet_id_parameter(yaml_file): + check_parameter_format(yaml_file, sid_regx_dict, "internal", ContrailV2InstanceIpProcessor, "subnet_uuid") + + + + + diff --git a/ice_validator/tests/test_contrail_instance_ip_resource_id.py b/ice_validator/tests/test_contrail_instance_ip_resource_id.py index 5e80075..2833d5b 100644 --- a/ice_validator/tests/test_contrail_instance_ip_resource_id.py +++ b/ice_validator/tests/test_contrail_instance_ip_resource_id.py @@ -36,10 +36,6 @@ # ============LICENSE_END============================================ # # -""" -resources: -{vm-type}_server_{vm-type_index} -""" import pytest from .structures import Heat @@ -64,8 +60,9 @@ def run_test(heat_template, regex_names, network_flavor): flavor = processor.get_network_flavor(resource) if flavor != network_flavor: continue + regex_name = processor.get_rid_match_tuple(rid)[0] - if regex_name in regex_names: + if regex_name and regex_name in regex_names: continue bad.append(rid) assert not bad, "%s resource ids %s must match one of %s" % ( @@ -101,7 +98,7 @@ def test_contrail_instance_ip_resource_id_external(yaml_file): run_test( yaml_file, - regex_names=("ip", "v6_ip"), + regex_names=("external"), network_flavor=ContrailV2InstanceIpProcessor.network_flavor_external, ) @@ -117,6 +114,6 @@ def test_contrail_instance_ip_resource_id_internal(yaml_file): """ run_test( yaml_file, - regex_names=("int_ip", "int_v6_ip"), + regex_names=("internal"), network_flavor=ContrailV2InstanceIpProcessor.network_flavor_internal, ) diff --git a/ice_validator/tests/test_contrail_vmi_parameters.py b/ice_validator/tests/test_contrail_vmi_parameters.py new file mode 100644 index 0000000..311e352 --- /dev/null +++ b/ice_validator/tests/test_contrail_vmi_parameters.py @@ -0,0 +1,99 @@ +# -*- coding: utf8 -*- +# ============LICENSE_START==================================================== +# org.onap.vvp/validation-scripts +# =================================================================== +# Copyright © 2019 AT&T Intellectual Property. All rights reserved. +# =================================================================== +# +# Unless otherwise specified, all software contained herein is licensed +# under the Apache License, Version 2.0 (the "License"); +# you may not use this software except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# +# +# Unless otherwise specified, all documentation contained herein is licensed +# under the Creative Commons License, Attribution 4.0 Intl. (the "License"); +# you may not use this documentation except in compliance with the License. +# You may obtain a copy of the License at +# +# https://creativecommons.org/licenses/by/4.0/ +# +# Unless required by applicable law or agreed to in writing, documentation +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# ============LICENSE_END============================================ +# +# +import re + +from tests.structures import ContrailV2VirtualMachineInterfaceProcessor +from tests.helpers import validates +from tests.utils.ports import check_parameter_format + +RE_EXTERNAL_PARAM_AAP = re.compile( # match pattern + r"(?P.+)_(?P.+)_floating(_v6)?_ip$" +) + +RE_INTERNAL_PARAM_AAP = re.compile( # match pattern + r"(?P.+)_int_(?P.+)_floating(_v6)?_ip$" +) + +RE_INTERNAL_PARAM_AAPS = re.compile( # match pattern + r"(?P.+)_int_(?P.+)_floating(_v6)?_ips$" +) + +aap_regx_dict = { + "external": { + "string": { + "readable": "{vm-type}_{network-role}_floating_ip or {vm-type}_{network-role}_floating_v6_ip", + "machine": RE_EXTERNAL_PARAM_AAP, + } + }, + "internal": { + "string": { + "readable": "{vm-type}_int_{network-role}_floating_ip or {vm-type}_int_{network-role}_floating_v6_ip", + "machine": RE_INTERNAL_PARAM_AAP, + }, + "comma_delimited_list": { + "readable": "{vm-type}_int_{network-role}_floating_ips or {vm-type}_int_{network-role}_floating_v6_ips", + "machine": RE_INTERNAL_PARAM_AAPS, + }, + }, + "parameter_to_resource_comparisons": ["vm_type", "network_role"], +} + + +@validates("R-100310", "R-100330", "R-100350") +def test_contrail_external_vmi_aap_parameter(yaml_file): + check_parameter_format(yaml_file, + aap_regx_dict, + "external", + ContrailV2VirtualMachineInterfaceProcessor, + "virtual_machine_interface_allowed_address_pairs", + "virtual_machine_interface_allowed_address_pairs_allowed_address_pair", + "virtual_machine_interface_allowed_address_pairs_allowed_address_pair_ip", + "virtual_machine_interface_allowed_address_pairs_allowed_address_pair_ip_ip_prefix") + + +@validates("R-100360", "R-100370") +def test_contrail_internal_vmi_aap_parameter(yaml_file): + check_parameter_format(yaml_file, + aap_regx_dict, + "internal", + ContrailV2VirtualMachineInterfaceProcessor, + "virtual_machine_interface_allowed_address_pairs", + "virtual_machine_interface_allowed_address_pairs_allowed_address_pair", + "virtual_machine_interface_allowed_address_pairs_allowed_address_pair_ip", + "virtual_machine_interface_allowed_address_pairs_allowed_address_pair_ip_ip_prefix") diff --git a/ice_validator/tests/test_contrail_vmi_resource_id.py b/ice_validator/tests/test_contrail_vmi_resource_id.py index 9cabfb4..ed8f87d 100644 --- a/ice_validator/tests/test_contrail_vmi_resource_id.py +++ b/ice_validator/tests/test_contrail_vmi_resource_id.py @@ -92,7 +92,7 @@ def test_contrail_instance_ip_resource_id_external(yaml_file): """ run_test( yaml_file, - regex_name="vmi_external", + regex_name="external", network_flavor=ContrailV2VirtualMachineInterfaceProcessor.network_flavor_external, ) @@ -109,6 +109,6 @@ def test_contrail_instance_ip_resource_id_internal(yaml_file): """ run_test( yaml_file, - regex_name="vmi_internal", + regex_name="internal", network_flavor=ContrailV2VirtualMachineInterfaceProcessor.network_flavor_internal, ) diff --git a/ice_validator/tests/test_fixed_ips_include_vm_type_network_role.py b/ice_validator/tests/test_fixed_ips_include_vm_type_network_role.py index 4c62528..2ce1bcf 100644 --- a/ice_validator/tests/test_fixed_ips_include_vm_type_network_role.py +++ b/ice_validator/tests/test_fixed_ips_include_vm_type_network_role.py @@ -40,7 +40,8 @@ import re from .helpers import validates -from .utils.ports import check_ip_format +from .utils.ports import check_parameter_format +from tests.structures import NeutronPortProcessor RE_EXTERNAL_PARAM_FIP = re.compile( # match pattern @@ -86,9 +87,9 @@ fip_regx_dict = { @validates("R-40971", "R-35735", "R-23503", "R-71577", "R-04697", "R-34037") def test_external_fip_format(yaml_file): - check_ip_format(yaml_file, fip_regx_dict, "external", "fixed_ips", "ip_address") + check_parameter_format(yaml_file, fip_regx_dict, "external", NeutronPortProcessor, "fixed_ips", "ip_address") @validates("R-27818", "R-29765", "R-85235", "R-78380", "R-34037") def test_internal_fip_format(yaml_file): - check_ip_format(yaml_file, fip_regx_dict, "internal", "fixed_ips", "ip_address") + check_parameter_format(yaml_file, fip_regx_dict, "internal", NeutronPortProcessor, "fixed_ips", "ip_address") diff --git a/ice_validator/tests/test_nested_parameters.py b/ice_validator/tests/test_nested_parameters.py index 846a977..47c4d90 100644 --- a/ice_validator/tests/test_nested_parameters.py +++ b/ice_validator/tests/test_nested_parameters.py @@ -90,7 +90,8 @@ def check_nested_parameter_doesnt_change(yaml_file, nresource_type, *nprops): continue for nparam in prop_iterator(nresource_dict, *nprops): # get iterator of all target parameters - if nparam: # iterator yields None if parameter isn't found + if nparam and "get_param" in nparam: # iterator yields None if parameter isn't found + nparam = nparam.get("get_param") for k1, v1 in properties.items(): # found nparam, now comparing to parent template if isinstance(v1, dict) and "get_param" in v1: parameter = v1.get("get_param") diff --git a/ice_validator/tests/test_neutron_port_fixed_ips_subnet.py b/ice_validator/tests/test_neutron_port_fixed_ips_subnet.py index 1df7aac..a07225b 100644 --- a/ice_validator/tests/test_neutron_port_fixed_ips_subnet.py +++ b/ice_validator/tests/test_neutron_port_fixed_ips_subnet.py @@ -36,31 +36,6 @@ # ============LICENSE_END============================================ # # - -""" -resources: -{vm-type}_{vm-type_index}_{network-role}_port_{port-index}: - type: OS::Neutron::Port - properties: - network: { get_param: ...} - fixed_ips: [ { "ipaddress": { get_param: ... } } ] - binding:vnic_type: direct #only SR-IOV ports, not OVS ports - value_specs: { - vlan_filter: { get_param: ... }, #all NC ports - public_vlans: { get_param: ... }, #all NC ports - private_vlans: { get_param: ... },#all NC ports - guest_vlans: { get_param: ... }, #SR-IOV Trunk Port only - vlan_mirror: { get_param: ... }, #SRIOV Trunk Port - # Receiving Mirrored Traffic only - ATT_FABRIC_CONFIGURATION_REQUIRED: true #all NC ports - } - metadata: - port_type: SR-IOV_Trunk #SR-IOV Trunk Port - port_type: SR-IOV_Non_Trunk #SR-IOV Non Trunk Port - port_type: OVS #OVS Port - port_type: SR-IOV_Mirrored_Trunk #SR-IOV Trunk Port - # Receiving Mirrored Traffic -""" import re from tests.utils.network_roles import get_network_type_from_port @@ -68,7 +43,8 @@ from tests.parametrizers import get_nested_files from .structures import Heat from .helpers import validates, load_yaml, get_base_template_from_yaml_files -from .utils.ports import check_ip_format +from .utils.ports import check_parameter_format +from tests.structures import NeutronPortProcessor VERSION = "1.3.0" @@ -99,12 +75,12 @@ fip_regx_dict = { @validates("R-38236", "R-84123", "R-76160") def test_internal_subnet_format(yaml_file): - check_ip_format(yaml_file, fip_regx_dict, "internal", "fixed_ips", "subnet") + check_parameter_format(yaml_file, fip_regx_dict, "internal", NeutronPortProcessor, "fixed_ips", "subnet") @validates("R-38236", "R-62802", "R-15287") def test_external_subnet_format(yaml_file): - check_ip_format(yaml_file, fip_regx_dict, "external", "fixed_ips", "subnet") + check_parameter_format(yaml_file, fip_regx_dict, "external", NeutronPortProcessor, "fixed_ips", "subnet") @validates("R-84123", "R-76160") diff --git a/ice_validator/tests/utils/ports.py b/ice_validator/tests/utils/ports.py index c005e32..afce592 100644 --- a/ice_validator/tests/utils/ports.py +++ b/ice_validator/tests/utils/ports.py @@ -36,120 +36,114 @@ # ============LICENSE_END============================================ # # -from .network_roles import get_network_role_and_type -from tests.structures import Heat, NeutronPortProcessor -from tests.helpers import parameter_type_to_heat_type +from tests.structures import Heat +from tests.helpers import parameter_type_to_heat_type, prop_iterator from . import nested_dict -def check_ip_format(yaml_file, regx, port_type, resource_property, nested_property): +def check_parameter_format(yaml_file, regx, intext, resource_processor, *properties): """ yaml_file: input file to check regx: dictionary containing the regex to use to validate parameter - port_type: internal or external - resource_property: OS::Neutron::Port property to check for parameter - nested_property: resource_property will be a list of dicts, this is the key to index into + intext: internal or external + resource_processor: resource type specific helper, defined in structures.py + properties: arg list of property that is being checked """ - invalid_ips = [] + + invalid_parameters = [] heat = Heat(filepath=yaml_file) - ports = heat.get_resource_by_type("OS::Neutron::Port") + resource_type = resource_processor.resource_type + resources = heat.get_resource_by_type(resource_type) heat_parameters = heat.parameters - - for rid, resource in ports.items(): - network_role, network_type = get_network_role_and_type(resource) - if ( - network_type != port_type - ): # skipping if port type (internal/external) doesn't match - continue - - name, port_match = NeutronPortProcessor.get_rid_match_tuple(rid) + for rid, resource in resources.items(): + resource_intext, port_match = resource_processor.get_rid_match_tuple(rid) if not port_match: continue # port resource ID not formatted correctely - params = nested_dict.get(resource, "properties", resource_property, default={}) + if ( + resource_intext != intext + ): # skipping if type (internal/external) doesn't match + continue - for param in params: - prop = nested_dict.get(param, nested_property) + for param in prop_iterator(resource, *properties): if ( - not prop - or not isinstance(prop, dict) - or "get_resource" in prop - or "get_attr" in prop - # or "str_replace" in prop - should str_replace be checked? + param + and isinstance(param, dict) + and "get_resource" not in param + and "get_attr" not in param ): - continue # lets only check parameters shall we? - - # checking parameter uses get_param - parameter = nested_dict.get(prop, "get_param") - if not parameter: - msg = ( - "Unexpected parameter format for OS::Neutron::Port {} property {}: {}. " - + "Please consult the heat guidelines documentation for details." - ).format(rid, resource_property, prop) - invalid_ips.append(msg) # should this be a failure? - continue - - # getting parameter if the get_param uses list, and getting official HEAT parameter type - parameter_type = parameter_type_to_heat_type(parameter) - if parameter_type == "comma_delimited_list": - parameter = parameter[0] - elif parameter_type != "string": - continue - - # checking parameter format = type defined in template - heat_parameter_type = nested_dict.get(heat_parameters, parameter, "type") - if not heat_parameter_type or heat_parameter_type != parameter_type: - msg = ( - "OS::Neutron::Port {} parameter {} defined as type {} " - + "is being used as type {} in the heat template" - ).format( - resource_property, parameter, heat_parameter_type, parameter_type - ) - invalid_ips.append(msg) - continue - - # if parameter type is not in regx dict, then it is not supported by automation - regx_dict = regx[port_type].get(parameter_type) - if not regx_dict: - msg = ( - "WARNING: OS::Neutron::Port {} parameter {} defined as type {} " - + "is not supported by platform automation. If this VNF is not able " - + "to adhere to this requirement, please consult the Heat Orchestration " - + "Template guidelines for alternative solutions. If already adhering to " - + "an alternative provided by the heat guidelines, please disregard this " - + "message." - ).format(resource_property, parameter, parameter_type) - invalid_ips.append(msg) - continue - - # checking if param adheres to guidelines format - regexp = regx[port_type][parameter_type]["machine"] - readable_format = regx[port_type][parameter_type]["readable"] - match = regexp.match(parameter) - if not match: - msg = "{} parameter {} does not follow format {}".format( - resource_property, parameter, readable_format - ) - invalid_ips.append(msg) - continue - - # checking that parameter includes correct vm_type/network_role - parameter_checks = regx.get("parameter_to_resource_comparisons", []) - for check in parameter_checks: - resource_match = port_match.group(check) - if ( - resource_match - and not parameter.startswith(resource_match) - and parameter.find("_{}_".format(resource_match)) == -1 - ): + + # checking parameter uses get_param + parameter = param.get("get_param") + if not parameter: + msg = ( + "Unexpected parameter format for {} {} property {}: {}. " + + "Please consult the heat guidelines documentation for details." + ).format(resource_type, rid, properties, param) + invalid_parameters.append(msg) # should this be a failure? + continue + + # getting parameter if the get_param uses list, and getting official HEAT parameter type + parameter_type = parameter_type_to_heat_type(parameter) + if parameter_type == "comma_delimited_list": + parameter = parameter[0] + elif parameter_type != "string": + continue + + # checking parameter format = parameter type defined in parameters section + heat_parameter_type = nested_dict.get(heat_parameters, parameter, "type") + if not heat_parameter_type or heat_parameter_type != parameter_type: msg = ( - "OS::Neutron::Port {0} property {1} parameter " - + "{2} {3} does match resource {3} {4}" - ).format(rid, resource_property, parameter, check, resource_match) - invalid_ips.append(msg) + "{} {} parameter {} defined as type {} " + + "is being used as type {} in the heat template" + ).format( + resource_type, properties, parameter, heat_parameter_type, parameter_type + ) + invalid_parameters.append(msg) # should this actually be an error? + continue + + # if parameter type is not in regx dict, then it is not supported by automation + regx_dict = regx[resource_intext].get(parameter_type) + if not regx_dict: + msg = ( + "WARNING: {} {} parameter {} defined as type {} " + "is not supported by platform automation. If this VNF is not able " + "to adhere to this requirement, please consult the Heat Orchestration " + "Template guidelines for alternative solutions. If already adhering to " + "an alternative provided by the heat guidelines, please disregard this " + "message." + ).format(resource_type, properties, parameter, parameter_type) + invalid_parameters.append(msg) + continue + + # checking if param adheres to guidelines format + regexp = regx[resource_intext][parameter_type]["machine"] + readable_format = regx[resource_intext][parameter_type]["readable"] + match = regexp.match(parameter) + if not match: + msg = "{} {} property {} parameter {} does not follow {} format {}".format( + resource_type, rid, properties, parameter, resource_intext, readable_format + ) + invalid_parameters.append(msg) continue - assert not invalid_ips, "%s" % "\n".join(invalid_ips) + # checking that parameter includes correct vm_type/network_role + parameter_checks = regx.get("parameter_to_resource_comparisons", []) + for check in parameter_checks: + resource_match = port_match.group(check) + if ( + resource_match + and not parameter.startswith(resource_match) + and parameter.find("_{}_".format(resource_match)) == -1 + ): + msg = ( + "{0} {1} property {2} parameter " + "{3} {4} does match resource {4} {5}" + ).format(resource_type, rid, properties, parameter, check, resource_match) + invalid_parameters.append(msg) + continue + + assert not invalid_parameters, "%s" % "\n".join(invalid_parameters) def get_list_of_ports_attached_to_nova_server(nova_server): -- 2.16.6