[VVP] Adding tests for new reqs from VNFRQTS-630 98/87598/1
authorstark, steven <steven.stark@att.com>
Mon, 13 May 2019 21:41:55 +0000 (14:41 -0700)
committerstark, steven <steven.stark@att.com>
Mon, 13 May 2019 21:41:55 +0000 (14:41 -0700)
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 <steven.stark@att.com>
18 files changed:
ice_validator/tests/fixtures/test_contrail_instance_ip_parameters/fail/fail.yaml [new file with mode: 0644]
ice_validator/tests/fixtures/test_contrail_instance_ip_parameters/pass/pass.yaml [new file with mode: 0644]
ice_validator/tests/fixtures/test_contrail_instance_ip_resource_id/fail/fail0.yaml
ice_validator/tests/fixtures/test_contrail_vmi_parameters/fail/fail.yaml [new file with mode: 0644]
ice_validator/tests/fixtures/test_contrail_vmi_parameters/pass/pass.yaml [new file with mode: 0644]
ice_validator/tests/fixtures/test_neutron_port_fixed_ips_subnet/fail/fail0.yaml
ice_validator/tests/fixtures/test_neutron_port_fixed_ips_subnet/fail/fail1.yaml
ice_validator/tests/helpers.py
ice_validator/tests/structures.py
ice_validator/tests/test_allowed_address_pairs_include_vm_type_network_role.py
ice_validator/tests/test_contrail_instance_ip_parameters.py [new file with mode: 0644]
ice_validator/tests/test_contrail_instance_ip_resource_id.py
ice_validator/tests/test_contrail_vmi_parameters.py [new file with mode: 0644]
ice_validator/tests/test_contrail_vmi_resource_id.py
ice_validator/tests/test_fixed_ips_include_vm_type_network_role.py
ice_validator/tests/test_nested_parameters.py
ice_validator/tests/test_neutron_port_fixed_ips_subnet.py
ice_validator/tests/utils/ports.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 (file)
index 0000000..d7770d7
--- /dev/null
@@ -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 (file)
index 0000000..8645348
--- /dev/null
@@ -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
index a5f5e16..92bdb35 100644 (file)
@@ -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 (file)
index 0000000..248f9ec
--- /dev/null
@@ -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 (file)
index 0000000..df4ca00
--- /dev/null
@@ -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
index 901072f..de509a2 100644 (file)
@@ -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
+
index 60f9874..9233707 100644 (file)
@@ -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}
index afa8672..c73a118 100644 (file)
@@ -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)
index a6b2015..8abe87b 100644 (file)
@@ -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<vm_type>.+)"
                     r"_(?P<vm_type_index>\d+)"
@@ -278,27 +278,14 @@ class ContrailV2InstanceIpProcessor(ContrailV2NetworkFlavorBaseProcessor):
                     r"_(?P<network_role>.+)"
                     r"_vmi"
                     r"_(?P<vmi_index>\d+)"
+                    r"(_v6)?"
                     r"_IP"
                     r"_(?P<index>\d+)"
                     r"$"
                 ),
             ),
             (
-                "int_v6_ip",
-                _get_regex(
-                    r"(?P<vm_type>.+)"
-                    r"_(?P<vm_type_index>\d+)"
-                    r"_int"
-                    r"_(?P<network_role>.+)"
-                    r"_vmi"
-                    r"_(?P<vmi_index>\d+)"
-                    r"_v6_IP"
-                    r"_(?P<index>\d+)"
-                    r"$"
-                ),
-            ),
-            (
-                "subint_ip",
+                "subinterface",
                 _get_regex(
                     r"(?P<vm_type>.+)"
                     r"_(?P<vm_type_index>\d+)"
@@ -306,51 +293,26 @@ class ContrailV2InstanceIpProcessor(ContrailV2NetworkFlavorBaseProcessor):
                     r"_(?P<network_role>.+)"
                     r"_vmi"
                     r"_(?P<vmi_index>\d+)"
+                    r"(_v6)?"
                     r"_IP"
                     r"_(?P<index>\d+)"
                     r"$"
                 ),
             ),
             (
-                "subint_v6_ip",
-                _get_regex(
-                    r"(?P<vm_type>.+)"
-                    r"_(?P<vm_type_index>\d+)"
-                    r"_subint"
-                    r"_(?P<network_role>.+)"
-                    r"_vmi"
-                    r"_(?P<vmi_index>\d+)"
-                    r"_v6_IP"
-                    r"_(?P<index>\d+)"
-                    r"$"
-                ),
-            ),
-            (
-                "ip",
+                "external",
                 _get_regex(
                     r"(?P<vm_type>.+)"
                     r"_(?P<vm_type_index>\d+)"
                     r"_(?P<network_role>.+)"
                     r"_vmi"
                     r"_(?P<vmi_index>\d+)"
+                    r"(_v6)?"
                     r"_IP"
                     r"_(?P<index>\d+)"
                     r"$"
                 ),
             ),
-            (
-                "v6_ip",
-                _get_regex(
-                    r"(?P<vm_type>.+)"
-                    r"_(?P<vm_type_index>\d+)"
-                    r"_(?P<network_role>.+)"
-                    r"_vmi"
-                    r"_(?P<vmi_index>\d+)"
-                    r"_v6_IP"
-                    r"_(?P<index>\d+)"
-                    r"$"
-                ),
-            ),
         ]
     )
 
@@ -412,7 +374,7 @@ class ContrailV2VirtualMachineInterfaceProcessor(ContrailV2NetworkFlavorBaseProc
     re_rids = collections.OrderedDict(
         [
             (
-                "vmi_internal",
+                "internal",
                 _get_regex(
                     r"(?P<vm_type>.+)"
                     r"_(?P<vm_type_index>\d+)"
@@ -424,7 +386,7 @@ class ContrailV2VirtualMachineInterfaceProcessor(ContrailV2NetworkFlavorBaseProc
                 ),
             ),
             (
-                "vmi_subint",
+                "subinterface",
                 _get_regex(
                     r"(?P<vm_type>.+)"
                     r"_(?P<vm_type_index>\d+)"
@@ -436,7 +398,7 @@ class ContrailV2VirtualMachineInterfaceProcessor(ContrailV2NetworkFlavorBaseProc
                 ),
             ),
             (
-                "vmi_external",
+                "external",
                 _get_regex(
                     r"(?P<vm_type>.+)"
                     r"_(?P<vm_type_index>\d+)"
@@ -504,7 +466,7 @@ class NeutronPortProcessor(HeatProcessor):
     re_rids = collections.OrderedDict(
         [
             (
-                "internal_port",
+                "internal",
                 _get_regex(
                     r"(?P<vm_type>.+)"
                     r"_(?P<vm_type_index>\d+)"
@@ -515,7 +477,7 @@ class NeutronPortProcessor(HeatProcessor):
                 ),
             ),
             (
-                "port",
+                "external",
                 _get_regex(
                     r"(?P<vm_type>.+)"
                     r"_(?P<vm_type_index>\d+)"
@@ -524,26 +486,6 @@ class NeutronPortProcessor(HeatProcessor):
                     r"$"
                 ),
             ),
-            (
-                "floating_ip",
-                _get_regex(
-                    r"reserve_port"
-                    r"_(?P<vm_type>.+)"
-                    r"_(?P<network_role>.+)"
-                    r"_floating_ip_(?P<index>\d+)"
-                    r"$"
-                ),
-            ),
-            (
-                "floating_v6_ip",
-                _get_regex(
-                    r"reserve_port"
-                    r"_(?P<vm_type>.+)"
-                    r"_(?P<network_role>.+)"
-                    r"_floating_v6_ip_(?P<index>\d+)"
-                    r"$"
-                ),
-            ),
         ]
     )
 
index 4654333..76e5f18 100644 (file)
@@ -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 (file)
index 0000000..a708a58
--- /dev/null
@@ -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<vm_type>.+)_(?P<network_role>.+?)(_v6)?_ip_(?P<ip_index>.+)$"
+)
+
+RE_EXTERNAL_PARAM_IIPS = re.compile(  # match pattern
+    r"(?P<vm_type>.+)_(?P<network_role>.+?)(_v6)?_ips$"
+)
+
+RE_INTERNAL_PARAM_IIP = re.compile(  # match pattern
+    r"(?P<vm_type>.+)_int_(?P<network_role>.+?)(_v6)?_ip_(?P<ip_index>.+)$"
+)
+
+RE_INTERNAL_PARAM_IIPS = re.compile(  # match pattern
+    r"(?P<vm_type>.+)_int_(?P<network_role>.+?)(_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<network_role>.+?)(_v6)?_subnet_id$"
+)
+
+RE_INTERNAL_PARAM_SID = re.compile(  # match pattern
+    r"int_(?P<network_role>.+?)(_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")
+
+
+
+
+
index 5e80075..2833d5b 100644 (file)
 # ============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 (file)
index 0000000..311e352
--- /dev/null
@@ -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<vm_type>.+)_(?P<network_role>.+)_floating(_v6)?_ip$"
+)
+
+RE_INTERNAL_PARAM_AAP = re.compile(  # match pattern
+    r"(?P<vm_type>.+)_int_(?P<network_role>.+)_floating(_v6)?_ip$"
+)
+
+RE_INTERNAL_PARAM_AAPS = re.compile(  # match pattern
+    r"(?P<vm_type>.+)_int_(?P<network_role>.+)_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")
index 9cabfb4..ed8f87d 100644 (file)
@@ -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,
     )
index 4c62528..2ce1bcf 100644 (file)
@@ -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")
index 846a977..47c4d90 100644 (file)
@@ -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")
index 1df7aac..a07225b 100644 (file)
 # ============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")
index c005e32..afce592 100644 (file)
 # ============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):