new --force option for xxx-delete commands in sol005 client
[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, force=False):
78 ns = self.get(name)
79 querystring = ''
80 if force:
81 querystring = '?FORCE=True'
82 http_code, resp = self._http.delete_cmd('{}/{}{}'.format(self._apiBase,
83 ns['_id'], querystring))
84 if resp:
85 resp = json.loads(resp)
86 #print 'RESP: {}'.format(resp)
87 if http_code == 202:
88 print 'Deletion in progress'
89 elif http_code == 204:
90 print 'Deleted'
91 else:
92 raise ClientException("failed to delete ns {}: {}".format(name, resp))
93
94 def create(self, nsd_name, nsr_name, account, config=None,
95 ssh_keys=None, description='default description',
96 admin_status='ENABLED'):
97
98 nsd = self._client.nsd.get(nsd_name)
99
100 vim_account_id = {}
101
102 def get_vim_account_id(vim_account):
103 if vim_account_id.get(vim_account):
104 return vim_account_id[vim_account]
105
106 vim = self._client.vim.get(vim_account)
107 if vim is None:
108 raise NotFound("cannot find vim account '{}'".format(vim_account))
109 vim_account_id[vim_account] = vim['_id']
110 return vim['_id']
111
112 ns = {}
113 ns['nsdId'] = nsd['_id']
114 ns['nsName'] = nsr_name
115 ns['nsDescription'] = description
116 ns['vimAccountId'] = get_vim_account_id(account)
117 #ns['userdata'] = {}
118 #ns['userdata']['key1']='value1'
119 #ns['userdata']['key2']='value2'
120
121 if ssh_keys is not None:
122 # ssh_keys is comma separate list
123 # ssh_keys_format = []
124 # for key in ssh_keys.split(','):
125 # ssh_keys_format.append({'key-pair-ref': key})
126 #
127 # ns['ssh-authorized-key'] = ssh_keys_format
128 ns['ssh-authorized-key'] = []
129 for pubkeyfile in ssh_keys.split(','):
130 with open(pubkeyfile, 'r') as f:
131 ns['ssh-authorized-key'].append(f.read())
132 if config:
133 ns_config = yaml.load(config)
134 if "vim-network-name" in ns_config:
135 ns_config["vld"] = ns_config.pop("vim-network-name")
136 if "vld" in ns_config:
137 for vld in ns_config["vld"]:
138 if vld.get("vim-network-name"):
139 if isinstance(vld["vim-network-name"], dict):
140 vim_network_name_dict = {}
141 for vim_account, vim_net in vld["vim-network-name"].items():
142 vim_network_name_dict[get_vim_account_id(vim_account)] = vim_net
143 vld["vim-network-name"] = vim_network_name_dict
144 ns["vld"] = ns_config["vld"]
145 if "vnf" in ns_config:
146 for vnf in ns_config["vnf"]:
147 if vnf.get("vim_account"):
148 vnf["vimAccountId"] = get_vim_account_id(vnf.pop("vim_account"))
149
150 ns["vnf"] = ns_config["vnf"]
151
152 #print yaml.safe_dump(ns)
153 try:
154 self._apiResource = '/ns_instances_content'
155 self._apiBase = '{}{}{}'.format(self._apiName,
156 self._apiVersion, self._apiResource)
157 http_code, resp = self._http.post_cmd(endpoint=self._apiBase,
158 postfields_dict=ns)
159 if resp:
160 resp = json.loads(resp)
161 #print 'RESP: {}'.format(resp)
162 if not resp or 'id' not in resp:
163 raise ClientException('unexpected response from server: '.format(
164 resp))
165 else:
166 print resp['id']
167 except ClientException as exc:
168 message="failed to create ns: {} nsd: {}\nerror:\n{}".format(
169 nsr_name,
170 nsd_name,
171 exc.message)
172 raise ClientException(message)
173
174 def list_op(self, name, filter=None):
175 """Returns the list of operations of a NS
176 """
177 ns = self.get(name)
178 try:
179 self._apiResource = '/ns_lcm_op_occs'
180 self._apiBase = '{}{}{}'.format(self._apiName,
181 self._apiVersion, self._apiResource)
182 filter_string = ''
183 if filter:
184 filter_string = '&{}'.format(filter)
185 http_code, resp = self._http.get2_cmd('{}?nsInstanceId={}'.format(self._apiBase, ns['_id'],
186 filter_string) )
187 resp = json.loads(resp)
188 #print 'RESP: {}'.format(resp)
189 if http_code == 200:
190 return resp
191 else:
192 raise ClientException('{}'.format(resp['detail']))
193
194 except ClientException as exc:
195 message="failed to get operation list of NS {}:\nerror:\n{}".format(
196 name,
197 exc.message)
198 raise ClientException(message)
199
200 def get_op(self, operationId):
201 """Returns the status of an operation
202 """
203 try:
204 self._apiResource = '/ns_lcm_op_occs'
205 self._apiBase = '{}{}{}'.format(self._apiName,
206 self._apiVersion, self._apiResource)
207 http_code, resp = self._http.get2_cmd('{}/{}'.format(self._apiBase, operationId))
208 resp = json.loads(resp)
209 #print 'RESP: {}'.format(resp)
210 if http_code == 200:
211 return resp
212 else:
213 raise ClientException("{}".format(resp['detail']))
214 except ClientException as exc:
215 message="failed to get status of operation {}:\nerror:\n{}".format(
216 operationId,
217 exc.message)
218 raise ClientException(message)
219
220 def exec_op(self, name, op_name, op_data=None):
221 """Executes an operation on a NS
222 """
223 ns = self.get(name)
224 try:
225 self._apiResource = '/ns_instances'
226 self._apiBase = '{}{}{}'.format(self._apiName,
227 self._apiVersion, self._apiResource)
228 endpoint = '{}/{}/{}'.format(self._apiBase, ns['_id'], op_name)
229 #print 'OP_NAME: {}'.format(op_name)
230 #print 'OP_DATA: {}'.format(json.dumps(op_data))
231 http_code, resp = self._http.post_cmd(endpoint=endpoint, postfields_dict=op_data)
232 if resp:
233 resp = json.loads(resp)
234 #print 'RESP: {}'.format(resp)
235 if not resp or 'id' not in resp:
236 raise ClientException('unexpected response from server: '.format(
237 resp))
238 else:
239 print resp['id']
240 except ClientException as exc:
241 message="failed to exec operation {}:\nerror:\n{}".format(
242 name,
243 exc.message)
244 raise ClientException(message)
245
246 def create_alarm(self, alarm):
247 data = {}
248 data["create_alarm_request"] = {}
249 data["create_alarm_request"]["alarm_create_request"] = alarm
250 try:
251 http_code, resp = self._http.post_cmd(endpoint='/test/message/alarm_request',
252 postfields_dict=data)
253 if http_code in (200, 201, 202, 204):
254 #resp = json.loads(resp)
255 #print 'RESP: {}'.format(resp)
256 print 'Alarm created'
257 else:
258 raise ClientException('unexpected response from server: code: {}, resp: {}'.format(
259 http_code, resp))
260 except ClientException as exc:
261 message="failed to create alarm: alarm {}\nerror:\n{}".format(
262 alarm,
263 exc.message)
264 raise ClientException(message)
265
266 def delete_alarm(self, name):
267 data = {}
268 data["delete_alarm_request"] = {}
269 data["delete_alarm_request"]["alarm_delete_request"] = {}
270 data["delete_alarm_request"]["alarm_delete_request"]["alarm_uuid"] = name
271 try:
272 http_code, resp = self._http.post_cmd(endpoint='/test/message/alarm_request',
273 postfields_dict=data)
274 if http_code in (200, 201, 202, 204):
275 #resp = json.loads(resp)
276 #print 'RESP: {}'.format(resp)
277 print 'Alarm deleted'
278 else:
279 raise ClientException('unexpected response from server: code: {}, resp: {}'.format(
280 http_code, resp))
281 except ClientException as exc:
282 message="failed to delete alarm: alarm {}\nerror:\n{}".format(
283 alarm,
284 exc.message)
285 raise ClientException(message)
286
287 def export_metric(self, metric):
288 data = {}
289 data["read_metric_data_request"] = metric
290 try:
291 http_code, resp = self._http.post_cmd(endpoint='/test/message/metric_request',
292 postfields_dict=data)
293 if http_code in (200, 201, 202, 204):
294 #resp = json.loads(resp)
295 #print 'RESP: {}'.format(resp)
296 return 'Metric exported'
297 else:
298 raise ClientException('unexpected response from server: code: {}, resp: {}'.format(
299 http_code, resp))
300 except ClientException as exc:
301 message="failed to export metric: metric {}\nerror:\n{}".format(
302 metric,
303 exc.message)
304 raise ClientException(message)
305