f47e078f2e76bdd615617f1a3f4d72353fe7bddc
[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 # ECOMP is a trademark and service mark of AT&T Intellectual Property.
39 #
40
41 """
42 resource property name
43 """
44
45 import collections
46
47 import pytest
48
49 from .structures import Heat
50 from .structures import HeatProcessor
51 from .helpers import validates
52
53 VERSION = "1.2.0"
54
55
56 def get_non_servers(heat):
57     """
58     Return a dict of non servers.  key is rid, value is resource
59     """
60     non_servers = {
61         rid: resource
62         for rid, resource in heat.resources.items()
63         if heat.nested_get(resource, "type") != "OS::Nova::Server"
64     }
65     return non_servers
66
67
68 @validates("R-85734")
69 def test_non_server_name(heat_template):
70     """
71     If a VNF's Heat Orchestration Template contains the property ``name``
72     for a non ``OS::Nova::Server`` resource, the intrinsic function
73     ``str_replace`` **MUST** be used in conjunction with the ONAP
74     supplied metadata parameter ``vnf_name`` to generate a unique value.
75
76     """
77     h = Heat(filepath=heat_template)
78     if not h.resources:
79         pytest.skip("No resources in this template")
80
81     non_servers = get_non_servers(h)
82     if not non_servers:
83         pytest.skip("No non-server resources in this template")
84
85     bad = []
86     for rid, resource in non_servers.items():
87         name = h.nested_get(resource, "properties", "name")
88         if not name:
89             continue
90
91         # Make sure it uses str_replace
92         str_replace = name.get("str_replace") if hasattr(name, "get") else None
93         if not str_replace:
94             bad.append("{}'s name property does not use str_replace".format(rid))
95             continue
96
97         # Make sure str_replace is properly formatted
98         if not all(key in str_replace for key in ("template", "params")):
99             bad.append(
100                 (
101                     "{}'s name property use of str_replace is "
102                     + "missing template, params, or both"
103                 ).format(rid)
104             )
105             continue
106         params = str_replace["params"]
107         if not isinstance(params, dict):
108             bad.append(
109                 (
110                     "{}'s name property's use of str_replace.params is "
111                     + "missing or invalid"
112                 ).format(rid)
113             )
114             continue
115
116         # Find the param that uses vnf_name
117         vnf_name_param = None
118         for key, value in params.items():
119             if not isinstance(value, dict):
120                 continue
121             if value.get("get_param", "") == "vnf_name":
122                 vnf_name_param = key
123                 break
124         if not vnf_name_param:
125             bad.append(
126                 (
127                     "{}'s name property's use str_replace does not "
128                     + "use have a params that maps to the parameter "
129                     "via {{get_param: vnf_name}}"
130                 ).format(rid)
131             )
132             continue
133
134         # make sure the VNF name is used in the template string
135         template = str_replace.get("template") or ""
136         if vnf_name_param not in template:
137             bad.append(
138                 (
139                     "{}'s name property's str_replace template does "
140                     + "not incorporate vnf_name; expected {} in "
141                     + "template ({})"
142                 ).format(rid, vnf_name_param, template)
143             )
144     msg = (
145         "Improper name property for" " non-OS::Nova::Server resources. "
146     ) + ". ".join(bad)
147
148     assert not bad, msg
149
150
151 @validates("R-85734")
152 def test_non_server_name_unique(yaml_files):
153     """Test name has unique value
154     """
155     non_servers = {}
156     for yaml_file in yaml_files:
157         h = Heat(filepath=yaml_file)
158         non_servers.update(get_non_servers(h))
159     names = collections.defaultdict(set)
160     for rid, resource in non_servers.items():
161         name = HeatProcessor.get_str_replace_name(resource)
162         if name:
163             names[name].add(rid)
164     bad = {key: value for key, value in names.items() if len(value) > 1}
165     delim = "\n" + 4 * " "
166     assert not bad, "Names must be unique," " not shared across resource ids.%s%s" % (
167         delim,
168         delim.join("%s: %s" % (name, list(value)) for name, value in bad.items()),
169     )