9361389defc21ea6e18d5300e49b5c791e525cc8
[vvp/validation-scripts.git] / ice_validator / tests / test_non_server_name.py
1 # -*- coding: utf8 -*-
2 # ============LICENSE_START====================================================
3 # org.onap.vvp/validation-scripts
4 # ===================================================================
5 # Copyright © 2019 AT&T Intellectual Property. All rights reserved.
6 # ===================================================================
7 #
8 # Unless otherwise specified, all software contained herein is licensed
9 # under the Apache License, Version 2.0 (the "License");
10 # you may not use this software except in compliance with the License.
11 # You may obtain a copy of the License at
12 #
13 #             http://www.apache.org/licenses/LICENSE-2.0
14 #
15 # Unless required by applicable law or agreed to in writing, software
16 # distributed under the License is distributed on an "AS IS" BASIS,
17 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 # See the License for the specific language governing permissions and
19 # limitations under the License.
20 #
21 #
22 #
23 # Unless otherwise specified, all documentation contained herein is licensed
24 # under the Creative Commons License, Attribution 4.0 Intl. (the "License");
25 # you may not use this documentation except in compliance with the License.
26 # You may obtain a copy of the License at
27 #
28 #             https://creativecommons.org/licenses/by/4.0/
29 #
30 # Unless required by applicable law or agreed to in writing, documentation
31 # distributed under the License is distributed on an "AS IS" BASIS,
32 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
33 # See the License for the specific language governing permissions and
34 # limitations under the License.
35 #
36 # ============LICENSE_END============================================
37 #
38 #
39
40 """
41 resource property name
42 """
43 import os
44 import collections
45 import pytest
46
47 from .structures import Heat
48 from .structures import HeatProcessor
49 from .helpers import validates
50 from tests.utils import nested_files
51
52 VERSION = "1.2.0"
53
54
55 def get_non_servers(heat):
56     """
57     Return a dict of non servers.  key is rid, value is resource
58     """
59     non_servers = {
60         rid: resource
61         for rid, resource in heat.resources.items()
62         if heat.nested_get(resource, "type") != "OS::Nova::Server"
63     }
64     return non_servers
65
66
67 @validates("R-85734")
68 def test_non_server_name(yaml_file):
69     """
70     If a VNF's Heat Orchestration Template contains the property ``name``
71     for a non ``OS::Nova::Server`` resource, the intrinsic function
72     ``str_replace`` **MUST** be used in conjunction with the ONAP
73     supplied metadata parameter ``vnf_name`` to generate a unique value.
74
75     """
76     h = Heat(filepath=yaml_file)
77     if not h.resources:
78         pytest.skip("No resources in this template")
79
80     non_servers = get_non_servers(h)
81     if not non_servers:
82         pytest.skip("No non-server resources in this template")
83
84     bad = []
85     for rid, resource in non_servers.items():
86         name = h.nested_get(resource, "properties", "name")
87         if not name:
88             continue
89
90         # Make sure it uses str_replace
91         str_replace = name.get("str_replace") if hasattr(name, "get") else None
92         if not str_replace:
93             bad.append("{}'s name property does not use str_replace".format(rid))
94             continue
95
96         # Make sure str_replace is properly formatted
97         if not all(key in str_replace for key in ("template", "params")):
98             bad.append(
99                 (
100                     "{}'s name property use of str_replace is "
101                     + "missing template, params, or both"
102                 ).format(rid)
103             )
104             continue
105         params = str_replace["params"]
106         if not isinstance(params, dict):
107             bad.append(
108                 (
109                     "{}'s name property's use of str_replace.params is "
110                     + "missing or invalid"
111                 ).format(rid)
112             )
113             continue
114
115         # Find the param that uses vnf_name
116         vnf_name_param = None
117         for key, value in params.items():
118             if not isinstance(value, dict):
119                 continue
120             if value.get("get_param", "") == "vnf_name":
121                 vnf_name_param = key
122                 break
123         if not vnf_name_param:
124             bad.append(
125                 (
126                     "{}'s name property's use str_replace does not "
127                     + "use have a params that maps to the parameter "
128                     "via {{get_param: vnf_name}}"
129                 ).format(rid)
130             )
131             continue
132
133         # make sure the VNF name is used in the template string
134         template = str_replace.get("template") or ""
135         if vnf_name_param not in template:
136             bad.append(
137                 (
138                     "{}'s name property's str_replace template does "
139                     + "not incorporate vnf_name; expected {} in "
140                     + "template ({})"
141                 ).format(rid, vnf_name_param, template)
142             )
143     msg = (
144         "Improper name property for" " non-OS::Nova::Server resources. "
145     ) + ". ".join(bad)
146
147     assert not bad, msg
148
149
150 @validates("R-85734")
151 def test_non_server_name_unique(heat_template):
152     """Test name has unique value
153     """
154     list_nest = nested_files.get_list_of_nested_files(
155         heat_template, os.path.dirname(heat_template)
156     )
157     list_nest.append(heat_template)
158     non_servers = {}
159     for yaml_file in list_nest:
160         h = Heat(filepath=yaml_file)
161         non_servers.update(get_non_servers(h))
162     names = collections.defaultdict(set)
163     for rid, resource in non_servers.items():
164         name = HeatProcessor.get_str_replace_name(resource)
165         if name:
166             names[name].add(rid)
167     bad = {key: value for key, value in names.items() if len(value) > 1}
168     delim = "\n" + 4 * " "
169     assert not bad, "Names must be unique," " not shared across resource ids.%s%s" % (
170         delim,
171         delim.join("%s: %s" % (name, list(value)) for name, value in bad.items()),
172     )