Merge "Revert "Add deployment_handler printout to prepare env""
[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):
49     return get_id_from_name(tacker_client, 'vnf', vnf_name)
50
51
52 def get_sfc_id(tacker_client, sfc_name):
53     return get_id_from_name(tacker_client, 'sfc', sfc_name)
54
55
56 def get_sfc_classifier_id(tacker_client, sfc_clf_name):
57     return get_id_from_name(tacker_client, 'sfc-classifier', sfc_clf_name)
58
59
60 def list_vnfds(tacker_client, verbose=False):
61     try:
62         vnfds = tacker_client.list_vnfds(retrieve_all=True)
63         if not verbose:
64             vnfds = [vnfd['id'] for vnfd in vnfds['vnfds']]
65         return vnfds
66     except Exception, e:
67         logger.error("Error [list_vnfds(tacker_client)]: %s" % e)
68         return None
69
70
71 def create_vnfd(tacker_client, tosca_file=None):
72     try:
73         vnfd_body = {}
74         if tosca_file is not None:
75             with open(tosca_file) as tosca_fd:
76                 vnfd_body = tosca_fd.read()
77             logger.info('VNFD template:\n{0}'.format(vnfd_body))
78         return tacker_client.create_vnfd(
79             body={"vnfd": {"attributes": {"vnfd": vnfd_body}}})
80     except Exception, e:
81         logger.error("Error [create_vnfd(tacker_client, '%s')]: %s"
82                      % (tosca_file, e))
83         return None
84
85
86 def delete_vnfd(tacker_client, vnfd_id=None, vnfd_name=None):
87     try:
88         vnfd = vnfd_id
89         if vnfd is None:
90             if vnfd_name is None:
91                 raise Exception('You need to provide VNFD id or VNFD name')
92             vnfd = get_vnfd_id(tacker_client, vnfd_name)
93         return tacker_client.delete_vnfd(vnfd)
94     except Exception, e:
95         logger.error("Error [delete_vnfd(tacker_client, '%s', '%s')]: %s"
96                      % (vnfd_id, vnfd_name, e))
97         return None
98
99
100 def list_vnfs(tacker_client, verbose=False):
101     try:
102         vnfs = tacker_client.list_vnfs(retrieve_all=True)
103         if not verbose:
104             vnfs = [vnf['id'] for vnf in vnfs['vnfs']]
105         return vnfs
106     except Exception, e:
107         logger.error("Error [list_vnfs(tacker_client)]: %s" % e)
108         return None
109
110
111 def create_vnf(tacker_client, vnf_name, vnfd_id=None,
112                vnfd_name=None, param_file=None):
113     try:
114         vnf_body = {
115             'vnf': {
116                 'attributes': {},
117                 'name': vnf_name
118             }
119         }
120         if param_file is not None:
121             params = None
122             with open(param_file) as f:
123                 params = f.read()
124             vnf_body['vnf']['attributes']['param_values'] = params
125         if vnfd_id is not None:
126             vnf_body['vnf']['vnfd_id'] = vnfd_id
127         else:
128             if vnfd_name is None:
129                 raise Exception('vnfd id or vnfd name is required')
130             vnf_body['vnf']['vnfd_id'] = get_vnfd_id(tacker_client, vnfd_name)
131         return tacker_client.create_vnf(body=vnf_body)
132     except Exception, e:
133         logger.error("error [create_vnf(tacker_client,"
134                      " '%s', '%s', '%s')]: %s"
135                      % (vnf_name, vnfd_id, vnfd_name, e))
136         return None
137
138
139 def wait_for_vnf(tacker_client, vnf_id=None, vnf_name=None):
140     try:
141         _id = None
142         if vnf_id is not None:
143             _id = vnf_id
144         elif vnf_name is not None:
145             while _id is None:
146                 try:
147                     _id = get_vnf_id(tacker_client, vnf_name)
148                 except:
149                     logger.error("Bazinga")
150         else:
151             raise Exception('You must specify vnf_id or vnf_name')
152         while True:
153             vnf = [v for v in list_vnfs(tacker_client, verbose=True)['vnfs']
154                    if v['id'] == _id]
155             vnf = vnf[0]
156             logger.info('Waiting for vnf {0}'.format(str(vnf)))
157             if vnf['status'] == 'ERROR':
158                 raise Exception('Error when booting vnf %s' % _id)
159             elif vnf['status'] == 'PENDING_CREATE':
160                 time.sleep(3)
161                 continue
162             else:
163                 break
164         return _id
165     except Exception, e:
166         logger.error("error [wait_for_vnf(tacker_client, '%s', '%s')]: %s"
167                      % (vnf_id, vnf_name, e))
168         return None
169
170
171 def delete_vnf(tacker_client, vnf_id=None, vnf_name=None):
172     try:
173         vnf = vnf_id
174         if vnf is None:
175             if vnf_name is None:
176                 raise Exception('You need to provide a VNF id or name')
177             vnf = get_vnf_id(tacker_client, vnf_name)
178         return tacker_client.delete_vnf(vnf)
179     except Exception, e:
180         logger.error("Error [delete_vnf(tacker_client, '%s', '%s')]: %s"
181                      % (vnf_id, vnf_name, e))
182         return None
183
184
185 def list_sfcs(tacker_client, verbose=False):
186     try:
187         sfcs = tacker_client.list_sfcs(retrieve_all=True)
188         if not verbose:
189             sfcs = [sfc['id'] for sfc in sfcs['sfcs']]
190         return sfcs
191     except Exception, e:
192         logger.error("Error [list_sfcs(tacker_client)]: %s" % e)
193         return None
194
195
196 def create_sfc(tacker_client, sfc_name,
197                chain_vnf_ids=None,
198                chain_vnf_names=None,
199                symmetrical=False):
200     try:
201         sfc_body = {
202             'sfc': {
203                 'attributes': {},
204                 'name': sfc_name,
205                 'chain': []
206             }
207         }
208         if symmetrical:
209             sfc_body['sfc']['symmetrical'] = True
210         if chain_vnf_ids is not None:
211             sfc_body['sfc']['chain'] = chain_vnf_ids
212         else:
213             if chain_vnf_names is None:
214                 raise Exception('You need to provide a chain of VNFs')
215             sfc_body['sfc']['chain'] = [get_vnf_id(tacker_client, name)
216                                         for name in chain_vnf_names]
217         return tacker_client.create_sfc(body=sfc_body)
218     except Exception, e:
219         logger.error("error [create_sfc(tacker_client,"
220                      " '%s', '%s', '%s')]: %s"
221                      % (sfc_name, chain_vnf_ids, chain_vnf_names, e))
222         return None
223
224
225 def delete_sfc(tacker_client, sfc_id=None, sfc_name=None):
226     try:
227         sfc = sfc_id
228         if sfc is None:
229             if sfc_name is None:
230                 raise Exception('You need to provide an SFC id or name')
231             sfc = get_sfc_id(tacker_client, sfc_name)
232         return tacker_client.delete_sfc(sfc)
233     except Exception, e:
234         logger.error("Error [delete_sfc(tacker_client, '%s', '%s')]: %s"
235                      % (sfc_id, sfc_name, e))
236         return None
237
238
239 def list_sfc_classifiers(tacker_client, verbose=False):
240     try:
241         sfc_clfs = tacker_client.list_sfc_classifiers(retrieve_all=True)
242         if not verbose:
243             sfc_clfs = [sfc_clf['id']
244                         for sfc_clf in sfc_clfs['sfc_classifiers']]
245         return sfc_clfs
246     except Exception, e:
247         logger.error("Error [list_sfc_classifiers(tacker_client)]: %s" % e)
248         return None
249
250
251 def create_sfc_classifier(tacker_client, sfc_clf_name, sfc_id=None,
252                           sfc_name=None, match={}):
253     # Example match:
254     # match: {
255     #     "source_port": "0",
256     #     "protocol": "6",
257     #     "dest_port": "80"
258     # }
259     try:
260         sfc_clf_body = {
261             'sfc_classifier': {
262                 'attributes': {},
263                 'name': sfc_clf_name,
264                 'match': match,
265                 'chain': ''
266             }
267         }
268         if sfc_id is not None:
269             sfc_clf_body['sfc_classifier']['chain'] = sfc_id
270         else:
271             if sfc_name is None:
272                 raise Exception('You need to provide an SFC id or name')
273             sfc_clf_body['sfc_classifier']['chain'] = get_sfc_id(
274                 tacker_client, sfc_name)
275         return tacker_client.create_sfc_classifier(body=sfc_clf_body)
276     except Exception, e:
277         logger.error("error [create_sfc_classifier(tacker_client,"
278                      " '%s', '%s','%s', '%s')]: '%s'"
279                      % (sfc_clf_name, sfc_id, sfc_name, str(match), e))
280         return None
281
282
283 def delete_sfc_classifier(tacker_client,
284                           sfc_clf_id=None,
285                           sfc_clf_name=None):
286     try:
287         sfc_clf = sfc_clf_id
288         if sfc_clf is None:
289             if sfc_clf_name is None:
290                 raise Exception('You need to provide an SFC'
291                                 'classifier id or name')
292             sfc_clf = get_sfc_classifier_id(tacker_client, sfc_clf_name)
293         return tacker_client.delete_sfc_classifier(sfc_clf)
294     except Exception, e:
295         logger.error("Error [delete_sfc_classifier(tacker_client, '%s', "
296                      "'%s')]: %s" % (sfc_clf_id, sfc_clf_name, e))
297         return None