2 # -*- coding: utf-8 -*-
6 import logging
.handlers
8 from lcm_utils
import LcmException
, LcmBase
9 from osm_common
.dbbase
import DbException
10 from copy
import deepcopy
12 __author__
= "Alfonso Tierno"
15 class VimLcm(LcmBase
):
17 def __init__(self
, db
, msg
, fs
, lcm_tasks
, ro_config
, loop
):
19 Init, Connect to database, filesystem storage, and messaging
20 :param config: two level dictionary with configuration. Top level should contain 'database', 'storage',
24 self
.logger
= logging
.getLogger('lcm.vim')
26 self
.lcm_tasks
= lcm_tasks
27 self
.ro_config
= ro_config
29 super().__init
__(db
, msg
, fs
, self
.logger
)
31 async def create(self
, vim_content
, order_id
):
32 vim_id
= vim_content
["_id"]
33 logging_text
= "Task vim_create={} ".format(vim_id
)
34 self
.logger
.debug(logging_text
+ "Enter")
40 step
= "Getting vim-id='{}' from db".format(vim_id
)
41 db_vim
= self
.db
.get_one("vim_accounts", {"_id": vim_id
})
42 db_vim_update
["_admin.deployed.RO"] = None
43 if vim_content
.get("config") and vim_content
["config"].get("sdn-controller"):
44 step
= "Getting sdn-controller-id='{}' from db".format(vim_content
["config"]["sdn-controller"])
45 db_sdn
= self
.db
.get_one("sdns", {"_id": vim_content
["config"]["sdn-controller"]})
46 if db_sdn
.get("_admin") and db_sdn
["_admin"].get("deployed") and db_sdn
["_admin"]["deployed"].get("RO"):
47 RO_sdn_id
= db_sdn
["_admin"]["deployed"]["RO"]
49 raise LcmException("sdn-controller={} is not available. Not deployed at RO".format(
50 vim_content
["config"]["sdn-controller"]))
52 step
= "Creating vim at RO"
53 db_vim_update
["_admin.detailed-status"] = step
54 self
.update_db_2("vim_accounts", vim_id
, db_vim_update
)
55 RO
= ROclient
.ROClient(self
.loop
, **self
.ro_config
)
56 vim_RO
= deepcopy(vim_content
)
57 vim_RO
.pop("_id", None)
58 vim_RO
.pop("_admin", None)
59 vim_RO
.pop("schema_version", None)
60 vim_RO
.pop("schema_type", None)
61 vim_RO
.pop("vim_tenant_name", None)
62 vim_RO
["type"] = vim_RO
.pop("vim_type")
63 vim_RO
.pop("vim_user", None)
64 vim_RO
.pop("vim_password", None)
66 vim_RO
["config"]["sdn-controller"] = RO_sdn_id
67 desc
= await RO
.create("vim", descriptor
=vim_RO
)
68 RO_vim_id
= desc
["uuid"]
69 db_vim_update
["_admin.deployed.RO"] = RO_vim_id
71 step
= "Creating vim_account at RO"
72 db_vim_update
["_admin.detailed-status"] = step
73 self
.update_db_2("vim_accounts", vim_id
, db_vim_update
)
75 vim_account_RO
= {"vim_tenant_name": vim_content
["vim_tenant_name"],
76 "vim_username": vim_content
["vim_user"],
77 "vim_password": vim_content
["vim_password"]
79 if vim_RO
.get("config"):
80 vim_account_RO
["config"] = vim_RO
["config"]
81 if "sdn-controller" in vim_account_RO
["config"]:
82 del vim_account_RO
["config"]["sdn-controller"]
83 if "sdn-port-mapping" in vim_account_RO
["config"]:
84 del vim_account_RO
["config"]["sdn-port-mapping"]
85 desc
= await RO
.attach_datacenter(RO_vim_id
, descriptor
=vim_account_RO
)
86 db_vim_update
["_admin.deployed.RO-account"] = desc
["uuid"]
87 db_vim_update
["_admin.operationalState"] = "ENABLED"
88 db_vim_update
["_admin.detailed-status"] = "Done"
90 # await asyncio.sleep(15) # TODO remove. This is for test
91 self
.logger
.debug(logging_text
+ "Exit Ok RO_vim_id={}".format(RO_vim_id
))
94 except (ROclient
.ROClientException
, DbException
) as e
:
95 self
.logger
.error(logging_text
+ "Exit Exception {}".format(e
))
97 except Exception as e
:
98 self
.logger
.critical(logging_text
+ "Exit Exception {}".format(e
), exc_info
=True)
102 db_vim_update
["_admin.operationalState"] = "ERROR"
103 db_vim_update
["_admin.detailed-status"] = "ERROR {}: {}".format(step
, exc
)
105 self
.update_db_2("vim_accounts", vim_id
, db_vim_update
)
106 self
.lcm_tasks
.remove("vim_account", vim_id
, order_id
)
108 async def edit(self
, vim_content
, order_id
):
109 vim_id
= vim_content
["_id"]
110 logging_text
= "Task vim_edit={} ".format(vim_id
)
111 self
.logger
.debug(logging_text
+ "Enter")
117 step
= "Getting vim-id='{}' from db".format(vim_id
)
119 db_vim
= self
.db
.get_one("vim_accounts", {"_id": vim_id
})
121 # look if previous tasks in process
122 task_name
, task_dependency
= self
.lcm_tasks
.lookfor_related("vim_account", vim_id
, order_id
)
124 step
= "Waiting for related tasks to be completed: {}".format(task_name
)
125 self
.logger
.debug(logging_text
+ step
)
126 # TODO write this to database
127 _
, pending
= await asyncio
.wait(task_dependency
, timeout
=3600)
129 raise LcmException("Timeout waiting related tasks to be completed")
131 if db_vim
.get("_admin") and db_vim
["_admin"].get("deployed") and db_vim
["_admin"]["deployed"].get("RO"):
132 if vim_content
.get("config") and vim_content
["config"].get("sdn-controller"):
133 step
= "Getting sdn-controller-id='{}' from db".format(vim_content
["config"]["sdn-controller"])
134 db_sdn
= self
.db
.get_one("sdns", {"_id": vim_content
["config"]["sdn-controller"]})
136 # look if previous tasks in process
137 task_name
, task_dependency
= self
.lcm_tasks
.lookfor_related("sdn", db_sdn
["_id"])
139 step
= "Waiting for related tasks to be completed: {}".format(task_name
)
140 self
.logger
.debug(logging_text
+ step
)
141 # TODO write this to database
142 _
, pending
= await asyncio
.wait(task_dependency
, timeout
=3600)
144 raise LcmException("Timeout waiting related tasks to be completed")
146 if db_sdn
.get("_admin") and db_sdn
["_admin"].get("deployed") and db_sdn
["_admin"]["deployed"].get(
148 RO_sdn_id
= db_sdn
["_admin"]["deployed"]["RO"]
150 raise LcmException("sdn-controller={} is not available. Not deployed at RO".format(
151 vim_content
["config"]["sdn-controller"]))
153 RO_vim_id
= db_vim
["_admin"]["deployed"]["RO"]
154 step
= "Editing vim at RO"
155 RO
= ROclient
.ROClient(self
.loop
, **self
.ro_config
)
156 vim_RO
= deepcopy(vim_content
)
157 vim_RO
.pop("_id", None)
158 vim_RO
.pop("_admin", None)
159 vim_RO
.pop("schema_version", None)
160 vim_RO
.pop("schema_type", None)
161 vim_RO
.pop("vim_tenant_name", None)
162 if "vim_type" in vim_RO
:
163 vim_RO
["type"] = vim_RO
.pop("vim_type")
164 vim_RO
.pop("vim_user", None)
165 vim_RO
.pop("vim_password", None)
167 vim_RO
["config"]["sdn-controller"] = RO_sdn_id
168 # TODO make a deep update of sdn-port-mapping
170 await RO
.edit("vim", RO_vim_id
, descriptor
=vim_RO
)
172 step
= "Editing vim-account at RO tenant"
174 if "config" in vim_content
:
175 if "sdn-controller" in vim_content
["config"]:
176 del vim_content
["config"]["sdn-controller"]
177 if "sdn-port-mapping" in vim_content
["config"]:
178 del vim_content
["config"]["sdn-port-mapping"]
179 if not vim_content
["config"]:
180 del vim_content
["config"]
181 for k
in ("vim_tenant_name", "vim_password", "config"):
183 vim_account_RO
[k
] = vim_content
[k
]
184 if "vim_user" in vim_content
:
185 vim_content
["vim_username"] = vim_content
["vim_user"]
186 # vim_account must be edited always even if empty in order to ensure changes are translated to RO
187 # vim_thread. RO will remove and relaunch a new thread for this vim_account
188 await RO
.edit("vim_account", RO_vim_id
, descriptor
=vim_account_RO
)
189 db_vim_update
["_admin.operationalState"] = "ENABLED"
191 self
.logger
.debug(logging_text
+ "Exit Ok RO_vim_id={}".format(RO_vim_id
))
194 except (ROclient
.ROClientException
, DbException
) as e
:
195 self
.logger
.error(logging_text
+ "Exit Exception {}".format(e
))
197 except Exception as e
:
198 self
.logger
.critical(logging_text
+ "Exit Exception {}".format(e
), exc_info
=True)
202 db_vim_update
["_admin.operationalState"] = "ERROR"
203 db_vim_update
["_admin.detailed-status"] = "ERROR {}: {}".format(step
, exc
)
205 self
.update_db_2("vim_accounts", vim_id
, db_vim_update
)
206 self
.lcm_tasks
.remove("vim_account", vim_id
, order_id
)
208 async def delete(self
, vim_id
, order_id
):
209 logging_text
= "Task vim_delete={} ".format(vim_id
)
210 self
.logger
.debug(logging_text
+ "Enter")
214 step
= "Getting vim from db"
216 db_vim
= self
.db
.get_one("vim_accounts", {"_id": vim_id
})
217 if db_vim
.get("_admin") and db_vim
["_admin"].get("deployed") and db_vim
["_admin"]["deployed"].get("RO"):
218 RO_vim_id
= db_vim
["_admin"]["deployed"]["RO"]
219 RO
= ROclient
.ROClient(self
.loop
, **self
.ro_config
)
220 step
= "Detaching vim from RO tenant"
222 await RO
.detach_datacenter(RO_vim_id
)
223 except ROclient
.ROClientException
as e
:
224 if e
.http_code
== 404: # not found
225 self
.logger
.debug(logging_text
+ "RO_vim_id={} already detached".format(RO_vim_id
))
229 step
= "Deleting vim from RO"
231 await RO
.delete("vim", RO_vim_id
)
232 except ROclient
.ROClientException
as e
:
233 if e
.http_code
== 404: # not found
234 self
.logger
.debug(logging_text
+ "RO_vim_id={} already deleted".format(RO_vim_id
))
239 self
.logger
.error(logging_text
+ "Nohing to remove at RO")
240 self
.db
.del_one("vim_accounts", {"_id": vim_id
})
241 self
.logger
.debug(logging_text
+ "Exit Ok")
244 except (ROclient
.ROClientException
, DbException
) as e
:
245 self
.logger
.error(logging_text
+ "Exit Exception {}".format(e
))
247 except Exception as e
:
248 self
.logger
.critical(logging_text
+ "Exit Exception {}".format(e
), exc_info
=True)
251 self
.lcm_tasks
.remove("vim_account", vim_id
, order_id
)
253 db_vim_update
["_admin.operationalState"] = "ERROR"
254 db_vim_update
["_admin.detailed-status"] = "ERROR {}: {}".format(step
, exc
)
256 self
.update_db_2("vim_accounts", vim_id
, db_vim_update
)
257 self
.lcm_tasks
.remove("vim_account", vim_id
, order_id
)
260 class SdnLcm(LcmBase
):
262 def __init__(self
, db
, msg
, fs
, lcm_tasks
, ro_config
, loop
):
264 Init, Connect to database, filesystem storage, and messaging
265 :param config: two level dictionary with configuration. Top level should contain 'database', 'storage',
269 self
.logger
= logging
.getLogger('lcm.sdn')
271 self
.lcm_tasks
= lcm_tasks
272 self
.ro_config
= ro_config
274 super().__init
__(db
, msg
, fs
, self
.logger
)
276 async def create(self
, sdn_content
, order_id
):
277 sdn_id
= sdn_content
["_id"]
278 logging_text
= "Task sdn_create={} ".format(sdn_id
)
279 self
.logger
.debug(logging_text
+ "Enter")
285 step
= "Getting sdn from db"
286 db_sdn
= self
.db
.get_one("sdns", {"_id": sdn_id
})
287 db_sdn_update
["_admin.deployed.RO"] = None
289 step
= "Creating sdn at RO"
290 RO
= ROclient
.ROClient(self
.loop
, **self
.ro_config
)
291 sdn_RO
= deepcopy(sdn_content
)
292 sdn_RO
.pop("_id", None)
293 sdn_RO
.pop("_admin", None)
294 sdn_RO
.pop("schema_version", None)
295 sdn_RO
.pop("schema_type", None)
296 sdn_RO
.pop("description", None)
297 desc
= await RO
.create("sdn", descriptor
=sdn_RO
)
298 RO_sdn_id
= desc
["uuid"]
299 db_sdn_update
["_admin.deployed.RO"] = RO_sdn_id
300 db_sdn_update
["_admin.operationalState"] = "ENABLED"
301 self
.logger
.debug(logging_text
+ "Exit Ok RO_sdn_id={}".format(RO_sdn_id
))
304 except (ROclient
.ROClientException
, DbException
) as e
:
305 self
.logger
.error(logging_text
+ "Exit Exception {}".format(e
))
307 except Exception as e
:
308 self
.logger
.critical(logging_text
+ "Exit Exception {}".format(e
), exc_info
=True)
312 db_sdn_update
["_admin.operationalState"] = "ERROR"
313 db_sdn_update
["_admin.detailed-status"] = "ERROR {}: {}".format(step
, exc
)
315 self
.update_db_2("sdns", sdn_id
, db_sdn_update
)
316 self
.lcm_tasks
.remove("sdn", sdn_id
, order_id
)
318 async def edit(self
, sdn_content
, order_id
):
319 sdn_id
= sdn_content
["_id"]
320 logging_text
= "Task sdn_edit={} ".format(sdn_id
)
321 self
.logger
.debug(logging_text
+ "Enter")
325 step
= "Getting sdn from db"
327 db_sdn
= self
.db
.get_one("sdns", {"_id": sdn_id
})
328 if db_sdn
.get("_admin") and db_sdn
["_admin"].get("deployed") and db_sdn
["_admin"]["deployed"].get("RO"):
329 RO_sdn_id
= db_sdn
["_admin"]["deployed"]["RO"]
330 RO
= ROclient
.ROClient(self
.loop
, **self
.ro_config
)
331 step
= "Editing sdn at RO"
332 sdn_RO
= deepcopy(sdn_content
)
333 sdn_RO
.pop("_id", None)
334 sdn_RO
.pop("_admin", None)
335 sdn_RO
.pop("schema_version", None)
336 sdn_RO
.pop("schema_type", None)
337 sdn_RO
.pop("description", None)
339 await RO
.edit("sdn", RO_sdn_id
, descriptor
=sdn_RO
)
340 db_sdn_update
["_admin.operationalState"] = "ENABLED"
342 self
.logger
.debug(logging_text
+ "Exit Ok RO_sdn_id".format(RO_sdn_id
))
345 except (ROclient
.ROClientException
, DbException
) as e
:
346 self
.logger
.error(logging_text
+ "Exit Exception {}".format(e
))
348 except Exception as e
:
349 self
.logger
.critical(logging_text
+ "Exit Exception {}".format(e
), exc_info
=True)
353 db_sdn
["_admin.operationalState"] = "ERROR"
354 db_sdn
["_admin.detailed-status"] = "ERROR {}: {}".format(step
, exc
)
356 self
.update_db_2("sdns", sdn_id
, db_sdn_update
)
357 self
.lcm_tasks
.remove("sdn", sdn_id
, order_id
)
359 async def delete(self
, sdn_id
, order_id
):
360 logging_text
= "Task sdn_delete={} ".format(sdn_id
)
361 self
.logger
.debug(logging_text
+ "Enter")
365 step
= "Getting sdn from db"
367 db_sdn
= self
.db
.get_one("sdns", {"_id": sdn_id
})
368 if db_sdn
.get("_admin") and db_sdn
["_admin"].get("deployed") and db_sdn
["_admin"]["deployed"].get("RO"):
369 RO_sdn_id
= db_sdn
["_admin"]["deployed"]["RO"]
370 RO
= ROclient
.ROClient(self
.loop
, **self
.ro_config
)
371 step
= "Deleting sdn from RO"
373 await RO
.delete("sdn", RO_sdn_id
)
374 except ROclient
.ROClientException
as e
:
375 if e
.http_code
== 404: # not found
376 self
.logger
.debug(logging_text
+ "RO_sdn_id={} already deleted".format(RO_sdn_id
))
381 self
.logger
.error(logging_text
+ "Skipping. There is not RO information at database")
382 self
.db
.del_one("sdns", {"_id": sdn_id
})
383 self
.logger
.debug("sdn_delete task sdn_id={} Exit Ok".format(sdn_id
))
386 except (ROclient
.ROClientException
, DbException
) as e
:
387 self
.logger
.error(logging_text
+ "Exit Exception {}".format(e
))
389 except Exception as e
:
390 self
.logger
.critical(logging_text
+ "Exit Exception {}".format(e
), exc_info
=True)
394 db_sdn
["_admin.operationalState"] = "ERROR"
395 db_sdn
["_admin.detailed-status"] = "ERROR {}: {}".format(step
, exc
)
397 self
.update_db_2("sdns", sdn_id
, db_sdn_update
)
398 self
.lcm_tasks
.remove("sdn", sdn_id
, order_id
)