30bbe02b0a2200302b66b4c3ad889e24f2a80f57
[osm/osmclient.git] / osmclient / sol005 / ns.py
1 # Copyright 2018 Telefonica
2 #
3 # All Rights Reserved.
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License"); you may
6 # not use this file except in compliance with the License. You may obtain
7 # a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14 # License for the specific language governing permissions and limitations
15 # under the License.
16
17 """
18 OSM ns API handling
19 """
20
21 from osmclient.common import utils
22 from osmclient.common.exceptions import ClientException
23 from osmclient.common.exceptions import NotFound
24 import yaml
25 import json
26
27
28 class Ns(object):
29
30 def __init__(self, http=None, client=None):
31 self._http = http
32 self._client = client
33 self._apiName = '/nslcm'
34 self._apiVersion = '/v1'
35 self._apiResource = '/ns_instances_content'
36 self._apiBase = '{}{}{}'.format(self._apiName,
37 self._apiVersion, self._apiResource)
38
39 def list(self, filter=None):
40 """Returns a list of NS
41 """
42 filter_string = ''
43 if filter:
44 filter_string = '?{}'.format(filter)
45 resp = self._http.get_cmd('{}{}'.format(self._apiBase,filter_string))
46 if resp:
47 return resp
48 return list()
49
50 def get(self, name):
51 """Returns an NS based on name or id
52 """
53 if utils.validate_uuid4(name):
54 for ns in self.list():
55 if name == ns['_id']:
56 return ns
57 else:
58 for ns in self.list():
59 if name == ns['name']:
60 return ns
61 raise NotFound("ns {} not found".format(name))
62
63 def get_individual(self, name):
64 ns_id = name
65 if not utils.validate_uuid4(name):
66 for ns in self.list():
67 if name == ns['name']:
68 ns_id = ns['_id']
69 break
70 resp = self._http.get_cmd('{}/{}'.format(self._apiBase, ns_id))
71 #resp = self._http.get_cmd('{}/{}/nsd_content'.format(self._apiBase, ns_id))
72 #print yaml.safe_dump(resp)
73 if resp:
74 return resp
75 raise NotFound("ns {} not found".format(name))
76
77 def delete(self, name):
78 ns = self.get(name)
79 http_code, resp = self._http.delete_cmd('{}/{}'.format(self._apiBase,ns['_id']))
80 #print 'RESP: {}'.format(resp)
81 if http_code == 202:
82 print 'Deletion in progress'
83 elif http_code == 204:
84 print 'Deleted'
85 else:
86 raise ClientException("failed to delete ns {}: {}".format(name, resp))
87
88 def create(self, nsd_name, nsr_name, account, config=None,
89 ssh_keys=None, description='default description',
90 admin_status='ENABLED'):
91
92 nsd = self._client.nsd.get(nsd_name)
93
94 vim_account_id = {}
95
96 def get_vim_account_id(vim_account):
97 if vim_account_id.get(vim_account):
98 return vim_account_id[vim_account]
99
100 vim = self._client.vim.get(vim_account)
101 if vim is None:
102 raise NotFound("cannot find vim account '{}'".format(vim_account))
103 vim_account_id[vim_account] = vim['_id']
104 return vim['_id']
105
106 ns = {}
107 ns['nsdId'] = nsd['_id']
108 ns['nsName'] = nsr_name
109 ns['nsDescription'] = description
110 ns['vimAccountId'] = get_vim_account_id(account)
111 #ns['userdata'] = {}
112 #ns['userdata']['key1']='value1'
113 #ns['userdata']['key2']='value2'
114
115 if ssh_keys is not None:
116 # ssh_keys is comma separate list
117 # ssh_keys_format = []
118 # for key in ssh_keys.split(','):
119 # ssh_keys_format.append({'key-pair-ref': key})
120 #
121 # ns['ssh-authorized-key'] = ssh_keys_format
122 ns['ssh-authorized-key'] = []
123 for pubkeyfile in ssh_keys.split(','):
124 with open(pubkeyfile, 'r') as f:
125 ns['ssh-authorized-key'].append(f.read())
126 if config:
127 ns_config = yaml.load(config)
128 if "vim-network-name" in ns_config:
129 ns_config["vld"] = ns_config.pop("vim-network-name")
130 if "vld" in ns_config:
131 for vld in ns_config["vld"]:
132 if vld.get("vim-network-name"):
133 if isinstance(vld["vim-network-name"], dict):
134 vim_network_name_dict = {}
135 for vim_account, vim_net in vld["vim-network-name"].items():
136 vim_network_name_dict[get_vim_account_id(vim_account)] = vim_net
137 vld["vim-network-name"] = vim_network_name_dict
138 ns["vld"] = ns_config["vld"]
139 if "vnf" in ns_config:
140 for vnf in ns_config["vnf"]:
141 if vnf.get("vim_account"):
142 vnf["vimAccountId"] = get_vim_account_id(vnf.pop("vim_account"))
143
144 ns["vnf"] = ns_config["vnf"]
145
146 #print yaml.safe_dump(ns)
147 try:
148 self._apiResource = '/ns_instances_content'
149 self._apiBase = '{}{}{}'.format(self._apiName,
150 self._apiVersion, self._apiResource)
151 http_code, resp = self._http.post_cmd(endpoint=self._apiBase,
152 postfields_dict=ns)
153 if resp:
154 resp = json.loads(resp)
155 #print 'RESP: {}'.format(resp)
156 if not resp or 'id' not in resp:
157 raise ClientException('unexpected response from server: '.format(
158 resp))
159 else:
160 print resp['id']
161 except ClientException as exc:
162 message="failed to create ns: {} nsd: {}\nerror:\n{}".format(
163 nsr_name,
164 nsd_name,
165 exc.message)
166 raise ClientException(message)
167
168 def list_op(self, name, filter=None):
169 """Returns the list of operations of a NS
170 """
171 ns = self.get(name)
172 try:
173 self._apiResource = '/ns_lcm_op_occs'
174 self._apiBase = '{}{}{}'.format(self._apiName,
175 self._apiVersion, self._apiResource)
176 filter_string = ''
177 if filter:
178 filter_string = '&{}'.format(filter)
179 http_code, resp = self._http.get2_cmd('{}?nsInstanceId={}'.format(self._apiBase, ns['_id'],
180 filter_string) )
181 resp = json.loads(resp)
182 #print 'RESP: {}'.format(resp)
183 if http_code == 200:
184 return resp
185 else:
186 raise ClientException('{}'.format(resp['detail']))
187
188 except ClientException as exc:
189 message="failed to get operation list of NS {}:\nerror:\n{}".format(
190 name,
191 exc.message)
192 raise ClientException(message)
193
194 def get_op(self, operationId):
195 """Returns the status of an operation
196 """
197 try:
198 self._apiResource = '/ns_lcm_op_occs'
199 self._apiBase = '{}{}{}'.format(self._apiName,
200 self._apiVersion, self._apiResource)
201 http_code, resp = self._http.get2_cmd('{}/{}'.format(self._apiBase, operationId))
202 resp = json.loads(resp)
203 #print 'RESP: {}'.format(resp)
204 if http_code == 200:
205 return resp
206 else:
207 raise ClientException("{}".format(resp['detail']))
208 except ClientException as exc:
209 message="failed to get status of operation {}:\nerror:\n{}".format(
210 operationId,
211 exc.message)
212 raise ClientException(message)
213
214 def exec_op(self, name, op_name, op_data=None):
215 """Executes an operation on a NS
216 """
217 ns = self.get(name)
218 try:
219 self._apiResource = '/ns_instances'
220 self._apiBase = '{}{}{}'.format(self._apiName,
221 self._apiVersion, self._apiResource)
222 endpoint = '{}/{}/{}'.format(self._apiBase, ns['_id'], op_name)
223 #print 'OP_NAME: {}'.format(op_name)
224 #print 'OP_DATA: {}'.format(json.dumps(op_data))
225 http_code, resp = self._http.post_cmd(endpoint=endpoint, postfields_dict=op_data)
226 if resp:
227 resp = json.loads(resp)
228 #print 'RESP: {}'.format(resp)
229 if not resp or 'id' not in resp:
230 raise ClientException('unexpected response from server: '.format(
231 resp))
232 else:
233 print resp['id']
234 except ClientException as exc:
235 message="failed to exec operation {}:\nerror:\n{}".format(
236 name,
237 exc.message)
238 raise ClientException(message)
239
240 def create_alarm(self, alarm):
241 data = {}
242 data["create_alarm_request"] = {}
243 data["create_alarm_request"]["alarm_create_request"] = alarm
244 try:
245 http_code, resp = self._http.post_cmd(endpoint='/test/message/alarm_request',
246 postfields_dict=data)
247 if http_code in (200, 201, 202, 204):
248 #resp = json.loads(resp)
249 #print 'RESP: {}'.format(resp)
250 print 'Alarm created'
251 else:
252 raise ClientException('unexpected response from server: code: {}, resp: {}'.format(
253 http_code, resp))
254 except ClientException as exc:
255 message="failed to create alarm: alarm {}\nerror:\n{}".format(
256 alarm,
257 exc.message)
258 raise ClientException(message)
259
260 def delete_alarm(self, name):
261 data = {}
262 data["delete_alarm_request"] = {}
263 data["delete_alarm_request"]["alarm_delete_request"] = {}
264 data["delete_alarm_request"]["alarm_delete_request"]["alarm_uuid"] = name
265 try:
266 http_code, resp = self._http.post_cmd(endpoint='/test/message/alarm_request',
267 postfields_dict=data)
268 if http_code in (200, 201, 202, 204):
269 #resp = json.loads(resp)
270 #print 'RESP: {}'.format(resp)
271 print 'Alarm deleted'
272 else:
273 raise ClientException('unexpected response from server: code: {}, resp: {}'.format(
274 http_code, resp))
275 except ClientException as exc:
276 message="failed to delete alarm: alarm {}\nerror:\n{}".format(
277 alarm,
278 exc.message)
279 raise ClientException(message)
280
281 def export_metric(self, metric):
282 data = {}
283 data["read_metric_data_request"] = metric
284 try:
285 http_code, resp = self._http.post_cmd(endpoint='/test/message/metric_request',
286 postfields_dict=data)
287 if http_code in (200, 201, 202, 204):
288 #resp = json.loads(resp)
289 #print 'RESP: {}'.format(resp)
290 return 'Metric exported'
291 else:
292 raise ClientException('unexpected response from server: code: {}, resp: {}'.format(
293 http_code, resp))
294 except ClientException as exc:
295 message="failed to export metric: metric {}\nerror:\n{}".format(
296 metric,
297 exc.message)
298 raise ClientException(message)
299