aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ice_validator/tests/fixtures/test_neutron_port_fixed_ips_subnet/fail/fail0.yaml (renamed from ice_validator/tests/fixtures/test_neutron_port_fixed_ips/fail/fail0.yaml)4
-rw-r--r--ice_validator/tests/fixtures/test_neutron_port_fixed_ips_subnet/fail/fail1.yaml (renamed from ice_validator/tests/fixtures/test_neutron_port_fixed_ips/fail/fail1.yaml)10
-rw-r--r--ice_validator/tests/fixtures/test_neutron_port_fixed_ips_subnet/pass/pass0.yaml (renamed from ice_validator/tests/fixtures/test_neutron_port_fixed_ips/pass/pass0.yaml)0
-rw-r--r--ice_validator/tests/fixtures/test_neutron_port_fixed_ips_subnet/pass/pass0_base.yaml (renamed from ice_validator/tests/fixtures/test_neutron_port_fixed_ips/pass/pass0_base.yaml)0
-rw-r--r--ice_validator/tests/helpers.py28
-rw-r--r--ice_validator/tests/test_neutron_port_fixed_ips_subnet.py (renamed from ice_validator/tests/test_neutron_port_fixed_ips.py)199
-rw-r--r--ice_validator/tests/test_neutron_port_internal_network.py49
7 files changed, 138 insertions, 152 deletions
diff --git a/ice_validator/tests/fixtures/test_neutron_port_fixed_ips/fail/fail0.yaml b/ice_validator/tests/fixtures/test_neutron_port_fixed_ips_subnet/fail/fail0.yaml
index 8ca5cec..901072f 100644
--- a/ice_validator/tests/fixtures/test_neutron_port_fixed_ips/fail/fail0.yaml
+++ b/ice_validator/tests/fixtures/test_neutron_port_fixed_ips_subnet/fail/fail0.yaml
@@ -50,7 +50,7 @@ parameters:
vm_typeX_bialy_guest_vlans:
type: comma_delimited_list
subnet_param:
- type: string
+ type: comma_delimited_list
subnet_id_param:
type: comma_delimited_list
@@ -63,7 +63,6 @@ resources:
fixed_ips:
- ip_address: { get_param: lb_1_int_intranet_floating_ip }
subnet: { get_param: subnet_param }
- subnet_id: { get_param: subnet_id_param }
binding:vnic_type: direct
value_specs:
vlan_filter: {get_param: vm_typeX_bialy_vlan_filter}
@@ -82,7 +81,6 @@ resources:
fixed_ips:
- ip_address: { get_param: lb_2_extnet_floating_v6_ip }
subnet: { get_param: subnet_param }
- subnet_id: { get_param: subnet_id_param }
binding:vnic_type: direct
value_specs:
vlan_filter: {get_param: vm_typeX_bialy_vlan_filter}
diff --git a/ice_validator/tests/fixtures/test_neutron_port_fixed_ips/fail/fail1.yaml b/ice_validator/tests/fixtures/test_neutron_port_fixed_ips_subnet/fail/fail1.yaml
index 58c75bb..60f9874 100644
--- a/ice_validator/tests/fixtures/test_neutron_port_fixed_ips/fail/fail1.yaml
+++ b/ice_validator/tests/fixtures/test_neutron_port_fixed_ips_subnet/fail/fail1.yaml
@@ -49,8 +49,8 @@ parameters:
type: comma_delimited_list
vm_typeX_bialy_guest_vlans:
type: comma_delimited_list
- bialy_subnet:
- type: string
+ bialy_susbnet:
+ type: comma_delimited_list
bialy_subnet_id:
type: string
@@ -62,8 +62,7 @@ resources:
network: { get_param: int_intranet_net_name }
fixed_ips:
- ip_address: { get_param: lb_1_int_intranet_floating_ip }
- subnet: { get_param: bialy_subnet }
- subnet_id: { get_param: bialy_subnet_id }
+ subnet: { get_param: bialy_susbnet }
binding:vnic_type: direct
value_specs:
vlan_filter: {get_param: vm_typeX_bialy_vlan_filter}
@@ -81,8 +80,7 @@ resources:
network: { get_param: extnet_net_id }
fixed_ips:
- ip_address: { get_param: lb_2_extnet_floating_v6_ip }
- subnet: { get_param: bialy_subnet }
- subnet_id: { get_param: bialy_subnet_id }
+ subnet: { get_param: bialy_susbnet }
binding:vnic_type: direct
value_specs:
vlan_filter: {get_param: vm_typeX_bialy_vlan_filter}
diff --git a/ice_validator/tests/fixtures/test_neutron_port_fixed_ips/pass/pass0.yaml b/ice_validator/tests/fixtures/test_neutron_port_fixed_ips_subnet/pass/pass0.yaml
index 2a651b1..2a651b1 100644
--- a/ice_validator/tests/fixtures/test_neutron_port_fixed_ips/pass/pass0.yaml
+++ b/ice_validator/tests/fixtures/test_neutron_port_fixed_ips_subnet/pass/pass0.yaml
diff --git a/ice_validator/tests/fixtures/test_neutron_port_fixed_ips/pass/pass0_base.yaml b/ice_validator/tests/fixtures/test_neutron_port_fixed_ips_subnet/pass/pass0_base.yaml
index 04919c3..04919c3 100644
--- a/ice_validator/tests/fixtures/test_neutron_port_fixed_ips/pass/pass0_base.yaml
+++ b/ice_validator/tests/fixtures/test_neutron_port_fixed_ips_subnet/pass/pass0_base.yaml
diff --git a/ice_validator/tests/helpers.py b/ice_validator/tests/helpers.py
index 69190d8..12a7a12 100644
--- a/ice_validator/tests/helpers.py
+++ b/ice_validator/tests/helpers.py
@@ -41,6 +41,7 @@
"""
import os
+import re
from collections import defaultdict
from boltons import funcutils
@@ -259,3 +260,30 @@ def check_indices(pattern, values, value_type):
).format(value_type, prefix, indices)
)
return invalid_params
+
+
+RE_BASE = re.compile(r"(^base$)|(^base_)|(_base_)|(_base$)")
+
+
+def get_base_template_from_yaml_files(yaml_files):
+ """Return first filepath to match RE_BASE
+ """
+ for filepath in yaml_files:
+ basename = get_base_template_from_yaml_file(filepath)
+ if basename:
+ return basename
+ return None
+
+
+def get_base_template_from_yaml_file(yaml_file):
+ (dirname, filename) = os.path.split(yaml_file)
+ files = os.listdir(dirname)
+ for file in files:
+ basename, __ = os.path.splitext(os.path.basename(file))
+ if (
+ (__ == ".yaml" or __ == ".yml")
+ and RE_BASE.search(basename)
+ and basename.find("volume") == -1
+ ):
+ return os.path.join(dirname, "{}{}".format(basename, __))
+ return None
diff --git a/ice_validator/tests/test_neutron_port_fixed_ips.py b/ice_validator/tests/test_neutron_port_fixed_ips_subnet.py
index 6e2d562..7b9bf3b 100644
--- a/ice_validator/tests/test_neutron_port_fixed_ips.py
+++ b/ice_validator/tests/test_neutron_port_fixed_ips_subnet.py
@@ -61,55 +61,40 @@ resources:
port_type: SR-IOV_Mirrored_Trunk #SR-IOV Trunk Port
# Receiving Mirrored Traffic
"""
-
-import os
-import os.path
import re
import pytest
from .structures import Heat
-from .helpers import validates
+from .helpers import validates, get_base_template_from_yaml_file
VERSION = "1.3.0"
RE_BASE = re.compile(r"(^base$)|(^base_)|(_base_)|(_base$)") # search pattern
-RE_EXTERNAL_PARAM_SUBNET_ID = re.compile( # match pattern
+RE_EXTERNAL_PARAM_SUBNET = re.compile( # match pattern
r"(?P<network_role>.+)(_v6)?_subnet_id$"
)
-RE_EXTERNAL_PARAM_SUBNET = RE_EXTERNAL_PARAM_SUBNET_ID
-# RE_EXTERNAL_PARAM_SUBNET = re.compile( # match pattern
-# r'(?P<network_role>.+)(_v6)?_subnet$')
-RE_INTERNAL_PARAM_SUBNET_ID = re.compile( # match pattern
+RE_INTERNAL_PARAM_SUBNET = re.compile( # match pattern
r"int_(?P<network_role>.+)(_v6)?_subnet_id$"
)
-RE_INTERNAL_PARAM_SUBNET = RE_INTERNAL_PARAM_SUBNET_ID
-# RE_INTERNAL_PARAM_SUBNET = re.compile( # match pattern
-# r'int_(?P<network_role>.+)(_v6)?_subnet$')
-def get_network(base_template_filepath):
+def get_base(base_template_filepath):
"""Return the base template's Heat instance.
"""
if base_template_filepath is None:
pytest.skip("No base template found")
base_template = Heat(filepath=base_template_filepath)
- for r in base_template.resources.values():
- if (
- base_template.nested_get(r, "type") == "OS::Neutron::Net"
- or base_template.nested_get(r, "type") == "OS::ContrailV2::VirtualNetwork"
- ):
- return base_template
- return None
+ return base_template
-def run_test(heat_template, validate):
+def run_test(heat_template, validate, validator=None):
"""call validate for each fixed_ips
"""
heat = Heat(filepath=heat_template)
- base_template = get_base_template(heat_template)
+ base_template = get_base_template_from_yaml_file(heat_template)
if not heat.resources:
pytest.skip("No resources found")
@@ -125,163 +110,109 @@ def run_test(heat_template, validate):
if not isinstance(fixed_ips, list):
bad[rid] = "properties.fixed_ips must be a list."
continue
- if not heat.parameters:
- bad[rid] = "fixed_ips requires parameters"
- continue
for fixed_ip in fixed_ips:
- error = validate(heat, fixed_ip, base_template)
+ error = validate(heat, fixed_ip, base_template, validator)
if error:
bad[rid] = error
break
if bad:
# raise RuntimeError(
raise AssertionError(
- "Bad OS::Neutron::Port: %s"
- % (", ".join("%s: %s" % (rid, error) for rid, error in bad.items()))
+ "%s"
+ % (", ".join("%s: %s" % (rid, error) for rid, error in bad.items()))
)
-def validate_external_fixed_ip(heat, fixed_ip, base_template):
- """ensure fixed_ip subnet and subnet_id for external network
+def validate_external_fixed_ip_subnet(heat, fixed_ip, base_template, validator):
+ """ensure fixed_ip subnet for external network
match the pattern.
Returns error message string or None.
"""
subnet = heat.nested_get(fixed_ip, "subnet", "get_param")
- subnet_id = heat.nested_get(fixed_ip, "subnet_id", "get_param")
- if subnet and subnet_id:
- error = 'fixed_ip %s has both "subnet" and "subnet_id"' % (fixed_ip)
- elif subnet:
- error = validate_external_subnet(subnet)
- elif subnet_id:
- error = validate_external_subnet_id(subnet_id)
+ if subnet:
+ error = validator(subnet, RE_EXTERNAL_PARAM_SUBNET)
else:
error = None
return error
-def validate_external_subnet(subnet):
+def validate_external_subnet_parameter_format(subnet, regx):
"""ensure subnet matches template.
Returns error message string or None.
"""
- if (
- subnet
- and not subnet.startswith("int_")
- and RE_EXTERNAL_PARAM_SUBNET.match(subnet) is None
- ):
- return 'fixed_ip subnet parameter "%s" does not match "%s"' % (
- subnet,
- RE_EXTERNAL_PARAM_SUBNET.pattern,
+ if subnet and not subnet.startswith("int_") and regx.match(subnet) is None:
+ return (
+ 'fixed_ip subnet parameter "%s" does not match '
+ "{network-role}_subnet_id or {network-role}_v6_subnet_id" % (subnet)
)
return None
-def validate_external_subnet_id(subnet_id):
- """ensure subnet_id matches template.
- Returns error message string or None.
- """
- if (
- subnet_id
- and not subnet_id.startswith("int_")
- and RE_EXTERNAL_PARAM_SUBNET_ID.match(subnet_id) is None
- ):
- return 'fixed_ip subnet_id parameter "%s" does not match "%s"' % (
- subnet_id,
- RE_EXTERNAL_PARAM_SUBNET_ID.pattern,
- )
- return None
-
-
-def validate_internal_fixed_ip(heat, fixed_ip, base_template):
- """ensure fixed_ip subnet and subnet_id for internal network
+def validate_internal_fixed_ip_subnet(heat, fixed_ip, base_template, validator):
+ """ensure fixed_ip subnet for internal network
match the pattern.
Returns error message string or None.
"""
- base_module = get_network(base_template)
+ base_module = get_base(base_template)
subnet = heat.nested_get(fixed_ip, "subnet", "get_param")
- subnet_id = heat.nested_get(fixed_ip, "subnet_id", "get_param")
- if subnet and subnet_id:
- error = 'fixed_ip %s has both "subnet" and "subnet_id"' % (fixed_ip)
- elif subnet:
- error = validate_internal_subnet(heat, base_module, subnet)
- elif subnet_id:
- error = validate_internal_subnet_id(heat, base_module, subnet_id)
+ if subnet:
+ error = validator(heat, base_module, subnet, RE_INTERNAL_PARAM_SUBNET)
else:
error = None
return error
-def validate_internal_subnet(heat, base_module, subnet):
+def validate_internal_subnet_parameter_format(heat, base_module, subnet, regx):
"""ensure if subnet matches template then its parameter exists.
Returns error message string or None.
"""
- if (
- subnet
- and subnet.startswith("int_")
- and RE_INTERNAL_PARAM_SUBNET.match(subnet)
- and heat.nested_get(base_module.outputs, subnet) is None
- ):
- return 'fixed_ip subnet parameter "%s" not in base outputs"' % (subnet)
+ if subnet and subnet.startswith("int_") and regx.match(subnet) is None:
+ return (
+ 'fixed_ip subnet parameter "%s" does not match '
+ "int_{network-role}_subnet_id or int_{network-role}_v6_subnet_id" % (subnet)
+ )
return None
-def validate_internal_subnet_id(heat, base_module, subnet_id):
- """ensure if subnet_id matches template then its parameter exists.
+def validate_internal_subnet_exists_in_base_output(heat, base_module, subnet, regx):
+ """ensure if subnet matches template then its parameter exists.
Returns error message string or None.
"""
if (
- subnet_id
- and subnet_id.startswith("int_")
- and RE_INTERNAL_PARAM_SUBNET_ID.match(subnet_id)
- and heat.nested_get(base_module.outputs, subnet_id) is None
+ subnet
+ and subnet.startswith("int_")
+ and regx.match(subnet)
+ and heat.nested_get(base_module.outputs, subnet) is None
):
- return 'fixed_ip subnet_id parameter "%s" not in base outputs"' % (subnet_id)
+ return 'fixed_ip subnet(_id) parameter "%s" not in base outputs"' % (subnet)
return None
-def validate_fixed_ip(heat, fixed_ip, base_template):
+def validate_fixed_ip_subnet(heat, fixed_ip, base_template, validator):
"""ensure fixed_ip has proper parameters
Returns error message string or None.
"""
subnet = heat.nested_get(fixed_ip, "subnet", "get_param")
- subnet_id = heat.nested_get(fixed_ip, "subnet_id", "get_param")
- if subnet and subnet_id:
- error = 'fixed_ip %s has both "subnet" and "subnet_id"' % (fixed_ip)
- elif subnet and heat.nested_get(heat.parameters, subnet, "type") != "string":
+ if subnet and heat.nested_get(heat.parameters, subnet, "type") != "string":
error = 'subnet parameter "%s" must be type "string"' % subnet
- elif subnet_id and heat.nested_get(heat.parameters, subnet_id, "type") != "string":
- error = 'subnet_id parameter "%s" must be type "string"' % subnet_id
else:
error = None
return error
-def get_base_template(heat_template):
- (dirname, filename) = os.path.split(heat_template)
- files = os.listdir(dirname)
- for file in files:
- basename, __ = os.path.splitext(os.path.basename(file))
- if (
- __ == ".yaml"
- and basename.find("base") != -1
- and basename.find("volume") == -1
- ):
- return os.path.join(dirname, "{}{}".format(basename, __))
- return None
-
-
@validates("R-38236")
-def test_neutron_port_fixed_ips(yaml_file):
+def test_neutron_port_fixed_ips_subnet(yaml_file):
"""
The VNF's Heat Orchestration Template's
resource ``OS::Neutron::Port`` property ``fixed_ips``
map property ``subnet``/``subnet_id`` parameter
**MUST** be declared type ``string``.
"""
- run_test(yaml_file, validate_fixed_ip)
+ run_test(yaml_file, validate_fixed_ip_subnet)
@validates("R-62802", "R-15287")
-def test_neutron_port_external_fixed_ips(yaml_file):
+def test_neutron_port_external_fixed_ips_subnet(yaml_file):
"""
When the VNF's Heat Orchestration Template's
resource ``OS::Neutron::Port`` is attaching
@@ -296,12 +227,46 @@ def test_neutron_port_external_fixed_ips(yaml_file):
and the external network IPv6 subnet is to be specified
* ``{network-role}_v6_subnet_id``
"""
- run_test(yaml_file, validate_external_fixed_ip)
+ run_test(
+ yaml_file,
+ validate_external_fixed_ip_subnet,
+ validate_external_subnet_parameter_format,
+ )
+
+
+@validates("R-84123", "R-76160")
+def test_neutron_port_internal_fixed_ips_subnet(yaml_file):
+ """
+ When
+
+ * the VNF's Heat Orchestration Template's
+ resource ``OS::Neutron::Port`` in an Incremental Module is attaching
+ to an internal network
+ that is created in the Base Module, AND
+ * an IPv4 address is being cloud assigned by OpenStack's DHCP Service AND
+ * the internal network IPv4 subnet is to be specified
+ using the property ``fixed_ips`` map property ``subnet``/``subnet_id``,
+
+ the parameter **MUST** follow the naming convention
+
+ * ``int_{network-role}_subnet_id``
+ an IPv6 address is being cloud assigned by OpenStack's DHCP Service AND
+ * ``int_{network-role}_v6_subnet_id``
+
+ """
+ run_test(
+ yaml_file,
+ validate_internal_fixed_ip_subnet,
+ validate_internal_subnet_parameter_format,
+ )
@validates("R-84123", "R-76160")
-def test_neutron_port_internal_fixed_ips(yaml_file):
+def test_neutron_port_internal_fixed_ips_subnet_in_base(heat_template):
"""
+ Only check parent incremental modules, because nested file parameter
+ name may have been changed.
+
When
* the VNF's Heat Orchestration Template's
@@ -318,5 +283,11 @@ def test_neutron_port_internal_fixed_ips(yaml_file):
an IPv6 address is being cloud assigned by OpenStack's DHCP Service AND
* ``int_{network-role}_v6_subnet_id``
+ Note that the parameter MUST be defined as an output parameter in
+ the base module.
"""
- run_test(yaml_file, validate_internal_fixed_ip)
+ run_test(
+ heat_template,
+ validate_internal_fixed_ip_subnet,
+ validate_internal_subnet_exists_in_base_output,
+ )
diff --git a/ice_validator/tests/test_neutron_port_internal_network.py b/ice_validator/tests/test_neutron_port_internal_network.py
index 00a3a93..e90f87c 100644
--- a/ice_validator/tests/test_neutron_port_internal_network.py
+++ b/ice_validator/tests/test_neutron_port_internal_network.py
@@ -36,39 +36,26 @@
# ============LICENSE_END============================================
#
-import os.path
-import re
-
from tests.parametrizers import get_nested_files
from tests.utils.network_roles import get_network_type_from_port
from .structures import Heat
-from .helpers import validates, load_yaml
-
-
-RE_BASE = re.compile(r"(^base$)|(^base_)|(_base_)|(_base$)")
-
-
-def get_base_template_filepath(yaml_files):
- """Return first filepath to match RE_BASE
- """
- for filepath in yaml_files:
- basename, __ = os.path.splitext(os.path.basename(filepath))
- if RE_BASE.search(basename) and basename.find("volume") == -1:
- return filepath
- return None
+from .helpers import validates, load_yaml, get_base_template_from_yaml_files
@validates("R-22688")
def test_neutron_port_internal_network_v2(yaml_files):
- base_path = get_base_template_filepath(yaml_files)
+ base_path = get_base_template_from_yaml_files(yaml_files)
nested_template_paths = get_nested_files(yaml_files)
errors = []
for yaml_file in yaml_files:
if yaml_file == base_path or yaml_file in nested_template_paths:
continue # Only applies to incremental modules
heat = Heat(filepath=yaml_file)
- internal_ports = {r_id: p for r_id, p in heat.neutron_port_resources.items()
- if get_network_type_from_port(p) == "internal"}
+ internal_ports = {
+ r_id: p
+ for r_id, p in heat.neutron_port_resources.items()
+ if get_network_type_from_port(p) == "internal"
+ }
for r_id, port in internal_ports.items():
props = port.get("properties") or {}
network_value = props.get("network") or {}
@@ -80,15 +67,19 @@ def test_neutron_port_internal_network_v2(yaml_files):
base_heat = load_yaml(base_path)
base_outputs = base_heat.get("outputs") or {}
if not param.endswith("_net_id"):
- errors.append((
- "Internal network {} is attached to port {}, but the "
- "network must be attached via UUID of the network not "
- "the name (ex: int_{{network-role}}_net_id)."
- ).format(param, r_id))
+ errors.append(
+ (
+ "Internal network {} is attached to port {}, but the "
+ "network must be attached via UUID of the network not "
+ "the name (ex: int_{{network-role}}_net_id)."
+ ).format(param, r_id)
+ )
if param not in base_outputs:
- errors.append((
- "Internal network {} is attached to port {}, but network "
- "is not defined as an output in the base module ({})."
- ).format(param, r_id, base_path))
+ errors.append(
+ (
+ "Internal network {} is attached to port {}, but network "
+ "is not defined as an output in the base module ({})."
+ ).format(param, r_id, base_path)
+ )
assert not errors, " ".join(errors)