c435916c04267c46b17fcc1f19e3a3278e655921
[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
44 import collections
45
46 import pytest
47
48 from .structures import Heat
49 from .structures import HeatProcessor
50 from .helpers import validates
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(yaml_files):
152     """Test name has unique value
153     """
154     non_servers = {}
155     for yaml_file in yaml_files:
156         h = Heat(filepath=yaml_file)
157         non_servers.update(get_non_servers(h))
158     names = collections.defaultdict(set)
159     for rid, resource in non_servers.items():
160         name = HeatProcessor.get_str_replace_name(resource)
161         if name:
162             names[name].add(rid)
163     bad = {key: value for key, value in names.items() if len(value) > 1}
164     delim = "\n" + 4 * " "
165     assert not bad, "Names must be unique," " not shared across resource ids.%s%s" % (
166         delim,
167         delim.join("%s: %s" % (name, list(value)) for name, value in bad.items()),
168     )