[VVP] R-100280, R-100290, and aap_exempt support 09/87709/5
authorLovett, Trevor <trevor.lovett@att.com>
Tue, 14 May 2019 21:30:42 +0000 (16:30 -0500)
committerLovett, Trevor <trevor.lovett@att.com>
Wed, 15 May 2019 15:00:30 +0000 (10:00 -0500)
Change-Id: I732af13a22e8c1dadc5fbf622a6efd102146262b
Issue-ID: VVP-214
Signed-off-by: Lovett, Trevor <trevor.lovett@att.com>
ice_validator/tests/fixtures/test_allowed_address_pairs_include_vm_type_network_role/fail/contrail/fail.yaml [moved from ice_validator/tests/fixtures/test_contrail_vmi_parameters/fail/fail.yaml with 100% similarity]
ice_validator/tests/fixtures/test_allowed_address_pairs_include_vm_type_network_role/fail/contrail/vmi_fail.yaml [new file with mode: 0644]
ice_validator/tests/fixtures/test_allowed_address_pairs_include_vm_type_network_role/fail/neutron/fail.yaml [moved from ice_validator/tests/fixtures/test_allowed_address_pairs_include_vm_type_network_role/fail/fail.yaml with 100% similarity]
ice_validator/tests/fixtures/test_allowed_address_pairs_include_vm_type_network_role/pass/contrail/pass.yaml [moved from ice_validator/tests/fixtures/test_contrail_vmi_parameters/pass/pass.yaml with 100% similarity]
ice_validator/tests/fixtures/test_allowed_address_pairs_include_vm_type_network_role/pass/contrail/vmi_pass.yaml [new file with mode: 0644]
ice_validator/tests/fixtures/test_allowed_address_pairs_include_vm_type_network_role/pass/contrail/vmi_pass_exemption.yaml [new file with mode: 0644]
ice_validator/tests/fixtures/test_allowed_address_pairs_include_vm_type_network_role/pass/neutron/valid_template.yaml [moved from ice_validator/tests/fixtures/test_allowed_address_pairs_include_vm_type_network_role/pass/valid_template.yaml with 100% similarity]
ice_validator/tests/test_allowed_address_pairs_include_vm_type_network_role.py
ice_validator/tests/test_contrail_vmi_parameters.py [deleted file]
ice_validator/tests/test_neutron_port_addresses.py
ice_validator/tests/utils/ports.py

diff --git a/ice_validator/tests/fixtures/test_allowed_address_pairs_include_vm_type_network_role/fail/contrail/vmi_fail.yaml b/ice_validator/tests/fixtures/test_allowed_address_pairs_include_vm_type_network_role/fail/contrail/vmi_fail.yaml
new file mode 100644 (file)
index 0000000..5113bd4
--- /dev/null
@@ -0,0 +1,61 @@
+# -*- 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============================================
+#
+#
+
+heat_template_version: 2015-04-30
+
+description: fdsafsfsa
+
+parameters:
+
+  invalid_format:
+    type: string
+
+resources:
+
+  fw_0_oam_vmi_0:
+    type: OS::ContrailV2::VirtualMachineInterface
+    properties:
+      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: invalid_format },
+               },
+           }]
diff --git a/ice_validator/tests/fixtures/test_allowed_address_pairs_include_vm_type_network_role/pass/contrail/vmi_pass.yaml b/ice_validator/tests/fixtures/test_allowed_address_pairs_include_vm_type_network_role/pass/contrail/vmi_pass.yaml
new file mode 100644 (file)
index 0000000..959c846
--- /dev/null
@@ -0,0 +1,61 @@
+# -*- 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============================================
+#
+#
+
+heat_template_version: 2015-04-30
+
+description: fdsafsfsa
+
+parameters:
+
+  fw_oam_floating_ip:
+    type: string
+
+resources:
+
+  fw_0_oam_vmi_0:
+    type: OS::ContrailV2::VirtualMachineInterface
+    properties:
+      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: fw_oam_floating_ip },
+               },
+           }]
diff --git a/ice_validator/tests/fixtures/test_allowed_address_pairs_include_vm_type_network_role/pass/contrail/vmi_pass_exemption.yaml b/ice_validator/tests/fixtures/test_allowed_address_pairs_include_vm_type_network_role/pass/contrail/vmi_pass_exemption.yaml
new file mode 100644 (file)
index 0000000..2d9ca4a
--- /dev/null
@@ -0,0 +1,83 @@
+# -*- 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============================================
+#
+#
+
+heat_template_version: 2015-04-30
+
+description: fdsafsfsa
+
+parameters:
+
+  other_format:
+    type: string
+
+  other_ips:
+    type: comma_delimited_list
+
+resources:
+
+  fw_0_oam_vmi_0:
+    type: OS::ContrailV2::VirtualMachineInterface
+    metadata:
+      aap_exempt:
+        - other_format
+    properties:
+      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: other_format },
+               },
+           }]
+
+  fw_0_oam_vmi_1:
+    type: OS::ContrailV2::VirtualMachineInterface
+    metadata:
+      aap_exempt:
+        - other_format
+        - other_ips
+    properties:
+      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: [other_ips, 1] },
+               },
+           }]
\ No newline at end of file
index 76e5f18..6fdb815 100644 (file)
@@ -2,7 +2,7 @@
 # ============LICENSE_START====================================================
 # org.onap.vvp/validation-scripts
 # ===================================================================
-# Copyright © 2017 AT&T Intellectual Property. All rights reserved.
+# Copyright © 2019 AT&T Intellectual Property. All rights reserved.
 # ===================================================================
 #
 # Unless otherwise specified, all software contained herein is licensed
@@ -40,7 +40,10 @@ import re
 
 from .helpers import validates
 from .utils.ports import check_parameter_format
-from tests.structures import NeutronPortProcessor
+from tests.structures import (
+    NeutronPortProcessor,
+    ContrailV2VirtualMachineInterfaceProcessor,
+)
 
 VERSION = "1.0.0"
 
@@ -79,15 +82,53 @@ aap_regx_dict = {
 }
 
 
-@validates("R-41492", "R-35735", "R-159016")
+@validates("R-41492", "R-35735", "R-159016", "R-91810", "R-41956")
 def test_external_aap_format(yaml_file):
     check_parameter_format(
-        yaml_file, aap_regx_dict, "external", NeutronPortProcessor, "allowed_address_pairs", "ip_address"
+        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_parameter_format(
-        yaml_file, aap_regx_dict, "internal", NeutronPortProcessor, "allowed_address_pairs", "ip_address"
+        yaml_file,
+        aap_regx_dict,
+        "internal",
+        NeutronPortProcessor,
+        "allowed_address_pairs",
+        "ip_address",
+    )
+
+
+@validates("R-100280", "R-100290", "R-100310", "R-100330", "R-100350")
+def test_external_aap_format_contrail(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_parameters.py b/ice_validator/tests/test_contrail_vmi_parameters.py
deleted file mode 100644 (file)
index 311e352..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-# -*- 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 b5ce375..ed433c2 100644 (file)
@@ -45,20 +45,12 @@ must have at most one ip_address and at most one v6_ip_address.
 import collections
 import os.path
 
-import pytest
-
 from .structures import Heat
 from .helpers import validates
 
 VERSION = "1.1.0"
 
 
-def is_v6_ip(ip_address):
-    if ip_address.find("v6") != -1:
-        return True
-    return False
-
-
 def get_neutron_ports(heat):
     """Return dict of resource_id: resource, whose type is
     OS::Neutron::Port.
@@ -113,109 +105,6 @@ def nested_update(out_dict, in_dict):
     return out_dict
 
 
-def run_test(heat_template, validate):
-    """call validate with allowed_address_pairs
-    """
-    heat = Heat(filepath=heat_template)
-    if not heat.resources:
-        pytest.skip("No resources found")
-
-    neutron_ports = get_neutron_ports(heat)
-    if not neutron_ports:
-        pytest.skip("No OS::Neutron::Port resources found")
-
-    bad = {}
-    for rid, resource in neutron_ports.items():
-        if rid.startswith("int_"):
-            continue
-        allowed_address_pairs = heat.nested_get(
-            resource, "properties", "allowed_address_pairs"
-        )
-        if allowed_address_pairs is None:
-            continue
-        if not isinstance(allowed_address_pairs, list):
-            bad[rid] = "properties.allowed_address_pairs must be a list."
-            continue
-        error = validate(heat, allowed_address_pairs)
-        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()))
-        )
-
-
-def validate_field(heat, allowed_address_pairs, field, v6=False):
-    """ensure at most one `field` is found in `allowed_address_pairs'
-    validate allowed_addrfess_pairs as well.
-    Returns error message string or None.
-    """
-    error = None
-    ports = set()
-    port_type = "ipv6" if v6 else "ipv4"
-    for allowed_address_pair in allowed_address_pairs:
-        if not isinstance(allowed_address_pair, dict):
-            error = 'allowed_address_pair "%s" is not a dict' % (allowed_address_pair)
-            break
-        if field in allowed_address_pair:
-            param = heat.nested_get(allowed_address_pair, field, "get_param")
-            if param is None:
-                # error = 'allowed_address_pair %s requires "get_param"' % field
-                break
-            else:
-                # if v6 and testing v6, or inverse
-                param = param[0] if isinstance(param, list) else param
-                if v6 == is_v6_ip(param):
-                    ports.add(param)
-    if error is None and len(ports) > 1:
-        error = 'More than one %s "%s" found in allowed_address_pairs: %s' % (
-            port_type,
-            field,
-            list(ports),
-        )
-    return error
-
-
-def validate_external_ipaddress(heat, allowed_address_pairs):
-    """ensure allowed_address_pairs has at most one ip_address
-    Returns error message string or None.
-    """
-    return validate_field(heat, allowed_address_pairs, "ip_address")
-
-
-def validate_external_ipaddress_v6(heat, allowed_address_pairs):
-    """ensure allowed_address_pairs has at most one v6_ip_address
-    Returns error message string or None.
-    """
-    return validate_field(heat, allowed_address_pairs, "ip_address", v6=True)
-
-
-# pylint: disable=invalid-name
-
-
-@validates("R-91810")
-def test_neutron_port_external_ipaddress(yaml_file):
-    """
-    If a VNF requires ONAP to assign a Virtual IP (VIP) Address to
-    ports connected an external network, the port
-    **MUST NOT** have more than one IPv4 VIP address.
-    """
-    run_test(yaml_file, validate_external_ipaddress)
-
-
-@validates("R-41956")
-def test_neutron_port_external_ipaddress_v6(yaml_file):
-    """
-    If a VNF requires ONAP to assign a Virtual IP (VIP) Address to
-    ports connected an external network, the port
-    **MUST NOT** have more than one IPv6 VIP address.
-    """
-    run_test(yaml_file, validate_external_ipaddress_v6)
-
-
 @validates("R-10754")
 def test_neutron_port_floating(yaml_files):
     """
index afce592..93e1d48 100644 (file)
@@ -41,6 +41,18 @@ from tests.helpers import parameter_type_to_heat_type, prop_iterator
 from . import nested_dict
 
 
+def get_aap_exemptions(resource_props):
+    """
+    Gets the list of parameters that the Heat author has exempted from following
+    the naming conventions associated with AAP.
+
+    :param resource_props: dict of properties under the resource ID
+    :return: list of all parameters to exempt or an empty list
+    """
+    metadata = resource_props.get("metadata") or {}
+    return metadata.get("aap_exempt") or []
+
+
 def check_parameter_format(yaml_file, regx, intext, resource_processor, *properties):
     """
     yaml_file: input file to check
@@ -72,7 +84,6 @@ def check_parameter_format(yaml_file, regx, intext, resource_processor, *propert
                 and "get_resource" not in param
                 and "get_attr" not in param
             ):
-
                 # checking parameter uses get_param
                 parameter = param.get("get_param")
                 if not parameter:
@@ -91,27 +102,37 @@ def check_parameter_format(yaml_file, regx, intext, resource_processor, *propert
                     continue
 
                 # checking parameter format = parameter type defined in parameters section
-                heat_parameter_type = nested_dict.get(heat_parameters, parameter, "type")
+                heat_parameter_type = nested_dict.get(
+                    heat_parameters, parameter, "type"
+                )
                 if not heat_parameter_type or heat_parameter_type != parameter_type:
                     msg = (
                         "{} {} parameter {} defined as type {} "
                         + "is being used as type {} in the heat template"
                     ).format(
-                        resource_type, properties, parameter, heat_parameter_type, parameter_type
+                        resource_type,
+                        properties,
+                        parameter,
+                        heat_parameter_type,
+                        parameter_type,
                     )
                     invalid_parameters.append(msg)  # should this actually be an error?
                     continue
 
+                if parameter in get_aap_exemptions(resource):
+                    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."
+                        "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 you are using an alternate option and wish to suppress "
+                        "error, then add the parameter to the aap_exempt list "
+                        "under this resources metadata."
                     ).format(resource_type, properties, parameter, parameter_type)
                     invalid_parameters.append(msg)
                     continue
@@ -121,8 +142,21 @@ def check_parameter_format(yaml_file, regx, intext, resource_processor, *propert
                 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
+                    msg = (
+                        "{} {} property {} parameter {} does not follow {} format {} "
+                        "which is required 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 you are using an alternate option and wish to suppress "
+                        "error, then add the parameter to the aap_exempt list "
+                        "under this resources metadata."
+                    ).format(
+                        resource_type,
+                        rid,
+                        properties,
+                        parameter,
+                        resource_intext,
+                        readable_format,
                     )
                     invalid_parameters.append(msg)
                     continue
@@ -139,7 +173,14 @@ def check_parameter_format(yaml_file, regx, intext, resource_processor, *propert
                         msg = (
                             "{0} {1} property {2} parameter "
                             "{3} {4} does match resource {4} {5}"
-                        ).format(resource_type, rid, properties, parameter, check, resource_match)
+                        ).format(
+                            resource_type,
+                            rid,
+                            properties,
+                            parameter,
+                            check,
+                            resource_match,
+                        )
                         invalid_parameters.append(msg)
                         continue