1 # -*- coding: utf-8 -*-
4 # Copyright 2018 Telefonica S.A.
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
10 # http://www.apache.org/licenses/LICENSE-2.0
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
21 import logging
.handlers
23 from lcm_utils
import LcmException
, LcmBase
24 from osm_common
.dbbase
import DbException
25 from copy
import deepcopy
27 __author__
= "Alfonso Tierno"
30 class VimLcm(LcmBase
):
31 # values that are encrypted at vim config because they are passwords
32 vim_config_encrypted
= {"1.1": ("admin_password", "nsx_password", "vcenter_password"),
33 "default": ("admin_password", "nsx_password", "vcenter_password", "vrops_password")}
35 def __init__(self
, db
, msg
, fs
, lcm_tasks
, ro_config
, loop
):
37 Init, Connect to database, filesystem storage, and messaging
38 :param config: two level dictionary with configuration. Top level should contain 'database', 'storage',
42 self
.logger
= logging
.getLogger('lcm.vim')
44 self
.lcm_tasks
= lcm_tasks
45 self
.ro_config
= ro_config
47 super().__init
__(db
, msg
, fs
, self
.logger
)
49 async def create(self
, vim_content
, order_id
):
50 vim_id
= vim_content
["_id"]
51 vim_content
.pop("op_id", None)
52 logging_text
= "Task vim_create={} ".format(vim_id
)
53 self
.logger
.debug(logging_text
+ "Enter")
59 step
= "Getting vim-id='{}' from db".format(vim_id
)
60 db_vim
= self
.db
.get_one("vim_accounts", {"_id": vim_id
})
61 if vim_content
.get("config") and vim_content
["config"].get("sdn-controller"):
62 step
= "Getting sdn-controller-id='{}' from db".format(vim_content
["config"]["sdn-controller"])
63 db_sdn
= self
.db
.get_one("sdns", {"_id": vim_content
["config"]["sdn-controller"]})
64 if db_sdn
.get("_admin") and db_sdn
["_admin"].get("deployed") and db_sdn
["_admin"]["deployed"].get("RO"):
65 RO_sdn_id
= db_sdn
["_admin"]["deployed"]["RO"]
67 raise LcmException("sdn-controller={} is not available. Not deployed at RO".format(
68 vim_content
["config"]["sdn-controller"]))
70 step
= "Creating vim at RO"
71 db_vim_update
["_admin.deployed.RO"] = None
72 db_vim_update
["_admin.detailed-status"] = step
73 self
.update_db_2("vim_accounts", vim_id
, db_vim_update
)
74 RO
= ROclient
.ROClient(self
.loop
, **self
.ro_config
)
75 vim_RO
= deepcopy(vim_content
)
76 vim_RO
.pop("_id", None)
77 vim_RO
.pop("_admin", None)
78 schema_version
= vim_RO
.pop("schema_version", None)
79 vim_RO
.pop("schema_type", None)
80 vim_RO
.pop("vim_tenant_name", None)
81 vim_RO
["type"] = vim_RO
.pop("vim_type")
82 vim_RO
.pop("vim_user", None)
83 vim_RO
.pop("vim_password", None)
85 vim_RO
["config"]["sdn-controller"] = RO_sdn_id
86 desc
= await RO
.create("vim", descriptor
=vim_RO
)
87 RO_vim_id
= desc
["uuid"]
88 db_vim_update
["_admin.deployed.RO"] = RO_vim_id
89 self
.logger
.debug(logging_text
+ "VIM created at RO_vim_id={}".format(RO_vim_id
))
91 step
= "Creating vim_account at RO"
92 db_vim_update
["_admin.detailed-status"] = step
93 self
.update_db_2("vim_accounts", vim_id
, db_vim_update
)
95 if vim_content
.get("vim_password"):
96 vim_content
["vim_password"] = self
.db
.decrypt(vim_content
["vim_password"],
97 schema_version
=schema_version
,
99 vim_account_RO
= {"vim_tenant_name": vim_content
["vim_tenant_name"],
100 "vim_username": vim_content
["vim_user"],
101 "vim_password": vim_content
["vim_password"]
103 if vim_RO
.get("config"):
104 vim_account_RO
["config"] = vim_RO
["config"]
105 if "sdn-controller" in vim_account_RO
["config"]:
106 del vim_account_RO
["config"]["sdn-controller"]
107 if "sdn-port-mapping" in vim_account_RO
["config"]:
108 del vim_account_RO
["config"]["sdn-port-mapping"]
109 vim_config_encrypted_keys
= self
.vim_config_encrypted
.get(schema_version
) or \
110 self
.vim_config_encrypted
.get("default")
111 for p
in vim_config_encrypted_keys
:
112 if vim_account_RO
["config"].get(p
):
113 vim_account_RO
["config"][p
] = self
.db
.decrypt(vim_account_RO
["config"][p
],
114 schema_version
=schema_version
,
117 desc
= await RO
.attach("vim_account", RO_vim_id
, descriptor
=vim_account_RO
)
118 db_vim_update
["_admin.deployed.RO-account"] = desc
["uuid"]
119 db_vim_update
["_admin.operationalState"] = "ENABLED"
120 db_vim_update
["_admin.detailed-status"] = "Done"
122 # await asyncio.sleep(15) # TODO remove. This is for test
123 self
.logger
.debug(logging_text
+ "Exit Ok VIM account created at RO_vim_account_id={}".format(desc
["uuid"]))
126 except (ROclient
.ROClientException
, DbException
) as e
:
127 self
.logger
.error(logging_text
+ "Exit Exception {}".format(e
))
129 except Exception as e
:
130 self
.logger
.critical(logging_text
+ "Exit Exception {}".format(e
), exc_info
=True)
134 db_vim_update
["_admin.operationalState"] = "ERROR"
135 db_vim_update
["_admin.detailed-status"] = "ERROR {}: {}".format(step
, exc
)
138 self
.update_db_2("vim_accounts", vim_id
, db_vim_update
)
139 except DbException
as e
:
140 self
.logger
.error(logging_text
+ "Cannot update database: {}".format(e
))
142 self
.lcm_tasks
.remove("vim_account", vim_id
, order_id
)
144 async def edit(self
, vim_content
, order_id
):
145 vim_id
= vim_content
["_id"]
146 vim_content
.pop("op_id", None)
147 logging_text
= "Task vim_edit={} ".format(vim_id
)
148 self
.logger
.debug(logging_text
+ "Enter")
154 step
= "Getting vim-id='{}' from db".format(vim_id
)
156 db_vim
= self
.db
.get_one("vim_accounts", {"_id": vim_id
})
158 # look if previous tasks in process
159 task_name
, task_dependency
= self
.lcm_tasks
.lookfor_related("vim_account", vim_id
, order_id
)
161 step
= "Waiting for related tasks to be completed: {}".format(task_name
)
162 self
.logger
.debug(logging_text
+ step
)
163 # TODO write this to database
164 _
, pending
= await asyncio
.wait(task_dependency
, timeout
=3600)
166 raise LcmException("Timeout waiting related tasks to be completed")
168 if db_vim
.get("_admin") and db_vim
["_admin"].get("deployed") and db_vim
["_admin"]["deployed"].get("RO"):
169 if vim_content
.get("config") and vim_content
["config"].get("sdn-controller"):
170 step
= "Getting sdn-controller-id='{}' from db".format(vim_content
["config"]["sdn-controller"])
171 db_sdn
= self
.db
.get_one("sdns", {"_id": vim_content
["config"]["sdn-controller"]})
173 # look if previous tasks in process
174 task_name
, task_dependency
= self
.lcm_tasks
.lookfor_related("sdn", db_sdn
["_id"])
176 step
= "Waiting for related tasks to be completed: {}".format(task_name
)
177 self
.logger
.debug(logging_text
+ step
)
178 # TODO write this to database
179 _
, pending
= await asyncio
.wait(task_dependency
, timeout
=3600)
181 raise LcmException("Timeout waiting related tasks to be completed")
183 if db_sdn
.get("_admin") and db_sdn
["_admin"].get("deployed") and db_sdn
["_admin"]["deployed"].get(
185 RO_sdn_id
= db_sdn
["_admin"]["deployed"]["RO"]
187 raise LcmException("sdn-controller={} is not available. Not deployed at RO".format(
188 vim_content
["config"]["sdn-controller"]))
190 RO_vim_id
= db_vim
["_admin"]["deployed"]["RO"]
191 step
= "Editing vim at RO"
192 RO
= ROclient
.ROClient(self
.loop
, **self
.ro_config
)
193 vim_RO
= deepcopy(vim_content
)
194 vim_RO
.pop("_id", None)
195 vim_RO
.pop("_admin", None)
196 schema_version
= vim_RO
.pop("schema_version", None)
197 vim_RO
.pop("schema_type", None)
198 vim_RO
.pop("vim_tenant_name", None)
199 if "vim_type" in vim_RO
:
200 vim_RO
["type"] = vim_RO
.pop("vim_type")
201 vim_RO
.pop("vim_user", None)
202 vim_RO
.pop("vim_password", None)
204 vim_RO
["config"]["sdn-controller"] = RO_sdn_id
205 # TODO make a deep update of sdn-port-mapping
207 await RO
.edit("vim", RO_vim_id
, descriptor
=vim_RO
)
209 step
= "Editing vim-account at RO tenant"
211 if "config" in vim_content
:
212 if "sdn-controller" in vim_content
["config"]:
213 del vim_content
["config"]["sdn-controller"]
214 if "sdn-port-mapping" in vim_content
["config"]:
215 del vim_content
["config"]["sdn-port-mapping"]
216 if not vim_content
["config"]:
217 del vim_content
["config"]
218 if "vim_tenant_name" in vim_content
:
219 vim_account_RO
["vim_tenant_name"] = vim_content
["vim_tenant_name"]
220 if "vim_password" in vim_content
:
221 vim_account_RO
["vim_password"] = vim_content
["vim_password"]
222 if vim_content
.get("vim_password"):
223 vim_account_RO
["vim_password"] = self
.db
.decrypt(vim_content
["vim_password"],
224 schema_version
=schema_version
,
226 if "config" in vim_content
:
227 vim_account_RO
["config"] = vim_content
["config"]
228 if vim_content
.get("config"):
229 vim_config_encrypted_keys
= self
.vim_config_encrypted
.get(schema_version
) or \
230 self
.vim_config_encrypted
.get("default")
231 for p
in vim_config_encrypted_keys
:
232 if vim_content
["config"].get(p
):
233 vim_account_RO
["config"][p
] = self
.db
.decrypt(vim_content
["config"][p
],
234 schema_version
=schema_version
,
237 if "vim_user" in vim_content
:
238 vim_content
["vim_username"] = vim_content
["vim_user"]
239 # vim_account must be edited always even if empty in order to ensure changes are translated to RO
240 # vim_thread. RO will remove and relaunch a new thread for this vim_account
241 await RO
.edit("vim_account", RO_vim_id
, descriptor
=vim_account_RO
)
242 db_vim_update
["_admin.operationalState"] = "ENABLED"
244 self
.logger
.debug(logging_text
+ "Exit Ok RO_vim_id={}".format(RO_vim_id
))
247 except (ROclient
.ROClientException
, DbException
) as e
:
248 self
.logger
.error(logging_text
+ "Exit Exception {}".format(e
))
250 except Exception as e
:
251 self
.logger
.critical(logging_text
+ "Exit Exception {}".format(e
), exc_info
=True)
255 db_vim_update
["_admin.operationalState"] = "ERROR"
256 db_vim_update
["_admin.detailed-status"] = "ERROR {}: {}".format(step
, exc
)
259 self
.update_db_2("vim_accounts", vim_id
, db_vim_update
)
260 except DbException
as e
:
261 self
.logger
.error(logging_text
+ "Cannot update database: {}".format(e
))
263 self
.lcm_tasks
.remove("vim_account", vim_id
, order_id
)
265 async def delete(self
, vim_id
, order_id
):
266 logging_text
= "Task vim_delete={} ".format(vim_id
)
267 self
.logger
.debug(logging_text
+ "Enter")
271 step
= "Getting vim from db"
273 db_vim
= self
.db
.get_one("vim_accounts", {"_id": vim_id
})
274 if db_vim
.get("_admin") and db_vim
["_admin"].get("deployed") and db_vim
["_admin"]["deployed"].get("RO"):
275 RO_vim_id
= db_vim
["_admin"]["deployed"]["RO"]
276 RO
= ROclient
.ROClient(self
.loop
, **self
.ro_config
)
277 step
= "Detaching vim from RO tenant"
279 await RO
.detach("vim_account", RO_vim_id
)
280 except ROclient
.ROClientException
as e
:
281 if e
.http_code
== 404: # not found
282 self
.logger
.debug(logging_text
+ "RO_vim_id={} already detached".format(RO_vim_id
))
286 step
= "Deleting vim from RO"
288 await RO
.delete("vim", RO_vim_id
)
289 except ROclient
.ROClientException
as e
:
290 if e
.http_code
== 404: # not found
291 self
.logger
.debug(logging_text
+ "RO_vim_id={} already deleted".format(RO_vim_id
))
296 self
.logger
.error(logging_text
+ "Nohing to remove at RO")
297 self
.db
.del_one("vim_accounts", {"_id": vim_id
})
299 self
.logger
.debug(logging_text
+ "Exit Ok")
302 except (ROclient
.ROClientException
, DbException
) as e
:
303 self
.logger
.error(logging_text
+ "Exit Exception {}".format(e
))
305 except Exception as e
:
306 self
.logger
.critical(logging_text
+ "Exit Exception {}".format(e
), exc_info
=True)
309 self
.lcm_tasks
.remove("vim_account", vim_id
, order_id
)
311 db_vim_update
["_admin.operationalState"] = "ERROR"
312 db_vim_update
["_admin.detailed-status"] = "ERROR {}: {}".format(step
, exc
)
314 if db_vim
and db_vim_update
:
315 self
.update_db_2("vim_accounts", vim_id
, db_vim_update
)
316 except DbException
as e
:
317 self
.logger
.error(logging_text
+ "Cannot update database: {}".format(e
))
318 self
.lcm_tasks
.remove("vim_account", vim_id
, order_id
)
321 class WimLcm(LcmBase
):
322 # values that are encrypted at wim config because they are passwords
323 wim_config_encrypted
= ()
325 def __init__(self
, db
, msg
, fs
, lcm_tasks
, ro_config
, loop
):
327 Init, Connect to database, filesystem storage, and messaging
328 :param config: two level dictionary with configuration. Top level should contain 'database', 'storage',
332 self
.logger
= logging
.getLogger('lcm.vim')
334 self
.lcm_tasks
= lcm_tasks
335 self
.ro_config
= ro_config
337 super().__init
__(db
, msg
, fs
, self
.logger
)
339 async def create(self
, wim_content
, order_id
):
340 wim_id
= wim_content
["_id"]
341 wim_content
.pop("op_id", None)
342 logging_text
= "Task wim_create={} ".format(wim_id
)
343 self
.logger
.debug(logging_text
+ "Enter")
348 step
= "Getting wim-id='{}' from db".format(wim_id
)
349 db_wim
= self
.db
.get_one("wim_accounts", {"_id": wim_id
})
350 db_wim_update
["_admin.deployed.RO"] = None
352 step
= "Creating wim at RO"
353 db_wim_update
["_admin.detailed-status"] = step
354 self
.update_db_2("wim_accounts", wim_id
, db_wim_update
)
355 RO
= ROclient
.ROClient(self
.loop
, **self
.ro_config
)
356 wim_RO
= deepcopy(wim_content
)
357 wim_RO
.pop("_id", None)
358 wim_RO
.pop("_admin", None)
359 schema_version
= wim_RO
.pop("schema_version", None)
360 wim_RO
.pop("schema_type", None)
361 wim_RO
.pop("wim_tenant_name", None)
362 wim_RO
["type"] = wim_RO
.pop("wim_type")
363 wim_RO
.pop("wim_user", None)
364 wim_RO
.pop("wim_password", None)
365 desc
= await RO
.create("wim", descriptor
=wim_RO
)
366 RO_wim_id
= desc
["uuid"]
367 db_wim_update
["_admin.deployed.RO"] = RO_wim_id
368 self
.logger
.debug(logging_text
+ "WIM created at RO_wim_id={}".format(RO_wim_id
))
370 step
= "Creating wim_account at RO"
371 db_wim_update
["_admin.detailed-status"] = step
372 self
.update_db_2("wim_accounts", wim_id
, db_wim_update
)
374 if wim_content
.get("wim_password"):
375 wim_content
["wim_password"] = self
.db
.decrypt(wim_content
["wim_password"],
376 schema_version
=schema_version
,
378 wim_account_RO
= {"name": wim_content
["name"],
379 "user": wim_content
["user"],
380 "password": wim_content
["password"]
382 if wim_RO
.get("config"):
383 wim_account_RO
["config"] = wim_RO
["config"]
384 if "wim_port_mapping" in wim_account_RO
["config"]:
385 del wim_account_RO
["config"]["wim_port_mapping"]
386 for p
in self
.wim_config_encrypted
:
387 if wim_account_RO
["config"].get(p
):
388 wim_account_RO
["config"][p
] = self
.db
.decrypt(wim_account_RO
["config"][p
],
389 schema_version
=schema_version
,
392 desc
= await RO
.attach("wim_account", RO_wim_id
, descriptor
=wim_account_RO
)
393 db_wim_update
["_admin.deployed.RO-account"] = desc
["uuid"]
394 db_wim_update
["_admin.operationalState"] = "ENABLED"
395 db_wim_update
["_admin.detailed-status"] = "Done"
397 self
.logger
.debug(logging_text
+ "Exit Ok WIM account created at RO_wim_account_id={}".format(desc
["uuid"]))
400 except (ROclient
.ROClientException
, DbException
) as e
:
401 self
.logger
.error(logging_text
+ "Exit Exception {}".format(e
))
403 except Exception as e
:
404 self
.logger
.critical(logging_text
+ "Exit Exception {}".format(e
), exc_info
=True)
408 db_wim_update
["_admin.operationalState"] = "ERROR"
409 db_wim_update
["_admin.detailed-status"] = "ERROR {}: {}".format(step
, exc
)
412 self
.update_db_2("wim_accounts", wim_id
, db_wim_update
)
413 except DbException
as e
:
414 self
.logger
.error(logging_text
+ "Cannot update database: {}".format(e
))
415 self
.lcm_tasks
.remove("wim_account", wim_id
, order_id
)
417 async def edit(self
, wim_content
, order_id
):
418 wim_id
= wim_content
["_id"]
419 wim_content
.pop("op_id", None)
420 logging_text
= "Task wim_edit={} ".format(wim_id
)
421 self
.logger
.debug(logging_text
+ "Enter")
426 step
= "Getting wim-id='{}' from db".format(wim_id
)
428 db_wim
= self
.db
.get_one("wim_accounts", {"_id": wim_id
})
430 # look if previous tasks in process
431 task_name
, task_dependency
= self
.lcm_tasks
.lookfor_related("wim_account", wim_id
, order_id
)
433 step
= "Waiting for related tasks to be completed: {}".format(task_name
)
434 self
.logger
.debug(logging_text
+ step
)
435 # TODO write this to database
436 _
, pending
= await asyncio
.wait(task_dependency
, timeout
=3600)
438 raise LcmException("Timeout waiting related tasks to be completed")
440 if db_wim
.get("_admin") and db_wim
["_admin"].get("deployed") and db_wim
["_admin"]["deployed"].get("RO"):
442 RO_wim_id
= db_wim
["_admin"]["deployed"]["RO"]
443 step
= "Editing wim at RO"
444 RO
= ROclient
.ROClient(self
.loop
, **self
.ro_config
)
445 wim_RO
= deepcopy(wim_content
)
446 wim_RO
.pop("_id", None)
447 wim_RO
.pop("_admin", None)
448 schema_version
= wim_RO
.pop("schema_version", None)
449 wim_RO
.pop("schema_type", None)
450 wim_RO
.pop("wim_tenant_name", None)
451 if "wim_type" in wim_RO
:
452 wim_RO
["type"] = wim_RO
.pop("wim_type")
453 wim_RO
.pop("wim_user", None)
454 wim_RO
.pop("wim_password", None)
455 # TODO make a deep update of wim_port_mapping
457 await RO
.edit("wim", RO_wim_id
, descriptor
=wim_RO
)
459 step
= "Editing wim-account at RO tenant"
461 if "config" in wim_content
:
462 if "wim_port_mapping" in wim_content
["config"]:
463 del wim_content
["config"]["wim_port_mapping"]
464 if not wim_content
["config"]:
465 del wim_content
["config"]
466 if "wim_tenant_name" in wim_content
:
467 wim_account_RO
["wim_tenant_name"] = wim_content
["wim_tenant_name"]
468 if "wim_password" in wim_content
:
469 wim_account_RO
["wim_password"] = wim_content
["wim_password"]
470 if wim_content
.get("wim_password"):
471 wim_account_RO
["wim_password"] = self
.db
.decrypt(wim_content
["wim_password"],
472 schema_version
=schema_version
,
474 if "config" in wim_content
:
475 wim_account_RO
["config"] = wim_content
["config"]
476 if wim_content
.get("config"):
477 for p
in self
.wim_config_encrypted
:
478 if wim_content
["config"].get(p
):
479 wim_account_RO
["config"][p
] = self
.db
.decrypt(wim_content
["config"][p
],
480 schema_version
=schema_version
,
483 if "wim_user" in wim_content
:
484 wim_content
["wim_username"] = wim_content
["wim_user"]
485 # wim_account must be edited always even if empty in order to ensure changes are translated to RO
486 # wim_thread. RO will remove and relaunch a new thread for this wim_account
487 await RO
.edit("wim_account", RO_wim_id
, descriptor
=wim_account_RO
)
488 db_wim_update
["_admin.operationalState"] = "ENABLED"
490 self
.logger
.debug(logging_text
+ "Exit Ok RO_wim_id={}".format(RO_wim_id
))
493 except (ROclient
.ROClientException
, DbException
) as e
:
494 self
.logger
.error(logging_text
+ "Exit Exception {}".format(e
))
496 except Exception as e
:
497 self
.logger
.critical(logging_text
+ "Exit Exception {}".format(e
), exc_info
=True)
501 db_wim_update
["_admin.operationalState"] = "ERROR"
502 db_wim_update
["_admin.detailed-status"] = "ERROR {}: {}".format(step
, exc
)
505 self
.update_db_2("wim_accounts", wim_id
, db_wim_update
)
506 except DbException
as e
:
507 self
.logger
.error(logging_text
+ "Cannot update database: {}".format(e
))
508 self
.lcm_tasks
.remove("wim_account", wim_id
, order_id
)
510 async def delete(self
, wim_id
, order_id
):
511 logging_text
= "Task wim_delete={} ".format(wim_id
)
512 self
.logger
.debug(logging_text
+ "Enter")
516 step
= "Getting wim from db"
518 db_wim
= self
.db
.get_one("wim_accounts", {"_id": wim_id
})
519 if db_wim
.get("_admin") and db_wim
["_admin"].get("deployed") and db_wim
["_admin"]["deployed"].get("RO"):
520 RO_wim_id
= db_wim
["_admin"]["deployed"]["RO"]
521 RO
= ROclient
.ROClient(self
.loop
, **self
.ro_config
)
522 step
= "Detaching wim from RO tenant"
524 await RO
.detach("wim_account", RO_wim_id
)
525 except ROclient
.ROClientException
as e
:
526 if e
.http_code
== 404: # not found
527 self
.logger
.debug(logging_text
+ "RO_wim_id={} already detached".format(RO_wim_id
))
531 step
= "Deleting wim from RO"
533 await RO
.delete("wim", RO_wim_id
)
534 except ROclient
.ROClientException
as e
:
535 if e
.http_code
== 404: # not found
536 self
.logger
.debug(logging_text
+ "RO_wim_id={} already deleted".format(RO_wim_id
))
541 self
.logger
.error(logging_text
+ "Nohing to remove at RO")
542 self
.db
.del_one("wim_accounts", {"_id": wim_id
})
544 self
.logger
.debug(logging_text
+ "Exit Ok")
547 except (ROclient
.ROClientException
, DbException
) as e
:
548 self
.logger
.error(logging_text
+ "Exit Exception {}".format(e
))
550 except Exception as e
:
551 self
.logger
.critical(logging_text
+ "Exit Exception {}".format(e
), exc_info
=True)
554 self
.lcm_tasks
.remove("wim_account", wim_id
, order_id
)
556 db_wim_update
["_admin.operationalState"] = "ERROR"
557 db_wim_update
["_admin.detailed-status"] = "ERROR {}: {}".format(step
, exc
)
559 if db_wim
and db_wim_update
:
560 self
.update_db_2("wim_accounts", wim_id
, db_wim_update
)
561 except DbException
as e
:
562 self
.logger
.error(logging_text
+ "Cannot update database: {}".format(e
))
563 self
.lcm_tasks
.remove("wim_account", wim_id
, order_id
)
566 class SdnLcm(LcmBase
):
568 def __init__(self
, db
, msg
, fs
, lcm_tasks
, ro_config
, loop
):
570 Init, Connect to database, filesystem storage, and messaging
571 :param config: two level dictionary with configuration. Top level should contain 'database', 'storage',
575 self
.logger
= logging
.getLogger('lcm.sdn')
577 self
.lcm_tasks
= lcm_tasks
578 self
.ro_config
= ro_config
580 super().__init
__(db
, msg
, fs
, self
.logger
)
582 async def create(self
, sdn_content
, order_id
):
583 sdn_id
= sdn_content
["_id"]
584 sdn_content
.pop("op_id", None)
585 logging_text
= "Task sdn_create={} ".format(sdn_id
)
586 self
.logger
.debug(logging_text
+ "Enter")
592 step
= "Getting sdn from db"
593 db_sdn
= self
.db
.get_one("sdns", {"_id": sdn_id
})
594 db_sdn_update
["_admin.deployed.RO"] = None
596 step
= "Creating sdn at RO"
597 db_sdn_update
["_admin.detailed-status"] = step
598 self
.update_db_2("sdns", sdn_id
, db_sdn_update
)
600 RO
= ROclient
.ROClient(self
.loop
, **self
.ro_config
)
601 sdn_RO
= deepcopy(sdn_content
)
602 sdn_RO
.pop("_id", None)
603 sdn_RO
.pop("_admin", None)
604 schema_version
= sdn_RO
.pop("schema_version", None)
605 sdn_RO
.pop("schema_type", None)
606 sdn_RO
.pop("description", None)
607 if sdn_RO
.get("password"):
608 sdn_RO
["password"] = self
.db
.decrypt(sdn_RO
["password"], schema_version
=schema_version
, salt
=sdn_id
)
610 desc
= await RO
.create("sdn", descriptor
=sdn_RO
)
611 RO_sdn_id
= desc
["uuid"]
612 db_sdn_update
["_admin.deployed.RO"] = RO_sdn_id
613 db_sdn_update
["_admin.operationalState"] = "ENABLED"
614 self
.logger
.debug(logging_text
+ "Exit Ok RO_sdn_id={}".format(RO_sdn_id
))
617 except (ROclient
.ROClientException
, DbException
) as e
:
618 self
.logger
.error(logging_text
+ "Exit Exception {}".format(e
))
620 except Exception as e
:
621 self
.logger
.critical(logging_text
+ "Exit Exception {}".format(e
), exc_info
=True)
625 db_sdn_update
["_admin.operationalState"] = "ERROR"
626 db_sdn_update
["_admin.detailed-status"] = "ERROR {}: {}".format(step
, exc
)
628 if db_sdn
and db_sdn_update
:
629 self
.update_db_2("sdns", sdn_id
, db_sdn_update
)
630 except DbException
as e
:
631 self
.logger
.error(logging_text
+ "Cannot update database: {}".format(e
))
632 self
.lcm_tasks
.remove("sdn", sdn_id
, order_id
)
634 async def edit(self
, sdn_content
, order_id
):
635 sdn_id
= sdn_content
["_id"]
636 sdn_content
.pop("op_id", None)
637 logging_text
= "Task sdn_edit={} ".format(sdn_id
)
638 self
.logger
.debug(logging_text
+ "Enter")
642 step
= "Getting sdn from db"
644 db_sdn
= self
.db
.get_one("sdns", {"_id": sdn_id
})
646 if db_sdn
.get("_admin") and db_sdn
["_admin"].get("deployed") and db_sdn
["_admin"]["deployed"].get("RO"):
647 RO_sdn_id
= db_sdn
["_admin"]["deployed"]["RO"]
648 RO
= ROclient
.ROClient(self
.loop
, **self
.ro_config
)
649 step
= "Editing sdn at RO"
650 sdn_RO
= deepcopy(sdn_content
)
651 sdn_RO
.pop("_id", None)
652 sdn_RO
.pop("_admin", None)
653 schema_version
= sdn_RO
.pop("schema_version", None)
654 sdn_RO
.pop("schema_type", None)
655 sdn_RO
.pop("description", None)
656 if sdn_RO
.get("password"):
657 sdn_RO
["password"] = self
.db
.decrypt(sdn_RO
["password"], schema_version
=schema_version
, salt
=sdn_id
)
659 await RO
.edit("sdn", RO_sdn_id
, descriptor
=sdn_RO
)
660 db_sdn_update
["_admin.operationalState"] = "ENABLED"
662 self
.logger
.debug(logging_text
+ "Exit Ok RO_sdn_id={}".format(RO_sdn_id
))
665 except (ROclient
.ROClientException
, DbException
) as e
:
666 self
.logger
.error(logging_text
+ "Exit Exception {}".format(e
))
668 except Exception as e
:
669 self
.logger
.critical(logging_text
+ "Exit Exception {}".format(e
), exc_info
=True)
673 db_sdn
["_admin.operationalState"] = "ERROR"
674 db_sdn
["_admin.detailed-status"] = "ERROR {}: {}".format(step
, exc
)
677 self
.update_db_2("sdns", sdn_id
, db_sdn_update
)
678 except DbException
as e
:
679 self
.logger
.error(logging_text
+ "Cannot update database: {}".format(e
))
680 self
.lcm_tasks
.remove("sdn", sdn_id
, order_id
)
682 async def delete(self
, sdn_id
, order_id
):
683 logging_text
= "Task sdn_delete={} ".format(sdn_id
)
684 self
.logger
.debug(logging_text
+ "Enter")
688 step
= "Getting sdn from db"
690 db_sdn
= self
.db
.get_one("sdns", {"_id": sdn_id
})
691 if db_sdn
.get("_admin") and db_sdn
["_admin"].get("deployed") and db_sdn
["_admin"]["deployed"].get("RO"):
692 RO_sdn_id
= db_sdn
["_admin"]["deployed"]["RO"]
693 RO
= ROclient
.ROClient(self
.loop
, **self
.ro_config
)
694 step
= "Deleting sdn from RO"
696 await RO
.delete("sdn", RO_sdn_id
)
697 except ROclient
.ROClientException
as e
:
698 if e
.http_code
== 404: # not found
699 self
.logger
.debug(logging_text
+ "RO_sdn_id={} already deleted".format(RO_sdn_id
))
704 self
.logger
.error(logging_text
+ "Skipping. There is not RO information at database")
705 self
.db
.del_one("sdns", {"_id": sdn_id
})
707 self
.logger
.debug("sdn_delete task sdn_id={} Exit Ok".format(sdn_id
))
710 except (ROclient
.ROClientException
, DbException
) as e
:
711 self
.logger
.error(logging_text
+ "Exit Exception {}".format(e
))
713 except Exception as e
:
714 self
.logger
.critical(logging_text
+ "Exit Exception {}".format(e
), exc_info
=True)
718 db_sdn
["_admin.operationalState"] = "ERROR"
719 db_sdn
["_admin.detailed-status"] = "ERROR {}: {}".format(step
, exc
)
721 if db_sdn
and db_sdn_update
:
722 self
.update_db_2("sdns", sdn_id
, db_sdn_update
)
723 except DbException
as e
:
724 self
.logger
.error(logging_text
+ "Cannot update database: {}".format(e
))
725 self
.lcm_tasks
.remove("sdn", sdn_id
, order_id
)