Fix expected_status types
[integration/test.git] / csit / libraries / ClusterEntities.py
1 """
2     Utility library for retrieving entity related data from ODL.
3 """
4
5 from logging import info
6 from requests import codes as status_codes
7 from requests import get
8 from requests import post
9 from sys import argv
10
11
12 def get_entities(restconf_url):
13     resp = post(
14         url=restconf_url + "/operations/odl-entity-owners:get-entities",
15         headers={
16             "Content-Type": "application/json",
17             "Accept": "application/json",
18             "User-Agent": "csit agent",
19         },
20         auth=("admin", "admin"),
21         timeout=10.0,
22     )
23
24     info(
25         "Response %s",
26         resp,
27     )
28     info(
29         "Response JSON %s",
30         resp.json(),
31     )
32
33     if resp.status_code == status_codes["bad_request"]:
34         info(
35             "Status code is '%s' - trying operational data instead.",
36             resp.status_code,
37         )
38         result = get_entities_data(restconf_url)
39     else:
40         result = resp.json()
41
42     return result
43
44
45 def get_entity_name(e_type, e_name):
46     """
47     Get the effective entity name for the given entity type.
48     If the entity type is not for odl-general-entity, entity name
49     should be the full instance identifier.
50     :param e_type: entity type
51     :param e_name: entity name
52     :return: updated entity name
53     """
54     name_templates = {
55         "ovsdb": "/network-topology:network-topology/topology[topology-id='ovsdb:1']/node[node-id='%s']",
56     }
57
58     if e_type in name_templates:
59         return name_templates[e_type] % e_name
60     else:
61         return e_name
62
63
64 def get_entity(restconf_url, e_type, e_name):
65     """Calls the get-entity rpc on the controller and returns the result in a
66     dictionary that contains the parsed response in two keys:
67     "candidates" and "owner"
68     """
69
70     data = """
71     {
72         "odl-entity-owners:input" : {
73             "type": "%s",
74             "name": "%s"
75         }
76     }
77     """ % (
78         e_type,
79         get_entity_name(e_type, e_name),
80     )
81
82     info("Data %s", data)
83
84     resp = post(
85         url=restconf_url + "/operations/odl-entity-owners:get-entity",
86         headers={
87             "Content-Type": "application/json",
88             "Accept": "application/json",
89             "User-Agent": "csit agent",
90         },
91         data=data,
92         auth=("admin", "admin"),
93         timeout=10.0,
94     )
95
96     info(
97         "Response %s",
98         resp,
99     )
100     info(
101         "Response JSON %s",
102         resp.json(),
103     )
104
105     if resp.status_code == status_codes["bad_request"]:
106         info(
107             "Status code is '%s' - trying operational data instead.",
108             resp.status_code,
109         )
110         result = get_entity_data(restconf_url, e_type, e_name)
111     else:
112         result = {
113             "candidates": resp.json()["odl-entity-owners:output"]["candidate-nodes"],
114             "owner": resp.json()["odl-entity-owners:output"]["owner-node"],
115         }
116
117     return result
118
119
120 def get_entity_owner(restconf_url, e_type, e_name):
121     data = """
122     {
123         "odl-entity-owners:input" : {
124             "type": "%s",
125             "name": "%s"
126         }
127     }
128     """ % (
129         e_type,
130         get_entity_name(e_type, e_name),
131     )
132
133     info("Data %s", data)
134
135     resp = post(
136         url=restconf_url + "/operations/odl-entity-owners:get-entity-owner",
137         headers={
138             "Content-Type": "application/json",
139             "Accept": "application/json",
140             "User-Agent": "csit agent",
141         },
142         data=data,
143         auth=("admin", "admin"),
144         timeout=10.0,
145     )
146
147     info(
148         "Response %s",
149         resp,
150     )
151     info(
152         "Response JSON %s",
153         resp.json(),
154     )
155
156     if resp.status_code == status_codes["bad_request"]:
157         info(
158             "Status code is '%s' - trying operational data instead.",
159             resp.status_code,
160         )
161         result = get_entity_owner_data(restconf_url, e_type, e_name)
162     else:
163         result = resp.json()["odl-entity-owners:output"]["owner-node"]
164
165     return result
166
167
168 def get_entities_data(restconf_url):
169     """
170     Get the entity information from the datastore for Silicon
171     or earlier versions.
172     :param restconf_url: RESTCONF URL up to the RESTCONF root
173     """
174     resp = get(
175         url=restconf_url + "/data/entity-owners:entity-owners",
176         headers={
177             "Accept": "application/yang-data+json",
178             "User-Agent": "csit agent",
179         },
180         auth=("admin", "admin"),
181         timeout=10.0,
182     )
183
184     info(
185         "Response %s",
186         resp,
187     )
188     info(
189         "Response JSON %s",
190         resp.json(),
191     )
192
193     return resp.json()
194
195
196 def get_entity_type_data(restconf_url, e_type):
197     """
198     Get the entity information for the given entity type from the datastore
199     for Silicon or earlier versions.
200     :param restconf_url: RESTCONF URL up to the RESTCONF root
201     :param e_type: entity type
202     :return: entity-type
203     """
204     resp = get(
205         url=restconf_url
206         + "/data/entity-owners:entity-owners"
207         + "/entity-type=%s" % e_type,
208         headers={
209             "Accept": "application/yang-data+json",
210             "User-Agent": "csit agent",
211         },
212         auth=("admin", "admin"),
213         timeout=10.0,
214     )
215
216     info(
217         "Response %s",
218         resp,
219     )
220     info(
221         "Response JSON %s",
222         resp.json(),
223     )
224
225     return resp.json()["entity-owners:entity-type"][0]
226
227
228 def get_entity_data(restconf_url, e_type, e_name):
229     """
230     Get the entity owner & candidates for the given entity type
231     and entity name from the datastore for Silicon or earlier versions
232     :param restconf_url: RESTCONF URL up to the RESTCONF root
233     :param e_type: entity type
234     :param e_name: entity name
235     :return: entity owner & candidates
236     """
237     id_templates = {
238         "org.opendaylight.mdsal.ServiceEntityType": "/odl-general-entity:entity[name='%s']",
239         "org.opendaylight.mdsal.AsyncServiceCloseEntityType": "/odl-general-entity:entity[name='%s']",
240         "ovsdb": "/network-topology:network-topology/topology[topology-id='ovsdb:1']/node[node-id='%s']",
241     }
242     id_template = id_templates[e_type]
243
244     entity_type = get_entity_type_data(restconf_url, e_type)
245     entity = [e for e in entity_type["entity"] if e["id"] == id_template % e_name][0]
246
247     result = {
248         "candidates": [c["name"] for c in entity["candidate"]],
249         "owner": entity["owner"],
250     }
251
252     return result
253
254
255 def get_entity_owner_data(restconf_url, e_type, e_name):
256     """
257     Get the entity owner for the given entity type and entity name
258     from the datastore for Silicon or earlier versions
259     :param restconf_url: RESTCONF URL up to the RESTCONF root
260     :param e_type: entity type
261     :param e_name: entity name
262     :return: entity owner
263     """
264     entity = get_entity_data(restconf_url, e_type, e_name)
265     return entity["owner"]
266
267
268 def main(args):
269     if args[0] == "get-entities":
270         json = get_entities(
271             restconf_url="http://127.0.0.1:8181/rests",
272         )
273         print(json)
274     elif args[0] == "get-entity":
275         json = get_entity(
276             restconf_url="http://127.0.0.1:8181/rests",
277             e_type=args[1],
278             e_name=args[2],
279         )
280         print(json)
281     elif args[0] == "get-entity-owner":
282         json = get_entity_owner(
283             restconf_url="http://127.0.0.1:8181/rests",
284             e_type=args[1],
285             e_name=args[2],
286         )
287         print(json)
288     else:
289         raise Exception("Unhandled argument %s" % args[0])
290
291
292 if __name__ == "__main__":
293     # i.e. main does not depend on name of the binary
294     main(argv[1:])