blob: 7c0bc0b81a20ffb058f7b6ca31129028538448d5 [file] [log] [blame]
tierno59d22d22018-09-25 18:10:19 +02001# -*- coding: utf-8 -*-
2
tierno2e215512018-11-28 09:37:52 +00003##
4# Copyright 2018 Telefonica S.A.
5#
6# Licensed under the Apache License, Version 2.0 (the "License"); you may
7# not use this file except in compliance with the License. You may obtain
8# a copy of the License at
9#
10# http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing, software
13# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
14# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
15# License for the specific language governing permissions and limitations
16# under the License.
17##
18
tierno59d22d22018-09-25 18:10:19 +020019import logging
20import logging.handlers
tierno8069ce52019-08-28 15:34:33 +000021from osm_lcm import ROclient
22from osm_lcm.lcm_utils import LcmException, LcmBase
tierno59d22d22018-09-25 18:10:19 +020023from osm_common.dbbase import DbException
24from copy import deepcopy
25
26__author__ = "Alfonso Tierno"
27
28
29class VimLcm(LcmBase):
tierno17a612f2018-10-23 11:30:42 +020030 # values that are encrypted at vim config because they are passwords
tierno2d9f6f52019-08-01 16:32:56 +000031 vim_config_encrypted = {"1.1": ("admin_password", "nsx_password", "vcenter_password"),
32 "default": ("admin_password", "nsx_password", "vcenter_password", "vrops_password")}
tierno59d22d22018-09-25 18:10:19 +020033
34 def __init__(self, db, msg, fs, lcm_tasks, ro_config, loop):
35 """
36 Init, Connect to database, filesystem storage, and messaging
37 :param config: two level dictionary with configuration. Top level should contain 'database', 'storage',
38 :return: None
39 """
40
41 self.logger = logging.getLogger('lcm.vim')
42 self.loop = loop
43 self.lcm_tasks = lcm_tasks
44 self.ro_config = ro_config
45
46 super().__init__(db, msg, fs, self.logger)
47
48 async def create(self, vim_content, order_id):
kuuse6a470c62019-07-10 13:52:45 +020049
50 # HA tasks and backward compatibility:
51 # If 'vim_content' does not include 'op_id', we a running a legacy NBI version.
52 # In such a case, HA is not supported by NBI, 'op_id' is None, and lock_HA() will do nothing.
53 # Register 'create' task here for related future HA operations
54 op_id = vim_content.pop('op_id', None)
55 if not self.lcm_tasks.lock_HA('vim', 'create', op_id):
56 return
57
tierno59d22d22018-09-25 18:10:19 +020058 vim_id = vim_content["_id"]
tierno2ef21172019-07-05 11:54:25 +000059 vim_content.pop("op_id", None)
tierno59d22d22018-09-25 18:10:19 +020060 logging_text = "Task vim_create={} ".format(vim_id)
61 self.logger.debug(logging_text + "Enter")
kuuse6a470c62019-07-10 13:52:45 +020062
tierno59d22d22018-09-25 18:10:19 +020063 db_vim = None
64 db_vim_update = {}
65 exc = None
66 RO_sdn_id = None
kuuse6a470c62019-07-10 13:52:45 +020067 operationState_HA = ''
68 detailed_status_HA = ''
tierno59d22d22018-09-25 18:10:19 +020069 try:
70 step = "Getting vim-id='{}' from db".format(vim_id)
71 db_vim = self.db.get_one("vim_accounts", {"_id": vim_id})
tierno59d22d22018-09-25 18:10:19 +020072 if vim_content.get("config") and vim_content["config"].get("sdn-controller"):
73 step = "Getting sdn-controller-id='{}' from db".format(vim_content["config"]["sdn-controller"])
74 db_sdn = self.db.get_one("sdns", {"_id": vim_content["config"]["sdn-controller"]})
kuuse6a470c62019-07-10 13:52:45 +020075
76 # If the VIM account has an associated SDN account, also
77 # wait for any previous tasks in process for the SDN
78 await self.lcm_tasks.waitfor_related_HA('sdn', 'ANY', db_sdn["_id"])
79
tierno59d22d22018-09-25 18:10:19 +020080 if db_sdn.get("_admin") and db_sdn["_admin"].get("deployed") and db_sdn["_admin"]["deployed"].get("RO"):
81 RO_sdn_id = db_sdn["_admin"]["deployed"]["RO"]
82 else:
83 raise LcmException("sdn-controller={} is not available. Not deployed at RO".format(
84 vim_content["config"]["sdn-controller"]))
85
86 step = "Creating vim at RO"
tiernobaa51102018-12-14 13:16:18 +000087 db_vim_update["_admin.deployed.RO"] = None
tierno59d22d22018-09-25 18:10:19 +020088 db_vim_update["_admin.detailed-status"] = step
89 self.update_db_2("vim_accounts", vim_id, db_vim_update)
90 RO = ROclient.ROClient(self.loop, **self.ro_config)
91 vim_RO = deepcopy(vim_content)
92 vim_RO.pop("_id", None)
93 vim_RO.pop("_admin", None)
tierno17a612f2018-10-23 11:30:42 +020094 schema_version = vim_RO.pop("schema_version", None)
tierno59d22d22018-09-25 18:10:19 +020095 vim_RO.pop("schema_type", None)
96 vim_RO.pop("vim_tenant_name", None)
97 vim_RO["type"] = vim_RO.pop("vim_type")
98 vim_RO.pop("vim_user", None)
99 vim_RO.pop("vim_password", None)
100 if RO_sdn_id:
101 vim_RO["config"]["sdn-controller"] = RO_sdn_id
102 desc = await RO.create("vim", descriptor=vim_RO)
103 RO_vim_id = desc["uuid"]
104 db_vim_update["_admin.deployed.RO"] = RO_vim_id
tiernoe37b57d2018-12-11 17:22:51 +0000105 self.logger.debug(logging_text + "VIM created at RO_vim_id={}".format(RO_vim_id))
tierno59d22d22018-09-25 18:10:19 +0200106
107 step = "Creating vim_account at RO"
108 db_vim_update["_admin.detailed-status"] = step
109 self.update_db_2("vim_accounts", vim_id, db_vim_update)
110
tierno17a612f2018-10-23 11:30:42 +0200111 if vim_content.get("vim_password"):
112 vim_content["vim_password"] = self.db.decrypt(vim_content["vim_password"],
113 schema_version=schema_version,
114 salt=vim_id)
tierno59d22d22018-09-25 18:10:19 +0200115 vim_account_RO = {"vim_tenant_name": vim_content["vim_tenant_name"],
116 "vim_username": vim_content["vim_user"],
117 "vim_password": vim_content["vim_password"]
118 }
119 if vim_RO.get("config"):
120 vim_account_RO["config"] = vim_RO["config"]
121 if "sdn-controller" in vim_account_RO["config"]:
122 del vim_account_RO["config"]["sdn-controller"]
123 if "sdn-port-mapping" in vim_account_RO["config"]:
124 del vim_account_RO["config"]["sdn-port-mapping"]
tierno2d9f6f52019-08-01 16:32:56 +0000125 vim_config_encrypted_keys = self.vim_config_encrypted.get(schema_version) or \
126 self.vim_config_encrypted.get("default")
127 for p in vim_config_encrypted_keys:
tierno17a612f2018-10-23 11:30:42 +0200128 if vim_account_RO["config"].get(p):
129 vim_account_RO["config"][p] = self.db.decrypt(vim_account_RO["config"][p],
130 schema_version=schema_version,
131 salt=vim_id)
132
tiernoe37b57d2018-12-11 17:22:51 +0000133 desc = await RO.attach("vim_account", RO_vim_id, descriptor=vim_account_RO)
tierno59d22d22018-09-25 18:10:19 +0200134 db_vim_update["_admin.deployed.RO-account"] = desc["uuid"]
135 db_vim_update["_admin.operationalState"] = "ENABLED"
136 db_vim_update["_admin.detailed-status"] = "Done"
kuuse6a470c62019-07-10 13:52:45 +0200137 # Mark the VIM 'create' HA task as successful
138 operationState_HA = 'COMPLETED'
139 detailed_status_HA = 'Done'
tierno59d22d22018-09-25 18:10:19 +0200140
141 # await asyncio.sleep(15) # TODO remove. This is for test
tiernoe37b57d2018-12-11 17:22:51 +0000142 self.logger.debug(logging_text + "Exit Ok VIM account created at RO_vim_account_id={}".format(desc["uuid"]))
tierno59d22d22018-09-25 18:10:19 +0200143 return
144
145 except (ROclient.ROClientException, DbException) as e:
146 self.logger.error(logging_text + "Exit Exception {}".format(e))
147 exc = e
148 except Exception as e:
149 self.logger.critical(logging_text + "Exit Exception {}".format(e), exc_info=True)
150 exc = e
151 finally:
152 if exc and db_vim:
153 db_vim_update["_admin.operationalState"] = "ERROR"
154 db_vim_update["_admin.detailed-status"] = "ERROR {}: {}".format(step, exc)
kuuse6a470c62019-07-10 13:52:45 +0200155 # Mark the VIM 'create' HA task as erroneous
156 operationState_HA = 'FAILED'
157 detailed_status_HA = "ERROR {}: {}".format(step, exc)
tiernobaa51102018-12-14 13:16:18 +0000158 try:
159 if db_vim_update:
160 self.update_db_2("vim_accounts", vim_id, db_vim_update)
kuuse6a470c62019-07-10 13:52:45 +0200161 # Register the VIM 'create' HA task either
162 # succesful or erroneous, or do nothing (if legacy NBI)
163 self.lcm_tasks.register_HA('vim', 'create', op_id,
164 operationState=operationState_HA,
165 detailed_status=detailed_status_HA)
tiernobaa51102018-12-14 13:16:18 +0000166 except DbException as e:
167 self.logger.error(logging_text + "Cannot update database: {}".format(e))
168
tierno59d22d22018-09-25 18:10:19 +0200169 self.lcm_tasks.remove("vim_account", vim_id, order_id)
170
171 async def edit(self, vim_content, order_id):
kuuse6a470c62019-07-10 13:52:45 +0200172
173 # HA tasks and backward compatibility:
174 # If 'vim_content' does not include 'op_id', we a running a legacy NBI version.
175 # In such a case, HA is not supported by NBI, and the HA check always returns True
176 op_id = vim_content.pop('op_id', None)
177 if not self.lcm_tasks.lock_HA('vim', 'edit', op_id):
178 return
179
tierno59d22d22018-09-25 18:10:19 +0200180 vim_id = vim_content["_id"]
tierno2ef21172019-07-05 11:54:25 +0000181 vim_content.pop("op_id", None)
tierno59d22d22018-09-25 18:10:19 +0200182 logging_text = "Task vim_edit={} ".format(vim_id)
183 self.logger.debug(logging_text + "Enter")
kuuse6a470c62019-07-10 13:52:45 +0200184
tierno59d22d22018-09-25 18:10:19 +0200185 db_vim = None
186 exc = None
187 RO_sdn_id = None
188 RO_vim_id = None
189 db_vim_update = {}
kuuse6a470c62019-07-10 13:52:45 +0200190 operationState_HA = ''
191 detailed_status_HA = ''
tierno59d22d22018-09-25 18:10:19 +0200192 step = "Getting vim-id='{}' from db".format(vim_id)
193 try:
kuuse6a470c62019-07-10 13:52:45 +0200194 # wait for any previous tasks in process
195 await self.lcm_tasks.waitfor_related_HA('vim', 'edit', op_id)
tierno59d22d22018-09-25 18:10:19 +0200196
kuuse6a470c62019-07-10 13:52:45 +0200197 db_vim = self.db.get_one("vim_accounts", {"_id": vim_id})
tierno59d22d22018-09-25 18:10:19 +0200198
199 if db_vim.get("_admin") and db_vim["_admin"].get("deployed") and db_vim["_admin"]["deployed"].get("RO"):
200 if vim_content.get("config") and vim_content["config"].get("sdn-controller"):
201 step = "Getting sdn-controller-id='{}' from db".format(vim_content["config"]["sdn-controller"])
202 db_sdn = self.db.get_one("sdns", {"_id": vim_content["config"]["sdn-controller"]})
203
kuuse6a470c62019-07-10 13:52:45 +0200204 # If the VIM account has an associated SDN account, also
205 # wait for any previous tasks in process for the SDN
206 await self.lcm_tasks.waitfor_related_HA('sdn', 'ANY', db_sdn["_id"])
tierno59d22d22018-09-25 18:10:19 +0200207
208 if db_sdn.get("_admin") and db_sdn["_admin"].get("deployed") and db_sdn["_admin"]["deployed"].get(
209 "RO"):
210 RO_sdn_id = db_sdn["_admin"]["deployed"]["RO"]
211 else:
212 raise LcmException("sdn-controller={} is not available. Not deployed at RO".format(
213 vim_content["config"]["sdn-controller"]))
214
215 RO_vim_id = db_vim["_admin"]["deployed"]["RO"]
216 step = "Editing vim at RO"
217 RO = ROclient.ROClient(self.loop, **self.ro_config)
218 vim_RO = deepcopy(vim_content)
219 vim_RO.pop("_id", None)
220 vim_RO.pop("_admin", None)
tierno17a612f2018-10-23 11:30:42 +0200221 schema_version = vim_RO.pop("schema_version", None)
tierno59d22d22018-09-25 18:10:19 +0200222 vim_RO.pop("schema_type", None)
223 vim_RO.pop("vim_tenant_name", None)
224 if "vim_type" in vim_RO:
225 vim_RO["type"] = vim_RO.pop("vim_type")
226 vim_RO.pop("vim_user", None)
227 vim_RO.pop("vim_password", None)
228 if RO_sdn_id:
229 vim_RO["config"]["sdn-controller"] = RO_sdn_id
230 # TODO make a deep update of sdn-port-mapping
231 if vim_RO:
232 await RO.edit("vim", RO_vim_id, descriptor=vim_RO)
233
234 step = "Editing vim-account at RO tenant"
235 vim_account_RO = {}
236 if "config" in vim_content:
237 if "sdn-controller" in vim_content["config"]:
238 del vim_content["config"]["sdn-controller"]
239 if "sdn-port-mapping" in vim_content["config"]:
240 del vim_content["config"]["sdn-port-mapping"]
241 if not vim_content["config"]:
242 del vim_content["config"]
tierno17a612f2018-10-23 11:30:42 +0200243 if "vim_tenant_name" in vim_content:
244 vim_account_RO["vim_tenant_name"] = vim_content["vim_tenant_name"]
245 if "vim_password" in vim_content:
246 vim_account_RO["vim_password"] = vim_content["vim_password"]
247 if vim_content.get("vim_password"):
248 vim_account_RO["vim_password"] = self.db.decrypt(vim_content["vim_password"],
249 schema_version=schema_version,
250 salt=vim_id)
251 if "config" in vim_content:
252 vim_account_RO["config"] = vim_content["config"]
253 if vim_content.get("config"):
tierno2d9f6f52019-08-01 16:32:56 +0000254 vim_config_encrypted_keys = self.vim_config_encrypted.get(schema_version) or \
255 self.vim_config_encrypted.get("default")
256 for p in vim_config_encrypted_keys:
tierno17a612f2018-10-23 11:30:42 +0200257 if vim_content["config"].get(p):
258 vim_account_RO["config"][p] = self.db.decrypt(vim_content["config"][p],
259 schema_version=schema_version,
260 salt=vim_id)
261
tierno59d22d22018-09-25 18:10:19 +0200262 if "vim_user" in vim_content:
263 vim_content["vim_username"] = vim_content["vim_user"]
264 # vim_account must be edited always even if empty in order to ensure changes are translated to RO
265 # vim_thread. RO will remove and relaunch a new thread for this vim_account
266 await RO.edit("vim_account", RO_vim_id, descriptor=vim_account_RO)
267 db_vim_update["_admin.operationalState"] = "ENABLED"
kuuse6a470c62019-07-10 13:52:45 +0200268 # Mark the VIM 'edit' HA task as successful
269 operationState_HA = 'COMPLETED'
270 detailed_status_HA = 'Done'
tierno59d22d22018-09-25 18:10:19 +0200271
272 self.logger.debug(logging_text + "Exit Ok RO_vim_id={}".format(RO_vim_id))
273 return
274
275 except (ROclient.ROClientException, DbException) as e:
276 self.logger.error(logging_text + "Exit Exception {}".format(e))
277 exc = e
278 except Exception as e:
279 self.logger.critical(logging_text + "Exit Exception {}".format(e), exc_info=True)
280 exc = e
281 finally:
282 if exc and db_vim:
283 db_vim_update["_admin.operationalState"] = "ERROR"
284 db_vim_update["_admin.detailed-status"] = "ERROR {}: {}".format(step, exc)
kuuse6a470c62019-07-10 13:52:45 +0200285 # Mark the VIM 'edit' HA task as erroneous
286 operationState_HA = 'FAILED'
287 detailed_status_HA = "ERROR {}: {}".format(step, exc)
tiernobaa51102018-12-14 13:16:18 +0000288 try:
289 if db_vim_update:
290 self.update_db_2("vim_accounts", vim_id, db_vim_update)
kuuse6a470c62019-07-10 13:52:45 +0200291 # Register the VIM 'edit' HA task either
292 # succesful or erroneous, or do nothing (if legacy NBI)
293 self.lcm_tasks.register_HA('vim', 'edit', op_id,
294 operationState=operationState_HA,
295 detailed_status=detailed_status_HA)
tiernobaa51102018-12-14 13:16:18 +0000296 except DbException as e:
297 self.logger.error(logging_text + "Cannot update database: {}".format(e))
298
tierno59d22d22018-09-25 18:10:19 +0200299 self.lcm_tasks.remove("vim_account", vim_id, order_id)
300
kuuse6a470c62019-07-10 13:52:45 +0200301 async def delete(self, vim_content, order_id):
302
303 # HA tasks and backward compatibility:
304 # If 'vim_content' does not include 'op_id', we a running a legacy NBI version.
305 # In such a case, HA is not supported by NBI, and the HA check always returns True
306 op_id = vim_content.pop('op_id', None)
307 if not self.lcm_tasks.lock_HA('vim', 'delete', op_id):
308 return
309
310 vim_id = vim_content["_id"]
tierno59d22d22018-09-25 18:10:19 +0200311 logging_text = "Task vim_delete={} ".format(vim_id)
312 self.logger.debug(logging_text + "Enter")
kuuse6a470c62019-07-10 13:52:45 +0200313
tierno59d22d22018-09-25 18:10:19 +0200314 db_vim = None
315 db_vim_update = {}
316 exc = None
kuuse6a470c62019-07-10 13:52:45 +0200317 operationState_HA = ''
318 detailed_status_HA = ''
tierno59d22d22018-09-25 18:10:19 +0200319 step = "Getting vim from db"
320 try:
kuuse6a470c62019-07-10 13:52:45 +0200321 # wait for any previous tasks in process
322 await self.lcm_tasks.waitfor_related_HA('vim', 'delete', op_id)
323
tierno59d22d22018-09-25 18:10:19 +0200324 db_vim = self.db.get_one("vim_accounts", {"_id": vim_id})
325 if db_vim.get("_admin") and db_vim["_admin"].get("deployed") and db_vim["_admin"]["deployed"].get("RO"):
326 RO_vim_id = db_vim["_admin"]["deployed"]["RO"]
327 RO = ROclient.ROClient(self.loop, **self.ro_config)
328 step = "Detaching vim from RO tenant"
329 try:
tiernoe37b57d2018-12-11 17:22:51 +0000330 await RO.detach("vim_account", RO_vim_id)
tierno59d22d22018-09-25 18:10:19 +0200331 except ROclient.ROClientException as e:
332 if e.http_code == 404: # not found
333 self.logger.debug(logging_text + "RO_vim_id={} already detached".format(RO_vim_id))
334 else:
335 raise
336
337 step = "Deleting vim from RO"
338 try:
339 await RO.delete("vim", RO_vim_id)
340 except ROclient.ROClientException as e:
341 if e.http_code == 404: # not found
342 self.logger.debug(logging_text + "RO_vim_id={} already deleted".format(RO_vim_id))
343 else:
344 raise
345 else:
346 # nothing to delete
kuuse6a470c62019-07-10 13:52:45 +0200347 self.logger.error(logging_text + "Nothing to remove at RO")
tierno59d22d22018-09-25 18:10:19 +0200348 self.db.del_one("vim_accounts", {"_id": vim_id})
tiernobaa51102018-12-14 13:16:18 +0000349 db_vim = None
tierno59d22d22018-09-25 18:10:19 +0200350 self.logger.debug(logging_text + "Exit Ok")
351 return
352
353 except (ROclient.ROClientException, DbException) as e:
354 self.logger.error(logging_text + "Exit Exception {}".format(e))
355 exc = e
356 except Exception as e:
357 self.logger.critical(logging_text + "Exit Exception {}".format(e), exc_info=True)
358 exc = e
359 finally:
360 self.lcm_tasks.remove("vim_account", vim_id, order_id)
361 if exc and db_vim:
362 db_vim_update["_admin.operationalState"] = "ERROR"
363 db_vim_update["_admin.detailed-status"] = "ERROR {}: {}".format(step, exc)
kuuse6a470c62019-07-10 13:52:45 +0200364 # Mark the VIM 'delete' HA task as erroneous
365 operationState_HA = 'FAILED'
366 detailed_status_HA = "ERROR {}: {}".format(step, exc)
367 self.lcm_tasks.register_HA('vim', 'delete', op_id,
368 operationState=operationState_HA,
369 detailed_status=detailed_status_HA)
tiernobaa51102018-12-14 13:16:18 +0000370 try:
371 if db_vim and db_vim_update:
372 self.update_db_2("vim_accounts", vim_id, db_vim_update)
kuuse6a470c62019-07-10 13:52:45 +0200373 # If the VIM 'delete' HA task was succesful, the DB entry has been deleted,
374 # which means that there is nowhere to register this task, so do nothing here.
tiernobaa51102018-12-14 13:16:18 +0000375 except DbException as e:
376 self.logger.error(logging_text + "Cannot update database: {}".format(e))
tierno59d22d22018-09-25 18:10:19 +0200377 self.lcm_tasks.remove("vim_account", vim_id, order_id)
378
379
tiernoe37b57d2018-12-11 17:22:51 +0000380class WimLcm(LcmBase):
381 # values that are encrypted at wim config because they are passwords
382 wim_config_encrypted = ()
383
384 def __init__(self, db, msg, fs, lcm_tasks, ro_config, loop):
385 """
386 Init, Connect to database, filesystem storage, and messaging
387 :param config: two level dictionary with configuration. Top level should contain 'database', 'storage',
388 :return: None
389 """
390
391 self.logger = logging.getLogger('lcm.vim')
392 self.loop = loop
393 self.lcm_tasks = lcm_tasks
394 self.ro_config = ro_config
395
396 super().__init__(db, msg, fs, self.logger)
397
398 async def create(self, wim_content, order_id):
kuuse6a470c62019-07-10 13:52:45 +0200399
400 # HA tasks and backward compatibility:
401 # If 'wim_content' does not include 'op_id', we a running a legacy NBI version.
402 # In such a case, HA is not supported by NBI, 'op_id' is None, and lock_HA() will do nothing.
403 # Register 'create' task here for related future HA operations
404 op_id = wim_content.pop('op_id', None)
405 self.lcm_tasks.lock_HA('wim', 'create', op_id)
406
tiernoe37b57d2018-12-11 17:22:51 +0000407 wim_id = wim_content["_id"]
tierno2ef21172019-07-05 11:54:25 +0000408 wim_content.pop("op_id", None)
tiernoe37b57d2018-12-11 17:22:51 +0000409 logging_text = "Task wim_create={} ".format(wim_id)
410 self.logger.debug(logging_text + "Enter")
kuuse6a470c62019-07-10 13:52:45 +0200411
tiernoe37b57d2018-12-11 17:22:51 +0000412 db_wim = None
413 db_wim_update = {}
414 exc = None
kuuse6a470c62019-07-10 13:52:45 +0200415 operationState_HA = ''
416 detailed_status_HA = ''
tiernoe37b57d2018-12-11 17:22:51 +0000417 try:
418 step = "Getting wim-id='{}' from db".format(wim_id)
419 db_wim = self.db.get_one("wim_accounts", {"_id": wim_id})
420 db_wim_update["_admin.deployed.RO"] = None
421
422 step = "Creating wim at RO"
423 db_wim_update["_admin.detailed-status"] = step
424 self.update_db_2("wim_accounts", wim_id, db_wim_update)
425 RO = ROclient.ROClient(self.loop, **self.ro_config)
426 wim_RO = deepcopy(wim_content)
427 wim_RO.pop("_id", None)
428 wim_RO.pop("_admin", None)
429 schema_version = wim_RO.pop("schema_version", None)
430 wim_RO.pop("schema_type", None)
431 wim_RO.pop("wim_tenant_name", None)
432 wim_RO["type"] = wim_RO.pop("wim_type")
433 wim_RO.pop("wim_user", None)
434 wim_RO.pop("wim_password", None)
435 desc = await RO.create("wim", descriptor=wim_RO)
436 RO_wim_id = desc["uuid"]
437 db_wim_update["_admin.deployed.RO"] = RO_wim_id
438 self.logger.debug(logging_text + "WIM created at RO_wim_id={}".format(RO_wim_id))
439
440 step = "Creating wim_account at RO"
441 db_wim_update["_admin.detailed-status"] = step
442 self.update_db_2("wim_accounts", wim_id, db_wim_update)
443
444 if wim_content.get("wim_password"):
445 wim_content["wim_password"] = self.db.decrypt(wim_content["wim_password"],
446 schema_version=schema_version,
447 salt=wim_id)
448 wim_account_RO = {"name": wim_content["name"],
449 "user": wim_content["user"],
450 "password": wim_content["password"]
451 }
452 if wim_RO.get("config"):
453 wim_account_RO["config"] = wim_RO["config"]
454 if "wim_port_mapping" in wim_account_RO["config"]:
455 del wim_account_RO["config"]["wim_port_mapping"]
456 for p in self.wim_config_encrypted:
457 if wim_account_RO["config"].get(p):
458 wim_account_RO["config"][p] = self.db.decrypt(wim_account_RO["config"][p],
459 schema_version=schema_version,
460 salt=wim_id)
461
462 desc = await RO.attach("wim_account", RO_wim_id, descriptor=wim_account_RO)
463 db_wim_update["_admin.deployed.RO-account"] = desc["uuid"]
464 db_wim_update["_admin.operationalState"] = "ENABLED"
465 db_wim_update["_admin.detailed-status"] = "Done"
kuuse6a470c62019-07-10 13:52:45 +0200466 # Mark the WIM 'create' HA task as successful
467 operationState_HA = 'COMPLETED'
468 detailed_status_HA = 'Done'
tiernoe37b57d2018-12-11 17:22:51 +0000469
470 self.logger.debug(logging_text + "Exit Ok WIM account created at RO_wim_account_id={}".format(desc["uuid"]))
471 return
472
473 except (ROclient.ROClientException, DbException) as e:
474 self.logger.error(logging_text + "Exit Exception {}".format(e))
475 exc = e
476 except Exception as e:
477 self.logger.critical(logging_text + "Exit Exception {}".format(e), exc_info=True)
478 exc = e
479 finally:
480 if exc and db_wim:
481 db_wim_update["_admin.operationalState"] = "ERROR"
482 db_wim_update["_admin.detailed-status"] = "ERROR {}: {}".format(step, exc)
kuuse6a470c62019-07-10 13:52:45 +0200483 # Mark the WIM 'create' HA task as erroneous
484 operationState_HA = 'FAILED'
485 detailed_status_HA = "ERROR {}: {}".format(step, exc)
tiernobaa51102018-12-14 13:16:18 +0000486 try:
487 if db_wim_update:
488 self.update_db_2("wim_accounts", wim_id, db_wim_update)
kuuse6a470c62019-07-10 13:52:45 +0200489 # Register the WIM 'create' HA task either
490 # succesful or erroneous, or do nothing (if legacy NBI)
491 self.lcm_tasks.register_HA('wim', 'create', op_id,
492 operationState=operationState_HA,
493 detailed_status=detailed_status_HA)
tiernobaa51102018-12-14 13:16:18 +0000494 except DbException as e:
495 self.logger.error(logging_text + "Cannot update database: {}".format(e))
tiernoe37b57d2018-12-11 17:22:51 +0000496 self.lcm_tasks.remove("wim_account", wim_id, order_id)
497
498 async def edit(self, wim_content, order_id):
kuuse6a470c62019-07-10 13:52:45 +0200499
500 # HA tasks and backward compatibility:
501 # If 'wim_content' does not include 'op_id', we a running a legacy NBI version.
502 # In such a case, HA is not supported by NBI, and the HA check always returns True
503 op_id = wim_content.pop('op_id', None)
504 if not self.lcm_tasks.lock_HA('wim', 'edit', op_id):
505 return
506
tiernoe37b57d2018-12-11 17:22:51 +0000507 wim_id = wim_content["_id"]
tierno2ef21172019-07-05 11:54:25 +0000508 wim_content.pop("op_id", None)
tiernoe37b57d2018-12-11 17:22:51 +0000509 logging_text = "Task wim_edit={} ".format(wim_id)
510 self.logger.debug(logging_text + "Enter")
kuuse6a470c62019-07-10 13:52:45 +0200511
tiernoe37b57d2018-12-11 17:22:51 +0000512 db_wim = None
513 exc = None
514 RO_wim_id = None
515 db_wim_update = {}
516 step = "Getting wim-id='{}' from db".format(wim_id)
kuuse6a470c62019-07-10 13:52:45 +0200517 operationState_HA = ''
518 detailed_status_HA = ''
tiernoe37b57d2018-12-11 17:22:51 +0000519 try:
kuuse6a470c62019-07-10 13:52:45 +0200520 # wait for any previous tasks in process
521 await self.lcm_tasks.waitfor_related_HA('wim', 'edit', op_id)
tiernoe37b57d2018-12-11 17:22:51 +0000522
kuuse6a470c62019-07-10 13:52:45 +0200523 db_wim = self.db.get_one("wim_accounts", {"_id": wim_id})
tiernoe37b57d2018-12-11 17:22:51 +0000524
525 if db_wim.get("_admin") and db_wim["_admin"].get("deployed") and db_wim["_admin"]["deployed"].get("RO"):
526
527 RO_wim_id = db_wim["_admin"]["deployed"]["RO"]
528 step = "Editing wim at RO"
529 RO = ROclient.ROClient(self.loop, **self.ro_config)
530 wim_RO = deepcopy(wim_content)
531 wim_RO.pop("_id", None)
532 wim_RO.pop("_admin", None)
533 schema_version = wim_RO.pop("schema_version", None)
534 wim_RO.pop("schema_type", None)
535 wim_RO.pop("wim_tenant_name", None)
536 if "wim_type" in wim_RO:
537 wim_RO["type"] = wim_RO.pop("wim_type")
538 wim_RO.pop("wim_user", None)
539 wim_RO.pop("wim_password", None)
540 # TODO make a deep update of wim_port_mapping
541 if wim_RO:
542 await RO.edit("wim", RO_wim_id, descriptor=wim_RO)
543
544 step = "Editing wim-account at RO tenant"
545 wim_account_RO = {}
546 if "config" in wim_content:
547 if "wim_port_mapping" in wim_content["config"]:
548 del wim_content["config"]["wim_port_mapping"]
549 if not wim_content["config"]:
550 del wim_content["config"]
551 if "wim_tenant_name" in wim_content:
552 wim_account_RO["wim_tenant_name"] = wim_content["wim_tenant_name"]
553 if "wim_password" in wim_content:
554 wim_account_RO["wim_password"] = wim_content["wim_password"]
555 if wim_content.get("wim_password"):
556 wim_account_RO["wim_password"] = self.db.decrypt(wim_content["wim_password"],
557 schema_version=schema_version,
558 salt=wim_id)
559 if "config" in wim_content:
560 wim_account_RO["config"] = wim_content["config"]
561 if wim_content.get("config"):
562 for p in self.wim_config_encrypted:
563 if wim_content["config"].get(p):
564 wim_account_RO["config"][p] = self.db.decrypt(wim_content["config"][p],
565 schema_version=schema_version,
566 salt=wim_id)
567
568 if "wim_user" in wim_content:
569 wim_content["wim_username"] = wim_content["wim_user"]
570 # wim_account must be edited always even if empty in order to ensure changes are translated to RO
571 # wim_thread. RO will remove and relaunch a new thread for this wim_account
572 await RO.edit("wim_account", RO_wim_id, descriptor=wim_account_RO)
573 db_wim_update["_admin.operationalState"] = "ENABLED"
kuuse6a470c62019-07-10 13:52:45 +0200574 # Mark the WIM 'edit' HA task as successful
575 operationState_HA = 'COMPLETED'
576 detailed_status_HA = 'Done'
tiernoe37b57d2018-12-11 17:22:51 +0000577
578 self.logger.debug(logging_text + "Exit Ok RO_wim_id={}".format(RO_wim_id))
579 return
580
581 except (ROclient.ROClientException, DbException) as e:
582 self.logger.error(logging_text + "Exit Exception {}".format(e))
583 exc = e
584 except Exception as e:
585 self.logger.critical(logging_text + "Exit Exception {}".format(e), exc_info=True)
586 exc = e
587 finally:
588 if exc and db_wim:
589 db_wim_update["_admin.operationalState"] = "ERROR"
590 db_wim_update["_admin.detailed-status"] = "ERROR {}: {}".format(step, exc)
kuuse6a470c62019-07-10 13:52:45 +0200591 # Mark the WIM 'edit' HA task as erroneous
592 operationState_HA = 'FAILED'
593 detailed_status_HA = "ERROR {}: {}".format(step, exc)
tiernobaa51102018-12-14 13:16:18 +0000594 try:
595 if db_wim_update:
596 self.update_db_2("wim_accounts", wim_id, db_wim_update)
kuuse6a470c62019-07-10 13:52:45 +0200597 # Register the WIM 'edit' HA task either
598 # succesful or erroneous, or do nothing (if legacy NBI)
599 self.lcm_tasks.register_HA('wim', 'edit', op_id,
600 operationState=operationState_HA,
601 detailed_status=detailed_status_HA)
tiernobaa51102018-12-14 13:16:18 +0000602 except DbException as e:
603 self.logger.error(logging_text + "Cannot update database: {}".format(e))
tiernoe37b57d2018-12-11 17:22:51 +0000604 self.lcm_tasks.remove("wim_account", wim_id, order_id)
605
kuuse6a470c62019-07-10 13:52:45 +0200606 async def delete(self, wim_content, order_id):
607
608 # HA tasks and backward compatibility:
609 # If 'vim_content' does not include 'op_id', we a running a legacy NBI version.
610 # In such a case, HA is not supported by NBI, and the HA check always returns True
611 op_id = wim_content.pop('op_id', None)
612 if not self.lcm_tasks.lock_HA('wim', 'delete', op_id):
613 return
614
615 wim_id = wim_content["_id"]
tiernoe37b57d2018-12-11 17:22:51 +0000616 logging_text = "Task wim_delete={} ".format(wim_id)
617 self.logger.debug(logging_text + "Enter")
kuuse6a470c62019-07-10 13:52:45 +0200618
tiernoe37b57d2018-12-11 17:22:51 +0000619 db_wim = None
620 db_wim_update = {}
621 exc = None
622 step = "Getting wim from db"
kuuse6a470c62019-07-10 13:52:45 +0200623 operationState_HA = ''
624 detailed_status_HA = ''
tiernoe37b57d2018-12-11 17:22:51 +0000625 try:
kuuse6a470c62019-07-10 13:52:45 +0200626 # wait for any previous tasks in process
627 await self.lcm_tasks.waitfor_related_HA('wim', 'delete', op_id)
628
tiernoe37b57d2018-12-11 17:22:51 +0000629 db_wim = self.db.get_one("wim_accounts", {"_id": wim_id})
630 if db_wim.get("_admin") and db_wim["_admin"].get("deployed") and db_wim["_admin"]["deployed"].get("RO"):
631 RO_wim_id = db_wim["_admin"]["deployed"]["RO"]
632 RO = ROclient.ROClient(self.loop, **self.ro_config)
633 step = "Detaching wim from RO tenant"
634 try:
635 await RO.detach("wim_account", RO_wim_id)
636 except ROclient.ROClientException as e:
637 if e.http_code == 404: # not found
638 self.logger.debug(logging_text + "RO_wim_id={} already detached".format(RO_wim_id))
639 else:
640 raise
641
642 step = "Deleting wim from RO"
643 try:
644 await RO.delete("wim", RO_wim_id)
645 except ROclient.ROClientException as e:
646 if e.http_code == 404: # not found
647 self.logger.debug(logging_text + "RO_wim_id={} already deleted".format(RO_wim_id))
648 else:
649 raise
650 else:
651 # nothing to delete
652 self.logger.error(logging_text + "Nohing to remove at RO")
653 self.db.del_one("wim_accounts", {"_id": wim_id})
tiernobaa51102018-12-14 13:16:18 +0000654 db_wim = None
tiernoe37b57d2018-12-11 17:22:51 +0000655 self.logger.debug(logging_text + "Exit Ok")
656 return
657
658 except (ROclient.ROClientException, DbException) as e:
659 self.logger.error(logging_text + "Exit Exception {}".format(e))
660 exc = e
661 except Exception as e:
662 self.logger.critical(logging_text + "Exit Exception {}".format(e), exc_info=True)
663 exc = e
664 finally:
665 self.lcm_tasks.remove("wim_account", wim_id, order_id)
666 if exc and db_wim:
667 db_wim_update["_admin.operationalState"] = "ERROR"
668 db_wim_update["_admin.detailed-status"] = "ERROR {}: {}".format(step, exc)
kuuse6a470c62019-07-10 13:52:45 +0200669 # Mark the WIM 'delete' HA task as erroneous
670 operationState_HA = 'FAILED'
671 detailed_status_HA = "ERROR {}: {}".format(step, exc)
672 self.lcm_tasks.register_HA('wim', 'delete', op_id,
673 operationState=operationState_HA,
674 detailed_status=detailed_status_HA)
tiernobaa51102018-12-14 13:16:18 +0000675 try:
676 if db_wim and db_wim_update:
677 self.update_db_2("wim_accounts", wim_id, db_wim_update)
kuuse6a470c62019-07-10 13:52:45 +0200678 # If the WIM 'delete' HA task was succesful, the DB entry has been deleted,
679 # which means that there is nowhere to register this task, so do nothing here.
tiernobaa51102018-12-14 13:16:18 +0000680 except DbException as e:
681 self.logger.error(logging_text + "Cannot update database: {}".format(e))
tiernoe37b57d2018-12-11 17:22:51 +0000682 self.lcm_tasks.remove("wim_account", wim_id, order_id)
683
684
tierno59d22d22018-09-25 18:10:19 +0200685class SdnLcm(LcmBase):
686
687 def __init__(self, db, msg, fs, lcm_tasks, ro_config, loop):
688 """
689 Init, Connect to database, filesystem storage, and messaging
690 :param config: two level dictionary with configuration. Top level should contain 'database', 'storage',
691 :return: None
692 """
693
694 self.logger = logging.getLogger('lcm.sdn')
695 self.loop = loop
696 self.lcm_tasks = lcm_tasks
697 self.ro_config = ro_config
698
699 super().__init__(db, msg, fs, self.logger)
700
701 async def create(self, sdn_content, order_id):
kuuse6a470c62019-07-10 13:52:45 +0200702
703 # HA tasks and backward compatibility:
704 # If 'sdn_content' does not include 'op_id', we a running a legacy NBI version.
705 # In such a case, HA is not supported by NBI, 'op_id' is None, and lock_HA() will do nothing.
706 # Register 'create' task here for related future HA operations
707 op_id = sdn_content.pop('op_id', None)
708 self.lcm_tasks.lock_HA('sdn', 'create', op_id)
709
tierno59d22d22018-09-25 18:10:19 +0200710 sdn_id = sdn_content["_id"]
tierno2ef21172019-07-05 11:54:25 +0000711 sdn_content.pop("op_id", None)
tierno59d22d22018-09-25 18:10:19 +0200712 logging_text = "Task sdn_create={} ".format(sdn_id)
713 self.logger.debug(logging_text + "Enter")
kuuse6a470c62019-07-10 13:52:45 +0200714
tierno59d22d22018-09-25 18:10:19 +0200715 db_sdn = None
716 db_sdn_update = {}
717 RO_sdn_id = None
718 exc = None
kuuse6a470c62019-07-10 13:52:45 +0200719 operationState_HA = ''
720 detailed_status_HA = ''
tierno59d22d22018-09-25 18:10:19 +0200721 try:
722 step = "Getting sdn from db"
723 db_sdn = self.db.get_one("sdns", {"_id": sdn_id})
724 db_sdn_update["_admin.deployed.RO"] = None
725
726 step = "Creating sdn at RO"
tiernobaa51102018-12-14 13:16:18 +0000727 db_sdn_update["_admin.detailed-status"] = step
728 self.update_db_2("sdns", sdn_id, db_sdn_update)
729
tierno59d22d22018-09-25 18:10:19 +0200730 RO = ROclient.ROClient(self.loop, **self.ro_config)
731 sdn_RO = deepcopy(sdn_content)
732 sdn_RO.pop("_id", None)
733 sdn_RO.pop("_admin", None)
tierno17a612f2018-10-23 11:30:42 +0200734 schema_version = sdn_RO.pop("schema_version", None)
tierno59d22d22018-09-25 18:10:19 +0200735 sdn_RO.pop("schema_type", None)
736 sdn_RO.pop("description", None)
tierno17a612f2018-10-23 11:30:42 +0200737 if sdn_RO.get("password"):
738 sdn_RO["password"] = self.db.decrypt(sdn_RO["password"], schema_version=schema_version, salt=sdn_id)
739
tierno59d22d22018-09-25 18:10:19 +0200740 desc = await RO.create("sdn", descriptor=sdn_RO)
741 RO_sdn_id = desc["uuid"]
742 db_sdn_update["_admin.deployed.RO"] = RO_sdn_id
743 db_sdn_update["_admin.operationalState"] = "ENABLED"
744 self.logger.debug(logging_text + "Exit Ok RO_sdn_id={}".format(RO_sdn_id))
kuuse6a470c62019-07-10 13:52:45 +0200745 # Mark the SDN 'create' HA task as successful
746 operationState_HA = 'COMPLETED'
747 detailed_status_HA = 'Done'
tierno59d22d22018-09-25 18:10:19 +0200748 return
749
750 except (ROclient.ROClientException, DbException) as e:
751 self.logger.error(logging_text + "Exit Exception {}".format(e))
752 exc = e
753 except Exception as e:
754 self.logger.critical(logging_text + "Exit Exception {}".format(e), exc_info=True)
755 exc = e
756 finally:
757 if exc and db_sdn:
758 db_sdn_update["_admin.operationalState"] = "ERROR"
759 db_sdn_update["_admin.detailed-status"] = "ERROR {}: {}".format(step, exc)
kuuse6a470c62019-07-10 13:52:45 +0200760 # Mark the SDN 'create' HA task as erroneous
761 operationState_HA = 'FAILED'
762 detailed_status_HA = "ERROR {}: {}".format(step, exc)
tiernobaa51102018-12-14 13:16:18 +0000763 try:
764 if db_sdn and db_sdn_update:
765 self.update_db_2("sdns", sdn_id, db_sdn_update)
kuuse6a470c62019-07-10 13:52:45 +0200766 # Register the SDN 'create' HA task either
767 # succesful or erroneous, or do nothing (if legacy NBI)
768 self.lcm_tasks.register_HA('sdn', 'create', op_id,
769 operationState=operationState_HA,
770 detailed_status=detailed_status_HA)
tiernobaa51102018-12-14 13:16:18 +0000771 except DbException as e:
772 self.logger.error(logging_text + "Cannot update database: {}".format(e))
tierno59d22d22018-09-25 18:10:19 +0200773 self.lcm_tasks.remove("sdn", sdn_id, order_id)
774
775 async def edit(self, sdn_content, order_id):
kuuse6a470c62019-07-10 13:52:45 +0200776
777 # HA tasks and backward compatibility:
778 # If 'sdn_content' does not include 'op_id', we a running a legacy NBI version.
779 # In such a case, HA is not supported by NBI, and the HA check always returns True
780 op_id = sdn_content.pop('op_id', None)
781 if not self.lcm_tasks.lock_HA('sdn', 'edit', op_id):
782 return
783
tierno59d22d22018-09-25 18:10:19 +0200784 sdn_id = sdn_content["_id"]
tierno2ef21172019-07-05 11:54:25 +0000785 sdn_content.pop("op_id", None)
tierno59d22d22018-09-25 18:10:19 +0200786 logging_text = "Task sdn_edit={} ".format(sdn_id)
787 self.logger.debug(logging_text + "Enter")
kuuse6a470c62019-07-10 13:52:45 +0200788
tierno59d22d22018-09-25 18:10:19 +0200789 db_sdn = None
790 db_sdn_update = {}
791 exc = None
kuuse6a470c62019-07-10 13:52:45 +0200792 operationState_HA = ''
793 detailed_status_HA = ''
tierno59d22d22018-09-25 18:10:19 +0200794 step = "Getting sdn from db"
795 try:
kuuse6a470c62019-07-10 13:52:45 +0200796 # wait for any previous tasks in process
797 await self.lcm_tasks.waitfor_related_HA('sdn', 'edit', op_id)
798
tierno59d22d22018-09-25 18:10:19 +0200799 db_sdn = self.db.get_one("sdns", {"_id": sdn_id})
tiernoe37b57d2018-12-11 17:22:51 +0000800 RO_sdn_id = None
tierno59d22d22018-09-25 18:10:19 +0200801 if db_sdn.get("_admin") and db_sdn["_admin"].get("deployed") and db_sdn["_admin"]["deployed"].get("RO"):
802 RO_sdn_id = db_sdn["_admin"]["deployed"]["RO"]
803 RO = ROclient.ROClient(self.loop, **self.ro_config)
804 step = "Editing sdn at RO"
805 sdn_RO = deepcopy(sdn_content)
806 sdn_RO.pop("_id", None)
807 sdn_RO.pop("_admin", None)
tierno17a612f2018-10-23 11:30:42 +0200808 schema_version = sdn_RO.pop("schema_version", None)
tierno59d22d22018-09-25 18:10:19 +0200809 sdn_RO.pop("schema_type", None)
810 sdn_RO.pop("description", None)
tierno17a612f2018-10-23 11:30:42 +0200811 if sdn_RO.get("password"):
812 sdn_RO["password"] = self.db.decrypt(sdn_RO["password"], schema_version=schema_version, salt=sdn_id)
tierno59d22d22018-09-25 18:10:19 +0200813 if sdn_RO:
814 await RO.edit("sdn", RO_sdn_id, descriptor=sdn_RO)
815 db_sdn_update["_admin.operationalState"] = "ENABLED"
kuuse6a470c62019-07-10 13:52:45 +0200816 # Mark the SDN 'edit' HA task as successful
817 operationState_HA = 'COMPLETED'
818 detailed_status_HA = 'Done'
tierno59d22d22018-09-25 18:10:19 +0200819
tiernoe37b57d2018-12-11 17:22:51 +0000820 self.logger.debug(logging_text + "Exit Ok RO_sdn_id={}".format(RO_sdn_id))
tierno59d22d22018-09-25 18:10:19 +0200821 return
822
823 except (ROclient.ROClientException, DbException) as e:
824 self.logger.error(logging_text + "Exit Exception {}".format(e))
825 exc = e
826 except Exception as e:
827 self.logger.critical(logging_text + "Exit Exception {}".format(e), exc_info=True)
828 exc = e
829 finally:
830 if exc and db_sdn:
831 db_sdn["_admin.operationalState"] = "ERROR"
832 db_sdn["_admin.detailed-status"] = "ERROR {}: {}".format(step, exc)
kuuse6a470c62019-07-10 13:52:45 +0200833 # Mark the SDN 'edit' HA task as erroneous
834 operationState_HA = 'FAILED'
835 detailed_status_HA = "ERROR {}: {}".format(step, exc)
tiernobaa51102018-12-14 13:16:18 +0000836 try:
837 if db_sdn_update:
838 self.update_db_2("sdns", sdn_id, db_sdn_update)
kuuse6a470c62019-07-10 13:52:45 +0200839 # Register the SDN 'edit' HA task either
840 # succesful or erroneous, or do nothing (if legacy NBI)
841 self.lcm_tasks.register_HA('sdn', 'edit', op_id,
842 operationState=operationState_HA,
843 detailed_status=detailed_status_HA)
tiernobaa51102018-12-14 13:16:18 +0000844 except DbException as e:
845 self.logger.error(logging_text + "Cannot update database: {}".format(e))
tierno59d22d22018-09-25 18:10:19 +0200846 self.lcm_tasks.remove("sdn", sdn_id, order_id)
847
kuuse6a470c62019-07-10 13:52:45 +0200848 async def delete(self, sdn_content, order_id):
849
850 # HA tasks and backward compatibility:
851 # If 'vim_content' does not include 'op_id', we a running a legacy NBI version.
852 # In such a case, HA is not supported by NBI, and the HA check always returns True
853 op_id = sdn_content.pop('op_id', None)
854 if not self.lcm_tasks.lock_HA('sdn', 'delete', op_id):
855 return
856
857 sdn_id = sdn_content["_id"]
tierno59d22d22018-09-25 18:10:19 +0200858 logging_text = "Task sdn_delete={} ".format(sdn_id)
859 self.logger.debug(logging_text + "Enter")
kuuse6a470c62019-07-10 13:52:45 +0200860
tierno59d22d22018-09-25 18:10:19 +0200861 db_sdn = None
862 db_sdn_update = {}
863 exc = None
kuuse6a470c62019-07-10 13:52:45 +0200864 operationState_HA = ''
865 detailed_status_HA = ''
tierno59d22d22018-09-25 18:10:19 +0200866 step = "Getting sdn from db"
867 try:
kuuse6a470c62019-07-10 13:52:45 +0200868 # wait for any previous tasks in process
869 await self.lcm_tasks.waitfor_related_HA('sdn', 'delete', op_id)
870
tierno59d22d22018-09-25 18:10:19 +0200871 db_sdn = self.db.get_one("sdns", {"_id": sdn_id})
872 if db_sdn.get("_admin") and db_sdn["_admin"].get("deployed") and db_sdn["_admin"]["deployed"].get("RO"):
873 RO_sdn_id = db_sdn["_admin"]["deployed"]["RO"]
874 RO = ROclient.ROClient(self.loop, **self.ro_config)
875 step = "Deleting sdn from RO"
876 try:
877 await RO.delete("sdn", RO_sdn_id)
878 except ROclient.ROClientException as e:
879 if e.http_code == 404: # not found
880 self.logger.debug(logging_text + "RO_sdn_id={} already deleted".format(RO_sdn_id))
881 else:
882 raise
883 else:
884 # nothing to delete
885 self.logger.error(logging_text + "Skipping. There is not RO information at database")
886 self.db.del_one("sdns", {"_id": sdn_id})
tiernobaa51102018-12-14 13:16:18 +0000887 db_sdn = None
tierno59d22d22018-09-25 18:10:19 +0200888 self.logger.debug("sdn_delete task sdn_id={} Exit Ok".format(sdn_id))
889 return
890
891 except (ROclient.ROClientException, DbException) as e:
892 self.logger.error(logging_text + "Exit Exception {}".format(e))
893 exc = e
894 except Exception as e:
895 self.logger.critical(logging_text + "Exit Exception {}".format(e), exc_info=True)
896 exc = e
897 finally:
898 if exc and db_sdn:
899 db_sdn["_admin.operationalState"] = "ERROR"
900 db_sdn["_admin.detailed-status"] = "ERROR {}: {}".format(step, exc)
kuuse6a470c62019-07-10 13:52:45 +0200901 # Mark the SDN 'delete' HA task as erroneous
902 operationState_HA = 'FAILED'
903 detailed_status_HA = "ERROR {}: {}".format(step, exc)
904 self.lcm_tasks.register_HA('sdn', 'delete', op_id,
905 operationState=operationState_HA,
906 detailed_status=detailed_status_HA)
tiernobaa51102018-12-14 13:16:18 +0000907 try:
908 if db_sdn and db_sdn_update:
909 self.update_db_2("sdns", sdn_id, db_sdn_update)
kuuse6a470c62019-07-10 13:52:45 +0200910 # If the SDN 'delete' HA task was succesful, the DB entry has been deleted,
911 # which means that there is nowhere to register this task, so do nothing here.
tiernobaa51102018-12-14 13:16:18 +0000912 except DbException as e:
913 self.logger.error(logging_text + "Cannot update database: {}".format(e))
tierno59d22d22018-09-25 18:10:19 +0200914 self.lcm_tasks.remove("sdn", sdn_id, order_id)