ed25820a0c48f6a9ad3990727317b6de80be4543
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
= ("admin_password", "nsx_password", "vcenter_password")
34 def __init__(self
, db
, msg
, fs
, lcm_tasks
, ro_config
, loop
):
36 Init, Connect to database, filesystem storage, and messaging
37 :param config: two level dictionary with configuration. Top level should contain 'database', 'storage',
41 self
.logger
= logging
.getLogger('lcm.vim')
43 self
.lcm_tasks
= lcm_tasks
44 self
.ro_config
= ro_config
46 super().__init
__(db
, msg
, fs
, self
.logger
)
48 async def create(self
, vim_content
, order_id
):
49 vim_id
= vim_content
["_id"]
50 vim_content
.pop("op_id", None)
51 logging_text
= "Task vim_create={} ".format(vim_id
)
52 self
.logger
.debug(logging_text
+ "Enter")
58 step
= "Getting vim-id='{}' from db".format(vim_id
)
59 db_vim
= self
.db
.get_one("vim_accounts", {"_id": vim_id
})
60 if vim_content
.get("config") and vim_content
["config"].get("sdn-controller"):
61 step
= "Getting sdn-controller-id='{}' from db".format(vim_content
["config"]["sdn-controller"])
62 db_sdn
= self
.db
.get_one("sdns", {"_id": vim_content
["config"]["sdn-controller"]})
63 if db_sdn
.get("_admin") and db_sdn
["_admin"].get("deployed") and db_sdn
["_admin"]["deployed"].get("RO"):
64 RO_sdn_id
= db_sdn
["_admin"]["deployed"]["RO"]
66 raise LcmException("sdn-controller={} is not available. Not deployed at RO".format(
67 vim_content
["config"]["sdn-controller"]))
69 step
= "Creating vim at RO"
70 db_vim_update
["_admin.deployed.RO"] = None
71 db_vim_update
["_admin.detailed-status"] = step
72 self
.update_db_2("vim_accounts", vim_id
, db_vim_update
)
73 RO
= ROclient
.ROClient(self
.loop
, **self
.ro_config
)
74 vim_RO
= deepcopy(vim_content
)
75 vim_RO
.pop("_id", None)
76 vim_RO
.pop("_admin", None)
77 schema_version
= vim_RO
.pop("schema_version", None)
78 vim_RO
.pop("schema_type", None)
79 vim_RO
.pop("vim_tenant_name", None)
80 vim_RO
["type"] = vim_RO
.pop("vim_type")
81 vim_RO
.pop("vim_user", None)
82 vim_RO
.pop("vim_password", None)
84 vim_RO
["config"]["sdn-controller"] = RO_sdn_id
85 desc
= await RO
.create("vim", descriptor
=vim_RO
)
86 RO_vim_id
= desc
["uuid"]
87 db_vim_update
["_admin.deployed.RO"] = RO_vim_id
88 self
.logger
.debug(logging_text
+ "VIM created at RO_vim_id={}".format(RO_vim_id
))
90 step
= "Creating vim_account at RO"
91 db_vim_update
["_admin.detailed-status"] = step
92 self
.update_db_2("vim_accounts", vim_id
, db_vim_update
)
94 if vim_content
.get("vim_password"):
95 vim_content
["vim_password"] = self
.db
.decrypt(vim_content
["vim_password"],
96 schema_version
=schema_version
,
98 vim_account_RO
= {"vim_tenant_name": vim_content
["vim_tenant_name"],
99 "vim_username": vim_content
["vim_user"],
100 "vim_password": vim_content
["vim_password"]
102 if vim_RO
.get("config"):
103 vim_account_RO
["config"] = vim_RO
["config"]
104 if "sdn-controller" in vim_account_RO
["config"]:
105 del vim_account_RO
["config"]["sdn-controller"]
106 if "sdn-port-mapping" in vim_account_RO
["config"]:
107 del vim_account_RO
["config"]["sdn-port-mapping"]
108 for p
in self
.vim_config_encrypted
:
109 if vim_account_RO
["config"].get(p
):
110 vim_account_RO
["config"][p
] = self
.db
.decrypt(vim_account_RO
["config"][p
],
111 schema_version
=schema_version
,
114 desc
= await RO
.attach("vim_account", RO_vim_id
, descriptor
=vim_account_RO
)
115 db_vim_update
["_admin.deployed.RO-account"] = desc
["uuid"]
116 db_vim_update
["_admin.operationalState"] = "ENABLED"
117 db_vim_update
["_admin.detailed-status"] = "Done"
119 # await asyncio.sleep(15) # TODO remove. This is for test
120 self
.logger
.debug(logging_text
+ "Exit Ok VIM account created at RO_vim_account_id={}".format(desc
["uuid"]))
123 except (ROclient
.ROClientException
, DbException
) as e
:
124 self
.logger
.error(logging_text
+ "Exit Exception {}".format(e
))
126 except Exception as e
:
127 self
.logger
.critical(logging_text
+ "Exit Exception {}".format(e
), exc_info
=True)
131 db_vim_update
["_admin.operationalState"] = "ERROR"
132 db_vim_update
["_admin.detailed-status"] = "ERROR {}: {}".format(step
, exc
)
135 self
.update_db_2("vim_accounts", vim_id
, db_vim_update
)
136 except DbException
as e
:
137 self
.logger
.error(logging_text
+ "Cannot update database: {}".format(e
))
139 self
.lcm_tasks
.remove("vim_account", vim_id
, order_id
)
141 async def edit(self
, vim_content
, order_id
):
142 vim_id
= vim_content
["_id"]
143 vim_content
.pop("op_id", None)
144 logging_text
= "Task vim_edit={} ".format(vim_id
)
145 self
.logger
.debug(logging_text
+ "Enter")
151 step
= "Getting vim-id='{}' from db".format(vim_id
)
153 db_vim
= self
.db
.get_one("vim_accounts", {"_id": vim_id
})
155 # look if previous tasks in process
156 task_name
, task_dependency
= self
.lcm_tasks
.lookfor_related("vim_account", vim_id
, order_id
)
158 step
= "Waiting for related tasks to be completed: {}".format(task_name
)
159 self
.logger
.debug(logging_text
+ step
)
160 # TODO write this to database
161 _
, pending
= await asyncio
.wait(task_dependency
, timeout
=3600)
163 raise LcmException("Timeout waiting related tasks to be completed")
165 if db_vim
.get("_admin") and db_vim
["_admin"].get("deployed") and db_vim
["_admin"]["deployed"].get("RO"):
166 if vim_content
.get("config") and vim_content
["config"].get("sdn-controller"):
167 step
= "Getting sdn-controller-id='{}' from db".format(vim_content
["config"]["sdn-controller"])
168 db_sdn
= self
.db
.get_one("sdns", {"_id": vim_content
["config"]["sdn-controller"]})
170 # look if previous tasks in process
171 task_name
, task_dependency
= self
.lcm_tasks
.lookfor_related("sdn", db_sdn
["_id"])
173 step
= "Waiting for related tasks to be completed: {}".format(task_name
)
174 self
.logger
.debug(logging_text
+ step
)
175 # TODO write this to database
176 _
, pending
= await asyncio
.wait(task_dependency
, timeout
=3600)
178 raise LcmException("Timeout waiting related tasks to be completed")
180 if db_sdn
.get("_admin") and db_sdn
["_admin"].get("deployed") and db_sdn
["_admin"]["deployed"].get(
182 RO_sdn_id
= db_sdn
["_admin"]["deployed"]["RO"]
184 raise LcmException("sdn-controller={} is not available. Not deployed at RO".format(
185 vim_content
["config"]["sdn-controller"]))
187 RO_vim_id
= db_vim
["_admin"]["deployed"]["RO"]
188 step
= "Editing vim at RO"
189 RO
= ROclient
.ROClient(self
.loop
, **self
.ro_config
)
190 vim_RO
= deepcopy(vim_content
)
191 vim_RO
.pop("_id", None)
192 vim_RO
.pop("_admin", None)
193 schema_version
= vim_RO
.pop("schema_version", None)
194 vim_RO
.pop("schema_type", None)
195 vim_RO
.pop("vim_tenant_name", None)
196 if "vim_type" in vim_RO
:
197 vim_RO
["type"] = vim_RO
.pop("vim_type")
198 vim_RO
.pop("vim_user", None)
199 vim_RO
.pop("vim_password", None)
201 vim_RO
["config"]["sdn-controller"] = RO_sdn_id
202 # TODO make a deep update of sdn-port-mapping
204 await RO
.edit("vim", RO_vim_id
, descriptor
=vim_RO
)
206 step
= "Editing vim-account at RO tenant"
208 if "config" in vim_content
:
209 if "sdn-controller" in vim_content
["config"]:
210 del vim_content
["config"]["sdn-controller"]
211 if "sdn-port-mapping" in vim_content
["config"]:
212 del vim_content
["config"]["sdn-port-mapping"]
213 if not vim_content
["config"]:
214 del vim_content
["config"]
215 if "vim_tenant_name" in vim_content
:
216 vim_account_RO
["vim_tenant_name"] = vim_content
["vim_tenant_name"]
217 if "vim_password" in vim_content
:
218 vim_account_RO
["vim_password"] = vim_content
["vim_password"]
219 if vim_content
.get("vim_password"):
220 vim_account_RO
["vim_password"] = self
.db
.decrypt(vim_content
["vim_password"],
221 schema_version
=schema_version
,
223 if "config" in vim_content
:
224 vim_account_RO
["config"] = vim_content
["config"]
225 if vim_content
.get("config"):
226 for p
in self
.vim_config_encrypted
:
227 if vim_content
["config"].get(p
):
228 vim_account_RO
["config"][p
] = self
.db
.decrypt(vim_content
["config"][p
],
229 schema_version
=schema_version
,
232 if "vim_user" in vim_content
:
233 vim_content
["vim_username"] = vim_content
["vim_user"]
234 # vim_account must be edited always even if empty in order to ensure changes are translated to RO
235 # vim_thread. RO will remove and relaunch a new thread for this vim_account
236 await RO
.edit("vim_account", RO_vim_id
, descriptor
=vim_account_RO
)
237 db_vim_update
["_admin.operationalState"] = "ENABLED"
239 self
.logger
.debug(logging_text
+ "Exit Ok RO_vim_id={}".format(RO_vim_id
))
242 except (ROclient
.ROClientException
, DbException
) as e
:
243 self
.logger
.error(logging_text
+ "Exit Exception {}".format(e
))
245 except Exception as e
:
246 self
.logger
.critical(logging_text
+ "Exit Exception {}".format(e
), exc_info
=True)
250 db_vim_update
["_admin.operationalState"] = "ERROR"
251 db_vim_update
["_admin.detailed-status"] = "ERROR {}: {}".format(step
, exc
)
254 self
.update_db_2("vim_accounts", vim_id
, db_vim_update
)
255 except DbException
as e
:
256 self
.logger
.error(logging_text
+ "Cannot update database: {}".format(e
))
258 self
.lcm_tasks
.remove("vim_account", vim_id
, order_id
)
260 async def delete(self
, vim_id
, order_id
):
261 logging_text
= "Task vim_delete={} ".format(vim_id
)
262 self
.logger
.debug(logging_text
+ "Enter")
266 step
= "Getting vim from db"
268 db_vim
= self
.db
.get_one("vim_accounts", {"_id": vim_id
})
269 if db_vim
.get("_admin") and db_vim
["_admin"].get("deployed") and db_vim
["_admin"]["deployed"].get("RO"):
270 RO_vim_id
= db_vim
["_admin"]["deployed"]["RO"]
271 RO
= ROclient
.ROClient(self
.loop
, **self
.ro_config
)
272 step
= "Detaching vim from RO tenant"
274 await RO
.detach("vim_account", RO_vim_id
)
275 except ROclient
.ROClientException
as e
:
276 if e
.http_code
== 404: # not found
277 self
.logger
.debug(logging_text
+ "RO_vim_id={} already detached".format(RO_vim_id
))
281 step
= "Deleting vim from RO"
283 await RO
.delete("vim", RO_vim_id
)
284 except ROclient
.ROClientException
as e
:
285 if e
.http_code
== 404: # not found
286 self
.logger
.debug(logging_text
+ "RO_vim_id={} already deleted".format(RO_vim_id
))
291 self
.logger
.error(logging_text
+ "Nohing to remove at RO")
292 self
.db
.del_one("vim_accounts", {"_id": vim_id
})
294 self
.logger
.debug(logging_text
+ "Exit Ok")
297 except (ROclient
.ROClientException
, DbException
) as e
:
298 self
.logger
.error(logging_text
+ "Exit Exception {}".format(e
))
300 except Exception as e
:
301 self
.logger
.critical(logging_text
+ "Exit Exception {}".format(e
), exc_info
=True)
304 self
.lcm_tasks
.remove("vim_account", vim_id
, order_id
)
306 db_vim_update
["_admin.operationalState"] = "ERROR"
307 db_vim_update
["_admin.detailed-status"] = "ERROR {}: {}".format(step
, exc
)
309 if db_vim
and db_vim_update
:
310 self
.update_db_2("vim_accounts", vim_id
, db_vim_update
)
311 except DbException
as e
:
312 self
.logger
.error(logging_text
+ "Cannot update database: {}".format(e
))
313 self
.lcm_tasks
.remove("vim_account", vim_id
, order_id
)
316 class WimLcm(LcmBase
):
317 # values that are encrypted at wim config because they are passwords
318 wim_config_encrypted
= ()
320 def __init__(self
, db
, msg
, fs
, lcm_tasks
, ro_config
, loop
):
322 Init, Connect to database, filesystem storage, and messaging
323 :param config: two level dictionary with configuration. Top level should contain 'database', 'storage',
327 self
.logger
= logging
.getLogger('lcm.vim')
329 self
.lcm_tasks
= lcm_tasks
330 self
.ro_config
= ro_config
332 super().__init
__(db
, msg
, fs
, self
.logger
)
334 async def create(self
, wim_content
, order_id
):
335 wim_id
= wim_content
["_id"]
336 wim_content
.pop("op_id", None)
337 logging_text
= "Task wim_create={} ".format(wim_id
)
338 self
.logger
.debug(logging_text
+ "Enter")
343 step
= "Getting wim-id='{}' from db".format(wim_id
)
344 db_wim
= self
.db
.get_one("wim_accounts", {"_id": wim_id
})
345 db_wim_update
["_admin.deployed.RO"] = None
347 step
= "Creating wim at RO"
348 db_wim_update
["_admin.detailed-status"] = step
349 self
.update_db_2("wim_accounts", wim_id
, db_wim_update
)
350 RO
= ROclient
.ROClient(self
.loop
, **self
.ro_config
)
351 wim_RO
= deepcopy(wim_content
)
352 wim_RO
.pop("_id", None)
353 wim_RO
.pop("_admin", None)
354 schema_version
= wim_RO
.pop("schema_version", None)
355 wim_RO
.pop("schema_type", None)
356 wim_RO
.pop("wim_tenant_name", None)
357 wim_RO
["type"] = wim_RO
.pop("wim_type")
358 wim_RO
.pop("wim_user", None)
359 wim_RO
.pop("wim_password", None)
360 desc
= await RO
.create("wim", descriptor
=wim_RO
)
361 RO_wim_id
= desc
["uuid"]
362 db_wim_update
["_admin.deployed.RO"] = RO_wim_id
363 self
.logger
.debug(logging_text
+ "WIM created at RO_wim_id={}".format(RO_wim_id
))
365 step
= "Creating wim_account at RO"
366 db_wim_update
["_admin.detailed-status"] = step
367 self
.update_db_2("wim_accounts", wim_id
, db_wim_update
)
369 if wim_content
.get("wim_password"):
370 wim_content
["wim_password"] = self
.db
.decrypt(wim_content
["wim_password"],
371 schema_version
=schema_version
,
373 wim_account_RO
= {"name": wim_content
["name"],
374 "user": wim_content
["user"],
375 "password": wim_content
["password"]
377 if wim_RO
.get("config"):
378 wim_account_RO
["config"] = wim_RO
["config"]
379 if "wim_port_mapping" in wim_account_RO
["config"]:
380 del wim_account_RO
["config"]["wim_port_mapping"]
381 for p
in self
.wim_config_encrypted
:
382 if wim_account_RO
["config"].get(p
):
383 wim_account_RO
["config"][p
] = self
.db
.decrypt(wim_account_RO
["config"][p
],
384 schema_version
=schema_version
,
387 desc
= await RO
.attach("wim_account", RO_wim_id
, descriptor
=wim_account_RO
)
388 db_wim_update
["_admin.deployed.RO-account"] = desc
["uuid"]
389 db_wim_update
["_admin.operationalState"] = "ENABLED"
390 db_wim_update
["_admin.detailed-status"] = "Done"
392 self
.logger
.debug(logging_text
+ "Exit Ok WIM account created at RO_wim_account_id={}".format(desc
["uuid"]))
395 except (ROclient
.ROClientException
, DbException
) as e
:
396 self
.logger
.error(logging_text
+ "Exit Exception {}".format(e
))
398 except Exception as e
:
399 self
.logger
.critical(logging_text
+ "Exit Exception {}".format(e
), exc_info
=True)
403 db_wim_update
["_admin.operationalState"] = "ERROR"
404 db_wim_update
["_admin.detailed-status"] = "ERROR {}: {}".format(step
, exc
)
407 self
.update_db_2("wim_accounts", wim_id
, db_wim_update
)
408 except DbException
as e
:
409 self
.logger
.error(logging_text
+ "Cannot update database: {}".format(e
))
410 self
.lcm_tasks
.remove("wim_account", wim_id
, order_id
)
412 async def edit(self
, wim_content
, order_id
):
413 wim_id
= wim_content
["_id"]
414 wim_content
.pop("op_id", None)
415 logging_text
= "Task wim_edit={} ".format(wim_id
)
416 self
.logger
.debug(logging_text
+ "Enter")
421 step
= "Getting wim-id='{}' from db".format(wim_id
)
423 db_wim
= self
.db
.get_one("wim_accounts", {"_id": wim_id
})
425 # look if previous tasks in process
426 task_name
, task_dependency
= self
.lcm_tasks
.lookfor_related("wim_account", wim_id
, order_id
)
428 step
= "Waiting for related tasks to be completed: {}".format(task_name
)
429 self
.logger
.debug(logging_text
+ step
)
430 # TODO write this to database
431 _
, pending
= await asyncio
.wait(task_dependency
, timeout
=3600)
433 raise LcmException("Timeout waiting related tasks to be completed")
435 if db_wim
.get("_admin") and db_wim
["_admin"].get("deployed") and db_wim
["_admin"]["deployed"].get("RO"):
437 RO_wim_id
= db_wim
["_admin"]["deployed"]["RO"]
438 step
= "Editing wim at RO"
439 RO
= ROclient
.ROClient(self
.loop
, **self
.ro_config
)
440 wim_RO
= deepcopy(wim_content
)
441 wim_RO
.pop("_id", None)
442 wim_RO
.pop("_admin", None)
443 schema_version
= wim_RO
.pop("schema_version", None)
444 wim_RO
.pop("schema_type", None)
445 wim_RO
.pop("wim_tenant_name", None)
446 if "wim_type" in wim_RO
:
447 wim_RO
["type"] = wim_RO
.pop("wim_type")
448 wim_RO
.pop("wim_user", None)
449 wim_RO
.pop("wim_password", None)
450 # TODO make a deep update of wim_port_mapping
452 await RO
.edit("wim", RO_wim_id
, descriptor
=wim_RO
)
454 step
= "Editing wim-account at RO tenant"
456 if "config" in wim_content
:
457 if "wim_port_mapping" in wim_content
["config"]:
458 del wim_content
["config"]["wim_port_mapping"]
459 if not wim_content
["config"]:
460 del wim_content
["config"]
461 if "wim_tenant_name" in wim_content
:
462 wim_account_RO
["wim_tenant_name"] = wim_content
["wim_tenant_name"]
463 if "wim_password" in wim_content
:
464 wim_account_RO
["wim_password"] = wim_content
["wim_password"]
465 if wim_content
.get("wim_password"):
466 wim_account_RO
["wim_password"] = self
.db
.decrypt(wim_content
["wim_password"],
467 schema_version
=schema_version
,
469 if "config" in wim_content
:
470 wim_account_RO
["config"] = wim_content
["config"]
471 if wim_content
.get("config"):
472 for p
in self
.wim_config_encrypted
:
473 if wim_content
["config"].get(p
):
474 wim_account_RO
["config"][p
] = self
.db
.decrypt(wim_content
["config"][p
],
475 schema_version
=schema_version
,
478 if "wim_user" in wim_content
:
479 wim_content
["wim_username"] = wim_content
["wim_user"]
480 # wim_account must be edited always even if empty in order to ensure changes are translated to RO
481 # wim_thread. RO will remove and relaunch a new thread for this wim_account
482 await RO
.edit("wim_account", RO_wim_id
, descriptor
=wim_account_RO
)
483 db_wim_update
["_admin.operationalState"] = "ENABLED"
485 self
.logger
.debug(logging_text
+ "Exit Ok RO_wim_id={}".format(RO_wim_id
))
488 except (ROclient
.ROClientException
, DbException
) as e
:
489 self
.logger
.error(logging_text
+ "Exit Exception {}".format(e
))
491 except Exception as e
:
492 self
.logger
.critical(logging_text
+ "Exit Exception {}".format(e
), exc_info
=True)
496 db_wim_update
["_admin.operationalState"] = "ERROR"
497 db_wim_update
["_admin.detailed-status"] = "ERROR {}: {}".format(step
, exc
)
500 self
.update_db_2("wim_accounts", wim_id
, db_wim_update
)
501 except DbException
as e
:
502 self
.logger
.error(logging_text
+ "Cannot update database: {}".format(e
))
503 self
.lcm_tasks
.remove("wim_account", wim_id
, order_id
)
505 async def delete(self
, wim_id
, order_id
):
506 logging_text
= "Task wim_delete={} ".format(wim_id
)
507 self
.logger
.debug(logging_text
+ "Enter")
511 step
= "Getting wim from db"
513 db_wim
= self
.db
.get_one("wim_accounts", {"_id": wim_id
})
514 if db_wim
.get("_admin") and db_wim
["_admin"].get("deployed") and db_wim
["_admin"]["deployed"].get("RO"):
515 RO_wim_id
= db_wim
["_admin"]["deployed"]["RO"]
516 RO
= ROclient
.ROClient(self
.loop
, **self
.ro_config
)
517 step
= "Detaching wim from RO tenant"
519 await RO
.detach("wim_account", RO_wim_id
)
520 except ROclient
.ROClientException
as e
:
521 if e
.http_code
== 404: # not found
522 self
.logger
.debug(logging_text
+ "RO_wim_id={} already detached".format(RO_wim_id
))
526 step
= "Deleting wim from RO"
528 await RO
.delete("wim", RO_wim_id
)
529 except ROclient
.ROClientException
as e
:
530 if e
.http_code
== 404: # not found
531 self
.logger
.debug(logging_text
+ "RO_wim_id={} already deleted".format(RO_wim_id
))
536 self
.logger
.error(logging_text
+ "Nohing to remove at RO")
537 self
.db
.del_one("wim_accounts", {"_id": wim_id
})
539 self
.logger
.debug(logging_text
+ "Exit Ok")
542 except (ROclient
.ROClientException
, DbException
) as e
:
543 self
.logger
.error(logging_text
+ "Exit Exception {}".format(e
))
545 except Exception as e
:
546 self
.logger
.critical(logging_text
+ "Exit Exception {}".format(e
), exc_info
=True)
549 self
.lcm_tasks
.remove("wim_account", wim_id
, order_id
)
551 db_wim_update
["_admin.operationalState"] = "ERROR"
552 db_wim_update
["_admin.detailed-status"] = "ERROR {}: {}".format(step
, exc
)
554 if db_wim
and db_wim_update
:
555 self
.update_db_2("wim_accounts", wim_id
, db_wim_update
)
556 except DbException
as e
:
557 self
.logger
.error(logging_text
+ "Cannot update database: {}".format(e
))
558 self
.lcm_tasks
.remove("wim_account", wim_id
, order_id
)
561 class SdnLcm(LcmBase
):
563 def __init__(self
, db
, msg
, fs
, lcm_tasks
, ro_config
, loop
):
565 Init, Connect to database, filesystem storage, and messaging
566 :param config: two level dictionary with configuration. Top level should contain 'database', 'storage',
570 self
.logger
= logging
.getLogger('lcm.sdn')
572 self
.lcm_tasks
= lcm_tasks
573 self
.ro_config
= ro_config
575 super().__init
__(db
, msg
, fs
, self
.logger
)
577 async def create(self
, sdn_content
, order_id
):
578 sdn_id
= sdn_content
["_id"]
579 sdn_content
.pop("op_id", None)
580 logging_text
= "Task sdn_create={} ".format(sdn_id
)
581 self
.logger
.debug(logging_text
+ "Enter")
587 step
= "Getting sdn from db"
588 db_sdn
= self
.db
.get_one("sdns", {"_id": sdn_id
})
589 db_sdn_update
["_admin.deployed.RO"] = None
591 step
= "Creating sdn at RO"
592 db_sdn_update
["_admin.detailed-status"] = step
593 self
.update_db_2("sdns", sdn_id
, db_sdn_update
)
595 RO
= ROclient
.ROClient(self
.loop
, **self
.ro_config
)
596 sdn_RO
= deepcopy(sdn_content
)
597 sdn_RO
.pop("_id", None)
598 sdn_RO
.pop("_admin", None)
599 schema_version
= sdn_RO
.pop("schema_version", None)
600 sdn_RO
.pop("schema_type", None)
601 sdn_RO
.pop("description", None)
602 if sdn_RO
.get("password"):
603 sdn_RO
["password"] = self
.db
.decrypt(sdn_RO
["password"], schema_version
=schema_version
, salt
=sdn_id
)
605 desc
= await RO
.create("sdn", descriptor
=sdn_RO
)
606 RO_sdn_id
= desc
["uuid"]
607 db_sdn_update
["_admin.deployed.RO"] = RO_sdn_id
608 db_sdn_update
["_admin.operationalState"] = "ENABLED"
609 self
.logger
.debug(logging_text
+ "Exit Ok RO_sdn_id={}".format(RO_sdn_id
))
612 except (ROclient
.ROClientException
, DbException
) as e
:
613 self
.logger
.error(logging_text
+ "Exit Exception {}".format(e
))
615 except Exception as e
:
616 self
.logger
.critical(logging_text
+ "Exit Exception {}".format(e
), exc_info
=True)
620 db_sdn_update
["_admin.operationalState"] = "ERROR"
621 db_sdn_update
["_admin.detailed-status"] = "ERROR {}: {}".format(step
, exc
)
623 if db_sdn
and db_sdn_update
:
624 self
.update_db_2("sdns", sdn_id
, db_sdn_update
)
625 except DbException
as e
:
626 self
.logger
.error(logging_text
+ "Cannot update database: {}".format(e
))
627 self
.lcm_tasks
.remove("sdn", sdn_id
, order_id
)
629 async def edit(self
, sdn_content
, order_id
):
630 sdn_id
= sdn_content
["_id"]
631 sdn_content
.pop("op_id", None)
632 logging_text
= "Task sdn_edit={} ".format(sdn_id
)
633 self
.logger
.debug(logging_text
+ "Enter")
637 step
= "Getting sdn from db"
639 db_sdn
= self
.db
.get_one("sdns", {"_id": sdn_id
})
641 if db_sdn
.get("_admin") and db_sdn
["_admin"].get("deployed") and db_sdn
["_admin"]["deployed"].get("RO"):
642 RO_sdn_id
= db_sdn
["_admin"]["deployed"]["RO"]
643 RO
= ROclient
.ROClient(self
.loop
, **self
.ro_config
)
644 step
= "Editing sdn at RO"
645 sdn_RO
= deepcopy(sdn_content
)
646 sdn_RO
.pop("_id", None)
647 sdn_RO
.pop("_admin", None)
648 schema_version
= sdn_RO
.pop("schema_version", None)
649 sdn_RO
.pop("schema_type", None)
650 sdn_RO
.pop("description", None)
651 if sdn_RO
.get("password"):
652 sdn_RO
["password"] = self
.db
.decrypt(sdn_RO
["password"], schema_version
=schema_version
, salt
=sdn_id
)
654 await RO
.edit("sdn", RO_sdn_id
, descriptor
=sdn_RO
)
655 db_sdn_update
["_admin.operationalState"] = "ENABLED"
657 self
.logger
.debug(logging_text
+ "Exit Ok RO_sdn_id={}".format(RO_sdn_id
))
660 except (ROclient
.ROClientException
, DbException
) as e
:
661 self
.logger
.error(logging_text
+ "Exit Exception {}".format(e
))
663 except Exception as e
:
664 self
.logger
.critical(logging_text
+ "Exit Exception {}".format(e
), exc_info
=True)
668 db_sdn
["_admin.operationalState"] = "ERROR"
669 db_sdn
["_admin.detailed-status"] = "ERROR {}: {}".format(step
, exc
)
672 self
.update_db_2("sdns", sdn_id
, db_sdn_update
)
673 except DbException
as e
:
674 self
.logger
.error(logging_text
+ "Cannot update database: {}".format(e
))
675 self
.lcm_tasks
.remove("sdn", sdn_id
, order_id
)
677 async def delete(self
, sdn_id
, order_id
):
678 logging_text
= "Task sdn_delete={} ".format(sdn_id
)
679 self
.logger
.debug(logging_text
+ "Enter")
683 step
= "Getting sdn from db"
685 db_sdn
= self
.db
.get_one("sdns", {"_id": sdn_id
})
686 if db_sdn
.get("_admin") and db_sdn
["_admin"].get("deployed") and db_sdn
["_admin"]["deployed"].get("RO"):
687 RO_sdn_id
= db_sdn
["_admin"]["deployed"]["RO"]
688 RO
= ROclient
.ROClient(self
.loop
, **self
.ro_config
)
689 step
= "Deleting sdn from RO"
691 await RO
.delete("sdn", RO_sdn_id
)
692 except ROclient
.ROClientException
as e
:
693 if e
.http_code
== 404: # not found
694 self
.logger
.debug(logging_text
+ "RO_sdn_id={} already deleted".format(RO_sdn_id
))
699 self
.logger
.error(logging_text
+ "Skipping. There is not RO information at database")
700 self
.db
.del_one("sdns", {"_id": sdn_id
})
702 self
.logger
.debug("sdn_delete task sdn_id={} Exit Ok".format(sdn_id
))
705 except (ROclient
.ROClientException
, DbException
) as e
:
706 self
.logger
.error(logging_text
+ "Exit Exception {}".format(e
))
708 except Exception as e
:
709 self
.logger
.critical(logging_text
+ "Exit Exception {}".format(e
), exc_info
=True)
713 db_sdn
["_admin.operationalState"] = "ERROR"
714 db_sdn
["_admin.detailed-status"] = "ERROR {}: {}".format(step
, exc
)
716 if db_sdn
and db_sdn_update
:
717 self
.update_db_2("sdns", sdn_id
, db_sdn_update
)
718 except DbException
as e
:
719 self
.logger
.error(logging_text
+ "Cannot update database: {}".format(e
))
720 self
.lcm_tasks
.remove("sdn", sdn_id
, order_id
)