b1f3230c07ba36724bd6aa236679105f32362454
2 # Copyright 2019 Telefonica Investigacion y Desarrollo, S.A.U.
3 # This file is part of OSM
6 # Licensed under the Apache License, Version 2.0 (the "License");
7 # you may not use this file except in compliance with the License.
8 # You may obtain 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,
14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
16 # See the License for the specific language governing permissions and
17 # limitations under the License.
19 # For those usages not covered by the Apache License, Version 2.0 please
20 # contact with: nfvlabs@tid.es
24 from n2vc
.loggable
import Loggable
29 class K8sConnector(abc
.ABC
, Loggable
):
32 ##################################################################################################
33 ########################################## P U B L I C ###########################################
34 ##################################################################################################
45 :param db: database object to write current operation status
46 :param log: logger for tracing
47 :param on_update_db: callback called when k8s connector updates database
51 Loggable
.__init
__(self
, log
=log
, log_to_console
=True, prefix
='\nK8S')
53 # self.log.info('Initializing generic K8S connector')
55 # the database and update callback
57 self
.on_update_db
= on_update_db
59 # self.log.info('K8S generic connector initialized')
65 namespace
: str = 'kube-system',
66 reuse_cluster_uuid
=None
69 It prepares a given K8s cluster environment to run Charts or juju Bundles on both sides:
73 :param k8s_creds: credentials to access a given K8s cluster, i.e. a valid '.kube/config'
74 :param namespace: optional namespace to be used for the K8s engine (helm tiller, juju).
75 By default, 'kube-system' will be used
76 :param reuse_cluster_uuid: existing cluster uuid for reuse
77 :return: uuid of the K8s cluster and True if connector has installed some software in the cluster
78 (on error, an exception will be raised)
87 repo_type
: str = 'chart'
90 Add a new repository to OSM database
92 :param cluster_uuid: the cluster
93 :param name: name for the repo in OSM
94 :param url: URL of the repo
95 :param repo_type: either "chart" or "bundle"
96 :return: True if successful
105 Get the list of registered repositories
107 :param cluster_uuid: the cluster
108 :return: list of registered repositories: [ (name, url) .... ]
112 async def repo_remove(
118 Remove a repository from OSM
120 :param name: repo name in OSM
121 :param cluster_uuid: the cluster
122 :return: True if successful
126 async def synchronize_repos(
132 Synchronizes the list of repositories created in the cluster with
133 the repositories added by the NBI
135 :param cluster_uuid: the cluster
136 :return: List of repositories deleted from the cluster and dictionary with repos added
144 uninstall_sw
: bool = False
147 Uninstalls Tiller/Charm from a known K8s cluster and removes it from the list of known K8s clusters.
148 Intended to be used e.g. when the NS instance is deleted.
150 :param cluster_uuid: UUID of a K8s cluster known by OSM.
151 :param force: force deletion, even in case there are deployed releases
152 :param uninstall_sw: flag to indicate that sw uninstallation from software is needed
153 :return: str: kdu_instance generated by helm
162 timeout
: float = 300,
164 db_dict
: dict = None,
165 kdu_name
: str = None,
166 namespace
: str = None
169 Deploys of a new KDU instance. It would implicitly rely on the `install` call to deploy the Chart/Bundle
170 properly parametrized (in practice, this call would happen before any _initial-config-primitive_
171 of the VNF is called).
173 :param cluster_uuid: UUID of a K8s cluster known by OSM
174 :param kdu_model: chart/bundle:version reference (string), which can be either of these options:
175 - a name of chart/bundle available via the repos known by OSM
176 - a path to a packaged chart/bundle
177 - a path to an unpacked chart/bundle directory or a URL
178 :param atomic: If set, installation process purges chart/bundle on fail, also will wait until
179 all the K8s objects are active
180 :param timeout: Time in seconds to wait for the install of the chart/bundle (defaults to
181 Helm default timeout: 300s)
182 :param params: dictionary of key-value pairs for instantiation parameters (overriding default values)
183 :param dict db_dict: where to write into database when the status changes.
184 It contains a dict with {collection: <str>, filter: {}, path: <str>},
185 e.g. {collection: "nsrs", filter: {_id: <nsd-id>, path: "_admin.deployed.K8S.3"}
186 :param kdu_name: Name of the KDU instance to be installed
187 :param namespace: K8s namespace to use for the KDU instance
188 :return: True if successful
196 kdu_model
: str = None,
198 timeout
: float = 300,
203 Upgrades an existing KDU instance. It would implicitly use the `upgrade` call over an existing Chart/Bundle.
204 It can be used both to upgrade the chart or to reconfigure it. This would be exposed as Day-2 primitive.
206 :param cluster_uuid: UUID of a K8s cluster known by OSM
207 :param kdu_instance: unique name for the KDU instance to be updated
208 :param kdu_model: new chart/bundle:version reference
209 :param atomic: rollback in case of fail and wait for pods and services are available
210 :param timeout: Time in seconds to wait for the install of the chart/bundle (defaults to
211 Helm default timeout: 300s)
212 :param params: new dictionary of key-value pairs for instantiation parameters
213 :param dict db_dict: where to write into database when the status changes.
214 It contains a dict with {collection: <str>, filter: {}, path: <str>},
215 e.g. {collection: "nsrs", filter: {_id: <nsd-id>, path: "_admin.deployed.K8S.3"}
216 :return: reference to the new revision number of the KDU instance
228 Rolls back a previous update of a KDU instance. It would implicitly use the `rollback` call.
229 It can be used both to rollback from a Chart/Bundle version update or from a reconfiguration.
230 This would be exposed as Day-2 primitive.
232 :param cluster_uuid: UUID of a K8s cluster known by OSM
233 :param kdu_instance: unique name for the KDU instance
234 :param revision: revision to which revert changes. If omitted, it will revert the last update only
235 :param dict db_dict: where to write into database when the status changes.
236 It contains a dict with {collection: <str>, filter: {}, path: <str>},
237 e.g. {collection: "nsrs", filter: {_id: <nsd-id>, path: "_admin.deployed.K8S.3"}
238 :return:If successful, reference to the current active revision of the KDU instance after the rollback
248 Removes an existing KDU instance. It would implicitly use the `delete` call (this call would happen
249 after all _terminate-config-primitive_ of the VNF are invoked).
251 :param cluster_uuid: UUID of a K8s cluster known by OSM
252 :param kdu_instance: unique name for the KDU instance to be deleted
253 :return: True if successful
257 async def exec_primitive(
259 cluster_uuid
: str = None,
260 kdu_instance
: str = None,
261 primitive_name
: str = None,
262 timeout
: float = 300,
264 db_dict
: dict = None,
266 """Exec primitive (Juju action)
268 :param cluster_uuid str: The UUID of the cluster
269 :param kdu_instance str: The unique name of the KDU instance
270 :param primitive_name: Name of action that will be executed
271 :param timeout: Timeout for action execution
272 :param params: Dictionary of all the parameters needed for the action
273 :db_dict: Dictionary for any additional data
275 :return: Returns the output of the action
279 async def inspect_kdu(
285 These calls will retrieve from the Chart/Bundle:
287 - The list of configurable values and their defaults (e.g. in Charts, it would retrieve
288 the contents of `values.yaml`).
289 - If available, any embedded help file (e.g. `readme.md`) embedded in the Chart/Bundle.
291 :param kdu_model: chart/bundle reference
292 :param repo_url: optional, reposotory URL (None if tar.gz, URl in other cases, even stable URL)
295 If successful, it will return the available parameters and their default values as provided by the backend.
306 :param kdu_model: chart/bundle reference
307 :param repo_url: optional, reposotory URL (None if tar.gz, URl in other cases, even stable URL)
308 :return: If successful, it will return the contents of the 'readme.md'
312 async def status_kdu(
318 This call would retrieve tha current state of a given KDU instance. It would be would allow to retrieve
319 the _composition_ (i.e. K8s objects) and _specific values_ of the configuration parameters applied
320 to a given instance. This call would be based on the `status` call.
322 :param cluster_uuid: UUID of a K8s cluster known by OSM
323 :param kdu_instance: unique name for the KDU instance
324 :return: If successful, it will return the following vector of arguments:
325 - K8s `namespace` in the cluster where the KDU lives
326 - `state` of the KDU instance. It can be:
333 - List of `resources` (objects) that this release consists of, sorted by kind, and the status of those resources
334 - Last `deployment_time`.
339 ##################################################################################################
340 ########################################## P R I V A T E #########################################
341 ##################################################################################################
344 async def write_app_status_to_db(
348 detailed_status
: str,
353 self
.warning('No db => No database write')
357 self
.warning('No db_dict => No database write')
360 self
.log
.debug('status={}'.format(status
))
364 the_table
= db_dict
['collection']
365 the_filter
= db_dict
['filter']
366 the_path
= db_dict
['path']
367 if not the_path
[-1] == '.':
368 the_path
= the_path
+ '.'
370 the_path
+ 'operation': operation
,
371 the_path
+ 'status': status
,
372 the_path
+ 'detailed-status': detailed_status
,
373 the_path
+ 'status-time': str(time
.time()),
379 update_dict
=update_dict
,
384 if self
.on_update_db
:
385 if asyncio
.iscoroutinefunction(self
.on_update_db
):
386 await self
.on_update_db(the_table
, the_filter
, the_path
, update_dict
)
388 self
.on_update_db(the_table
, the_filter
, the_path
, update_dict
)
392 except Exception as e
:
393 self
.log
.info('Exception writing status to database: {}'.format(e
))