Make karaf logout more stable
[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     )
22
23     info(
24         "Response %s ",
25         resp,
26     )
27
28     return resp.json()
29
30
31 def get_entity_name(e_type, e_name):
32     """
33     Get the effective entity name for the given entity type.
34     If the entity type is not for odl-general-entity, entity name
35     should be the full instance identifier.
36     :param e_type: entity type
37     :param e_name: entity name
38     :return: updated entity name
39     """
40     name_templates = {
41         "ovsdb": "/network-topology:network-topology/topology[topology-id='ovsdb:1']/node[node-id='%s']",
42     }
43
44     if e_type in name_templates:
45         return name_templates[e_type] % e_name
46     else:
47         return e_name
48
49
50 def get_entity(restconf_url, e_type, e_name):
51     """Calls the get-entity rpc on the controller and returns the result in a
52     dictionary that contains the parsed response in two keys:
53     "candidates" and "owner"
54     """
55
56     data = """
57     {
58         "odl-entity-owners:input" : {
59             "type": "%s",
60             "name": "%s"
61         }
62     }
63     """ % (
64         e_type,
65         get_entity_name(e_type, e_name),
66     )
67
68     info("Data %s", data)
69
70     resp = post(
71         url=restconf_url + "/operations/odl-entity-owners:get-entity",
72         headers={
73             "Content-Type": "application/json",
74             "Accept": "application/json",
75             "User-Agent": "csit agent",
76         },
77         data=data,
78         auth=("admin", "admin"),
79     )
80
81     info(
82         "Entity json %s",
83         resp.json(),
84     )
85
86     if resp.status_code == status_codes["bad_request"]:
87         info(
88             "Status code is '%s' - trying operational data instead.",
89             resp.status_code,
90         )
91         result = get_entity_data(restconf_url, e_type, e_name)
92     else:
93         result = {
94             "candidates": resp.json()["odl-entity-owners:output"]["candidate-nodes"],
95             "owner": resp.json()["odl-entity-owners:output"]["owner-node"],
96         }
97
98     return result
99
100
101 def get_entity_owner(restconf_url, e_type, e_name):
102     data = """
103     {
104         "odl-entity-owners:input" : {
105             "type": "%s",
106             "name": "%s"
107         }
108     }
109     """ % (
110         e_type,
111         get_entity_name(e_type, e_name),
112     )
113
114     info("Data %s", data)
115
116     resp = post(
117         url=restconf_url + "/operations/odl-entity-owners:get-entity-owner",
118         headers={
119             "Content-Type": "application/json",
120             "Accept": "application/json",
121             "User-Agent": "csit agent",
122         },
123         data=data,
124         auth=("admin", "admin"),
125     )
126
127     info(
128         "Response %s ",
129         resp,
130     )
131
132     if resp.status_code == status_codes["bad_request"]:
133         info(
134             "Status code is '%s' - trying operational data instead.",
135             resp.status_code,
136         )
137         result = get_entity_owner_data(restconf_url, e_type, e_name)
138     else:
139         result = resp.json()["odl-entity-owners:output"]["owner-node"]
140
141     return result
142
143
144 def get_entity_type_data(restconf_url, e_type):
145     """
146     Get the entity information for the given entity type from the datastore
147     for Silicon or earlier versions.
148     :param restconf_url: RESTCONF URL up to the RESTCONF root
149     :param e_type: entity type
150     :return: entity-type
151     """
152     resp = get(
153         url=restconf_url
154         + "/data/entity-owners:entity-owners"
155         + "/entity-type=%s" % e_type,
156         headers={
157             "Accept": "application/yang-data+json",
158             "User-Agent": "csit agent",
159         },
160         auth=("admin", "admin"),
161     )
162
163     info(
164         "Response %s ",
165         resp,
166     )
167     info(
168         "Entity json %s",
169         resp.json(),
170     )
171
172     return resp.json()["entity-owners:entity-type"][0]
173
174
175 def get_entity_data(restconf_url, e_type, e_name):
176     """
177     Get the entity owner & candidates for the given entity type
178     and entity name from the datastore for Silicon or earlier versions
179     :param restconf_url: RESTCONF URL up to the RESTCONF root
180     :param e_type: entity type
181     :param e_name: entity name
182     :return: entity owner & candidates
183     """
184     id_templates = {
185         "org.opendaylight.mdsal.ServiceEntityType": "/odl-general-entity:entity[name='%s']",
186         "org.opendaylight.mdsal.AsyncServiceCloseEntityType": "/odl-general-entity:entity[name='%s']",
187         "ovsdb": "/network-topology:network-topology/topology[topology-id='ovsdb:1']/node[node-id='%s']",
188     }
189     id_template = id_templates[e_type]
190
191     entity_type = get_entity_type_data(restconf_url, e_type)
192     entity = [e for e in entity_type["entity"] if e["id"] == id_template % e_name][0]
193
194     result = {
195         "candidates": [c["name"] for c in entity["candidate"]],
196         "owner": entity["owner"],
197     }
198
199     return result
200
201
202 def get_entity_owner_data(restconf_url, e_type, e_name):
203     """
204     Get the entity owner for the given entity type and entity name
205     from the datastore for Silicon or earlier versions
206     :param restconf_url: RESTCONF URL up to the RESTCONF root
207     :param e_type: entity type
208     :param e_name: entity name
209     :return: entity owner
210     """
211     entity = get_entity_data(restconf_url, e_type, e_name)
212     return entity["owner"]
213
214
215 def main(args):
216     if args[0] == "get-entities":
217         json = get_entities(
218             restconf_url="http://127.0.0.1:8181/rests",
219         )
220         print(json)
221     elif args[0] == "get-entity":
222         json = get_entity(
223             restconf_url="http://127.0.0.1:8181/rests",
224             e_type=args[1],
225             e_name=args[2],
226         )
227         print(json)
228     elif args[0] == "get-entity-owner":
229         json = get_entity_owner(
230             restconf_url="http://127.0.0.1:8181/rests",
231             e_type=args[1],
232             e_name=args[2],
233         )
234         print(json)
235     else:
236         raise Exception("Unhandled argument %s" % args[0])
237
238
239 if __name__ == "__main__":
240     # i.e. main does not depend on name of the binary
241     main(argv[1:])