1 # Copyright (C) 2021 Wind River Systems, Inc.
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.
15 # pylint: disable=unused-argument
16 from __future__ import annotations
17 from o2dms.domain.states import NfDeploymentState
18 # from o2common.service import messagebus
19 from o2dms.domain.dms import NfDeployment, NfDeploymentDesc
20 from o2dms.domain import commands
21 from typing import Callable
23 from o2dms.domain import events
24 from o2common.service.unit_of_work import AbstractUnitOfWork
25 from helm_sdk import Helm
26 from ruamel import yaml
28 from o2common.config import config
29 from retry import retry
31 # from . import unit_of_work
33 from o2common.helper import o2logging
34 logger = o2logging.get_logger(__name__)
35 LOCAL_HELM_BIN = config.get_helm_cli()
36 K8S_KUBECONFIG, K8S_APISERVER, K8S_TOKEN = \
37 config.get_k8s_api_endpoint()
40 def publish_nfdeployment_state_change(
41 event: events.NfDeploymentStateChanged,
44 publish("NfDeploymentStateChanged", event)
46 "published NfDeploymentStateChanged: {}, state from {} to {}".format(
47 event.NfDeploymentId, event.FromState, event.ToState))
50 def handle_nfdeployment_statechanged(
51 cmd: commands.HandleNfDeploymentStateChanged,
52 uow: AbstractUnitOfWork
54 if cmd.FromState == NfDeploymentState.Initial:
55 if cmd.ToState == NfDeploymentState.NotInstalled:
56 cmd2 = commands.InstallNfDeployment(cmd.NfDeploymentId)
57 install_nfdeployment(cmd2, uow)
59 logger.debug("Not insterested state change: {}".format(cmd))
60 elif cmd.FromState == NfDeploymentState.Installed:
61 if cmd.ToState == NfDeploymentState.Uninstalling:
62 cmd2 = commands.UninstallNfDeployment(cmd.NfDeploymentId)
63 uninstall_nfdeployment(cmd2, uow)
65 logger.debug("Not insterested state change: {}".format(cmd))
66 elif cmd.FromState == NfDeploymentState.NotInstalled:
67 if cmd.ToState == NfDeploymentState.Initial:
68 cmd2 = commands.DeleteNfDeployment(cmd.NfDeploymentId)
69 delete_nfdeployment(cmd2, uow)
71 logger.debug("Not insterested state change: {}".format(cmd))
73 logger.debug("Not insterested state change: {}".format(cmd))
77 @retry(tries=20, max_delay=10000)
78 def _retry_get_nfdeployment(
79 cmd: commands.InstallNfDeployment,
80 uow: AbstractUnitOfWork):
81 nfdeployment: NfDeployment = uow.nfdeployments.get(
83 if nfdeployment is None:
84 raise Exception("Cannot find NfDeployment: {}".format(
89 def install_nfdeployment(
90 cmd: commands.InstallNfDeployment,
91 uow: AbstractUnitOfWork
93 logger.info("install with NfDeploymentId: {}".format(
95 nfdeployment: NfDeployment = _retry_get_nfdeployment(cmd, uow)
96 if nfdeployment is None:
97 raise Exception("Cannot find NfDeployment: {}".format(
99 # get nfdeploymentdescriptor by descriptorId
100 desc: NfDeploymentDesc = uow.nfdeployment_descs.get(
101 nfdeployment.descriptorId)
104 "Cannot find NfDeploymentDescriptor:{} for NfDeployment:{}".format(
105 nfdeployment.descriptorId, nfdeployment.id
109 repourl = desc.artifactRepoUrl
110 helm = Helm(logger, LOCAL_HELM_BIN, environment_variables={})
113 repolist = helm.repo_list()
114 for repo in repolist:
115 if repo['url'] == repourl:
116 repoName = repo['name']
123 repoName = "repo4{}".format(nfdeployment.name)
124 logger.debug("Trying to add repo:{}".format(repourl))
125 helm.repo_add(repoName, repourl)
126 helm.repo_update(None)
128 repolist = helm.repo_list()
129 logger.debug('repo list:{}'.format(repolist))
131 # helm install name chart
132 values_file_path = '/tmp/override_{}.yaml'.format(nfdeployment.name)
133 if len(desc.inputParams) > 0:
134 logger.info("dump override yaml:{}".format(values_file_path))
135 values = json.loads(desc.inputParams)
136 _create_values_file(values_file_path, values)
138 values_file_path = None
140 logger.debug('Try to helm install {}/{} {} -f {}'.format(
141 repoName, nfdeployment.name, desc.artifactName, values_file_path))
142 tokens = desc.artifactName.split(':')
143 chartname = tokens[0]
145 # if (len(tokens) > 1):
146 # myflags = {"name": "version", "value": tokens[1]}
147 result = helm.install(
148 nfdeployment.name, "{}/{}".format(repoName, chartname), flags=myflags,
149 values_file=values_file_path, kubeconfig=K8S_KUBECONFIG,
150 token=K8S_TOKEN, apiserver=K8S_APISERVER)
151 logger.debug('result: {}'.format(result))
155 entity: NfDeployment = uow.nfdeployments.get(cmd.NfDeploymentId)
156 entity.transit_state(NfDeploymentState.Installed)
160 def _create_values_file(filePath: str, content: dict):
161 with open(filePath, "w", encoding="utf-8") as f:
162 yaml.dump(content, f, Dumper=yaml.RoundTripDumper)
165 def uninstall_nfdeployment(
166 cmd: commands.UninstallNfDeployment,
167 uow: AbstractUnitOfWork
169 logger.info("uninstall with NfDeploymentId: {}".format(
171 nfdeployment: NfDeployment = _retry_get_nfdeployment(cmd, uow)
172 if nfdeployment is None:
173 raise Exception("Cannot find NfDeployment: {}".format(
175 # get nfdeploymentdescriptor by descriptorId
176 desc: NfDeploymentDesc = uow.nfdeployment_descs.get(
177 nfdeployment.descriptorId)
180 "Cannot find NfDeploymentDescriptor:{} for NfDeployment:{}".format(
181 nfdeployment.descriptorId, nfdeployment.id
184 helm = Helm(logger, LOCAL_HELM_BIN, environment_variables={})
186 logger.debug('Try to helm del {}'.format(
189 # if (len(tokens) > 1):
190 # myflags = {"name": "version", "value": tokens[1]}
191 result = helm.uninstall(
192 nfdeployment.name, flags=myflags,
193 kubeconfig=K8S_KUBECONFIG,
194 token=K8S_TOKEN, apiserver=K8S_APISERVER)
195 logger.debug('result: {}'.format(result))
200 entity: NfDeployment = uow.nfdeployments.get(cmd.NfDeploymentId)
201 entity.transit_state(NfDeploymentState.Initial)
202 # uow.nfdeployments.update(
203 # cmd.NfDeploymentId, status=NfDeploymentState.Initial)
207 def delete_nfdeployment(
208 cmd: commands.UninstallNfDeployment,
209 uow: AbstractUnitOfWork
211 logger.info("delete with NfDeploymentId: {}".format(
214 # nfdeployment: NfDeployment = _retry_get_nfdeployment(cmd, uow)
216 uow.nfdeployments.delete(cmd.NfDeploymentId)