Merge "Unit tests added for openstack/tempest"
[functest.git] / functest / utils / openstack_tacker.py
1 ###########################################################################
2 # Copyright (c) 2016 Ericsson AB and others.
3 # Author: George Paraskevopoulos <geopar@intracom-telecom.com>
4 #
5 # Wrappers for trozet's python-tackerclient v1.0
6 # (https://github.com/trozet/python-tackerclient)
7 #
8 # All rights reserved. This program and the accompanying materials
9 # are made available under the terms of the Apache License, Version 2.0
10 # which accompanies this distribution, and is available at
11 # http://www.apache.org/licenses/LICENSE-2.0
12 ##########################################################################
13
14
15 from tackerclient.v1_0 import client as tackerclient
16 import functest.utils.functest_logger as ft_logger
17 import functest.utils.openstack_utils as os_utils
18 import time
19
20 logger = ft_logger.Logger("tacker_utils").getLogger()
21
22
23 def get_tacker_client(other_creds={}):
24     sess = os_utils.get_session(other_creds)
25     return tackerclient.Client(session=sess)
26
27
28 # *********************************************
29 #   TACKER
30 # *********************************************
31 def get_id_from_name(tacker_client, resource_type, resource_name):
32     try:
33         req_params = {'fields': 'id', 'name': resource_name}
34         endpoint = '/{0}s'.format(resource_type)
35         resp = tacker_client.get(endpoint, params=req_params)
36         endpoint = endpoint.replace('-', '_')
37         return resp[endpoint[1:]][0]['id']
38     except Exception, e:
39         logger.error("Error [get_id_from_name(tacker_client, "
40                      "resource_type, resource_name)]: %s" % e)
41         return None
42
43
44 def get_vnfd_id(tacker_client, vnfd_name):
45     return get_id_from_name(tacker_client, 'vnfd', vnfd_name)
46
47
48 def get_vnf_id(tacker_client, vnf_name, timeout=5):
49     vnf_id = None
50     while vnf_id is None and timeout >= 0:
51         vnf_id = get_id_from_name(tacker_client, 'vnf', vnf_name)
52         if vnf_id is None:
53             logger.info("Could not retrieve ID for vnf with name [%s]."
54                         " Retrying." % vnf_name)
55             time.sleep(1)
56             timeout -= 1
57     return vnf_id
58
59
60 def get_sfc_id(tacker_client, sfc_name):
61     return get_id_from_name(tacker_client, 'sfc', sfc_name)
62
63
64 def get_sfc_classifier_id(tacker_client, sfc_clf_name):
65     return get_id_from_name(tacker_client, 'sfc-classifier', sfc_clf_name)
66
67
68 def list_vnfds(tacker_client, verbose=False):
69     try:
70         vnfds = tacker_client.list_vnfds(retrieve_all=True)
71         if not verbose:
72             vnfds = [vnfd['id'] for vnfd in vnfds['vnfds']]
73         return vnfds
74     except Exception, e:
75         logger.error("Error [list_vnfds(tacker_client)]: %s" % e)
76         return None
77
78
79 def create_vnfd(tacker_client, tosca_file=None):
80     try:
81         vnfd_body = {}
82         if tosca_file is not None:
83             with open(tosca_file) as tosca_fd:
84                 vnfd_body = tosca_fd.read()
85             logger.info('VNFD template:\n{0}'.format(vnfd_body))
86         return tacker_client.create_vnfd(
87             body={"vnfd": {"attributes": {"vnfd": vnfd_body}}})
88     except Exception, e:
89         logger.error("Error [create_vnfd(tacker_client, '%s')]: %s"
90                      % (tosca_file, e))
91         return None
92
93
94 def delete_vnfd(tacker_client, vnfd_id=None, vnfd_name=None):
95     try:
96         vnfd = vnfd_id
97         if vnfd is None:
98             if vnfd_name is None:
99                 raise Exception('You need to provide VNFD id or VNFD name')
100             vnfd = get_vnfd_id(tacker_client, vnfd_name)
101         return tacker_client.delete_vnfd(vnfd)
102     except Exception, e:
103         logger.error("Error [delete_vnfd(tacker_client, '%s', '%s')]: %s"
104                      % (vnfd_id, vnfd_name, e))
105         return None
106
107
108 def list_vnfs(tacker_client, verbose=False):
109     try:
110         vnfs = tacker_client.list_vnfs(retrieve_all=True)
111         if not verbose:
112             vnfs = [vnf['id'] for vnf in vnfs['vnfs']]
113         return vnfs
114     except Exception, e:
115         logger.error("Error [list_vnfs(tacker_client)]: %s" % e)
116         return None
117
118
119 def create_vnf(tacker_client, vnf_name, vnfd_id=None,
120                vnfd_name=None, param_file=None):
121     try:
122         vnf_body = {
123             'vnf': {
124                 'attributes': {},
125                 'name': vnf_name
126             }
127         }
128         if param_file is not None:
129             params = None
130             with open(param_file) as f:
131                 params = f.read()
132             vnf_body['vnf']['attributes']['param_values'] = params
133         if vnfd_id is not None:
134             vnf_body['vnf']['vnfd_id'] = vnfd_id
135         else:
136             if vnfd_name is None:
137                 raise Exception('vnfd id or vnfd name is required')
138             vnf_body['vnf']['vnfd_id'] = get_vnfd_id(tacker_client, vnfd_name)
139         return tacker_client.create_vnf(body=vnf_body)
140     except Exception, e:
141         logger.error("error [create_vnf(tacker_client,"
142                      " '%s', '%s', '%s')]: %s"
143                      % (vnf_name, vnfd_id, vnfd_name, e))
144         return None
145
146
147 def get_vnf(tacker_client, vnf_id=None, vnf_name=None):
148     try:
149         if vnf_id is None and vnf_name is None:
150             raise Exception('You must specify vnf_id or vnf_name')
151
152         _id = get_vnf_id(tacker_client, vnf_name) if vnf_id is None else vnf_id
153
154         if _id is not None:
155             all_vnfs = list_vnfs(tacker_client, verbose=True)['vnfs']
156             return next((vnf for vnf in all_vnfs if vnf['id'] == _id), None)
157         else:
158             raise Exception('Could not retrieve ID from name [%s]' % vnf_name)
159
160     except Exception, e:
161         logger.error("Could not retrieve VNF [vnf_id=%s, vnf_name=%s] - %s"
162                      % (vnf_id, vnf_name, e))
163         return None
164
165
166 def wait_for_vnf(tacker_client, vnf_id=None, vnf_name=None, timeout=60):
167     try:
168         vnf = get_vnf(tacker_client, vnf_id, vnf_name)
169         if vnf is None:
170             raise Exception("Could not retrieve VNF - id='%s', name='%s'"
171                             % vnf_id, vnf_name)
172         logger.info('Waiting for vnf {0}'.format(str(vnf)))
173         while vnf['status'] != 'ACTIVE' and timeout >= 0:
174             if vnf['status'] == 'ERROR':
175                 raise Exception('Error when booting vnf %s' % vnf['id'])
176             elif vnf['status'] == 'PENDING_CREATE':
177                 time.sleep(3)
178                 timeout -= 3
179             vnf = get_vnf(tacker_client, vnf_id, vnf_name)
180
181         if (timeout < 0):
182             raise Exception('Timeout when booting vnf %s' % vnf['id'])
183
184         return vnf['id']
185     except Exception, e:
186         logger.error("error [wait_for_vnf(tacker_client, '%s', '%s')]: %s"
187                      % (vnf_id, vnf_name, e))
188         return None
189
190
191 def delete_vnf(tacker_client, vnf_id=None, vnf_name=None):
192     try:
193         vnf = vnf_id
194         if vnf is None:
195             if vnf_name is None:
196                 raise Exception('You need to provide a VNF id or name')
197             vnf = get_vnf_id(tacker_client, vnf_name)
198         return tacker_client.delete_vnf(vnf)
199     except Exception, e:
200         logger.error("Error [delete_vnf(tacker_client, '%s', '%s')]: %s"
201                      % (vnf_id, vnf_name, e))
202         return None
203
204
205 def list_sfcs(tacker_client, verbose=False):
206     try:
207         sfcs = tacker_client.list_sfcs(retrieve_all=True)
208         if not verbose:
209             sfcs = [sfc['id'] for sfc in sfcs['sfcs']]
210         return sfcs
211     except Exception, e:
212         logger.error("Error [list_sfcs(tacker_client)]: %s" % e)
213         return None
214
215
216 def create_sfc(tacker_client, sfc_name,
217                chain_vnf_ids=None,
218                chain_vnf_names=None,
219                symmetrical=False):
220     try:
221         sfc_body = {
222             'sfc': {
223                 'attributes': {},
224                 'name': sfc_name,
225                 'chain': []
226             }
227         }
228         if symmetrical:
229             sfc_body['sfc']['symmetrical'] = True
230         if chain_vnf_ids is not None:
231             sfc_body['sfc']['chain'] = chain_vnf_ids
232         else:
233             if chain_vnf_names is None:
234                 raise Exception('You need to provide a chain of VNFs')
235             sfc_body['sfc']['chain'] = [get_vnf_id(tacker_client, name)
236                                         for name in chain_vnf_names]
237         return tacker_client.create_sfc(body=sfc_body)
238     except Exception, e:
239         logger.error("error [create_sfc(tacker_client,"
240                      " '%s', '%s', '%s')]: %s"
241                      % (sfc_name, chain_vnf_ids, chain_vnf_names, e))
242         return None
243
244
245 def delete_sfc(tacker_client, sfc_id=None, sfc_name=None):
246     try:
247         sfc = sfc_id
248         if sfc is None:
249             if sfc_name is None:
250                 raise Exception('You need to provide an SFC id or name')
251             sfc = get_sfc_id(tacker_client, sfc_name)
252         return tacker_client.delete_sfc(sfc)
253     except Exception, e:
254         logger.error("Error [delete_sfc(tacker_client, '%s', '%s')]: %s"
255                      % (sfc_id, sfc_name, e))
256         return None
257
258
259 def list_sfc_classifiers(tacker_client, verbose=False):
260     try:
261         sfc_clfs = tacker_client.list_sfc_classifiers(retrieve_all=True)
262         if not verbose:
263             sfc_clfs = [sfc_clf['id']
264                         for sfc_clf in sfc_clfs['sfc_classifiers']]
265         return sfc_clfs
266     except Exception, e:
267         logger.error("Error [list_sfc_classifiers(tacker_client)]: %s" % e)
268         return None
269
270
271 def create_sfc_classifier(tacker_client, sfc_clf_name, sfc_id=None,
272                           sfc_name=None, match={}):
273     # Example match:
274     # match: {
275     #     "source_port": "0",
276     #     "protocol": "6",
277     #     "dest_port": "80"
278     # }
279     try:
280         sfc_clf_body = {
281             'sfc_classifier': {
282                 'attributes': {},
283                 'name': sfc_clf_name,
284                 'match': match,
285                 'chain': ''
286             }
287         }
288         if sfc_id is not None:
289             sfc_clf_body['sfc_classifier']['chain'] = sfc_id
290         else:
291             if sfc_name is None:
292                 raise Exception('You need to provide an SFC id or name')
293             sfc_clf_body['sfc_classifier']['chain'] = get_sfc_id(
294                 tacker_client, sfc_name)
295         return tacker_client.create_sfc_classifier(body=sfc_clf_body)
296     except Exception, e:
297         logger.error("error [create_sfc_classifier(tacker_client,"
298                      " '%s', '%s','%s', '%s')]: '%s'"
299                      % (sfc_clf_name, sfc_id, sfc_name, str(match), e))
300         return None
301
302
303 def delete_sfc_classifier(tacker_client,
304                           sfc_clf_id=None,
305                           sfc_clf_name=None):
306     try:
307         sfc_clf = sfc_clf_id
308         if sfc_clf is None:
309             if sfc_clf_name is None:
310                 raise Exception('You need to provide an SFC'
311                                 'classifier id or name')
312             sfc_clf = get_sfc_classifier_id(tacker_client, sfc_clf_name)
313         return tacker_client.delete_sfc_classifier(sfc_clf)
314     except Exception, e:
315         logger.error("Error [delete_sfc_classifier(tacker_client, '%s', "
316                      "'%s')]: %s" % (sfc_clf_id, sfc_clf_name, e))
317         return None