1 # Copyright 2021 Canonical Ltd.
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
19 from motor
.motor_asyncio
import AsyncIOMotorClient
20 from n2vc
.config
import EnvironConfig
21 from n2vc
.vca
.connection_data
import ConnectionData
22 from osm_common
.dbmongo
import DbMongo
, DbException
23 from osm_common
.dbbase
import Encryption
31 async def get_vca_connection_data(self
, vca_id
: str) -> ConnectionData
:
33 Get VCA connection data
35 :param: vca_id: VCA ID
37 :returns: ConnectionData with the information of the database
41 async def update_vca_endpoints(self
, hosts
: typing
.List
[str], vca_id
: str):
45 :param: endpoints: List of endpoints to write in the database
46 :param: vca_id: VCA ID
50 async def get_vca_endpoints(self
, vca_id
: str = None) -> typing
.List
[str]:
52 Get list if VCA endpoints
54 :param: vca_id: VCA ID
56 :returns: List of endpoints
60 async def get_vca_id(self
, vim_id
: str = None) -> str:
62 Get VCA id for a VIM account
64 :param: vim_id: Vim account ID
68 class DbMongoStore(Store
):
69 def __init__(self
, db
: DbMongo
):
73 :param: db: osm_common.dbmongo.DbMongo object
77 async def get_vca_connection_data(self
, vca_id
: str) -> ConnectionData
:
79 Get VCA connection data
81 :param: vca_id: VCA ID
83 :returns: ConnectionData with the information of the database
85 data
= self
.db
.get_one("vca", q_filter
={"_id": vca_id
})
86 self
.db
.encrypt_decrypt_fields(
90 schema_version
=data
["schema_version"],
93 return ConnectionData(**data
)
95 async def update_vca_endpoints(
96 self
, endpoints
: typing
.List
[str], vca_id
: str = None
101 :param: endpoints: List of endpoints to write in the database
102 :param: vca_id: VCA ID
105 data
= self
.db
.get_one("vca", q_filter
={"_id": vca_id
})
106 data
["endpoints"] = endpoints
107 self
._update
("vca", vca_id
, data
)
109 # The default VCA. Data for the endpoints is in a different place
110 juju_info
= self
._get
_juju
_info
()
111 # If it doesn't, then create it
118 except DbException
as e
:
119 # Racing condition: check if another N2VC worker has created it
120 juju_info
= self
._get
_juju
_info
()
126 {"api_endpoints": endpoints
},
129 async def get_vca_endpoints(self
, vca_id
: str = None) -> typing
.List
[str]:
131 Get list if VCA endpoints
133 :param: vca_id: VCA ID
135 :returns: List of endpoints
139 endpoints
= self
.get_vca_connection_data(vca_id
).endpoints
141 juju_info
= self
._get
_juju
_info
()
142 if juju_info
and "api_endpoints" in juju_info
:
143 endpoints
= juju_info
["api_endpoints"]
146 async def get_vca_id(self
, vim_id
: str = None) -> str:
148 Get VCA ID from the database for a given VIM account ID
150 :param: vim_id: VIM account ID
155 q_filter
={"_id": vim_id
},
162 def _update(self
, collection
: str, id: str, data
: dict):
164 Update object in database
166 :param: collection: Collection name
167 :param: id: ID of the object
168 :param: data: Object data
176 def _get_juju_info(self
):
177 """Get Juju information (the default VCA) from the admin collection"""
178 return self
.db
.get_one(
180 q_filter
={"_id": "juju"},
185 class MotorStore(Store
):
186 def __init__(self
, uri
: str, loop
=None):
190 :param: uri: Connection string to connect to the database.
191 :param: loop: Asyncio Loop
193 self
._client
= AsyncIOMotorClient(uri
)
194 self
.loop
= loop
or asyncio
.get_event_loop()
195 self
._secret
_key
= None
196 self
._config
= EnvironConfig(prefixes
=["OSMLCM_", "OSMMON_"])
197 self
.encryption
= Encryption(
200 encoding_type
="utf-8",
207 return self
._client
[DB_NAME
]
210 def _vca_collection(self
):
211 return self
._database
["vca"]
214 def _admin_collection(self
):
215 return self
._database
["admin"]
218 def _vim_accounts_collection(self
):
219 return self
._database
["vim_accounts"]
221 async def get_vca_connection_data(self
, vca_id
: str) -> ConnectionData
:
223 Get VCA connection data
225 :param: vca_id: VCA ID
227 :returns: ConnectionData with the information of the database
229 data
= await self
._vca
_collection
.find_one({"_id": vca_id
})
231 raise Exception("vca with id {} not found".format(vca_id
))
232 await self
.encryption
.decrypt_fields(
234 ["secret", "cacert"],
235 schema_version
=data
["schema_version"],
238 return ConnectionData(**data
)
240 async def update_vca_endpoints(
241 self
, endpoints
: typing
.List
[str], vca_id
: str = None
246 :param: endpoints: List of endpoints to write in the database
247 :param: vca_id: VCA ID
250 data
= await self
._vca
_collection
.find_one({"_id": vca_id
})
251 data
["endpoints"] = endpoints
252 await self
._vca
_collection
.replace_one({"_id": vca_id
}, data
)
254 # The default VCA. Data for the endpoints is in a different place
255 juju_info
= await self
._get
_juju
_info
()
256 # If it doesn't, then create it
259 await self
._admin
_collection
.insert_one({"_id": "juju"})
260 except Exception as e
:
261 # Racing condition: check if another N2VC worker has created it
262 juju_info
= await self
._get
_juju
_info
()
266 await self
._admin
_collection
.replace_one(
267 {"_id": "juju"}, {"api_endpoints": endpoints
}
270 async def get_vca_endpoints(self
, vca_id
: str = None) -> typing
.List
[str]:
272 Get list if VCA endpoints
274 :param: vca_id: VCA ID
276 :returns: List of endpoints
280 endpoints
= (await self
.get_vca_connection_data(vca_id
)).endpoints
282 juju_info
= await self
._get
_juju
_info
()
283 if juju_info
and "api_endpoints" in juju_info
:
284 endpoints
= juju_info
["api_endpoints"]
287 async def get_vca_id(self
, vim_id
: str = None) -> str:
289 Get VCA ID from the database for a given VIM account ID
291 :param: vim_id: VIM account ID
295 vim_account
= await self
._vim
_accounts
_collection
.find_one({"_id": vim_id
})
296 if vim_account
and "vca" in vim_account
:
297 vca_id
= vim_account
["vca"]
300 async def _get_juju_info(self
):
301 """Get Juju information (the default VCA) from the admin collection"""
302 return await self
._admin
_collection
.find_one({"_id": "juju"})