odoo-saas-kubernetes/kk_odoo_saas/utils/k8s_deployment.py

250 lines
10 KiB
Python
Executable File

from kubernetes import config, client
import yaml
from kubernetes.stream import stream
from odoo.exceptions import UserError
from .odoo_components import deploy_odoo_components, delete_odoo_components, delete_odoo_components_from_options,\
update_odoo_components
from .pg_server import delete_databases
from odoo.addons.smile_log.tools import SmileDBLogger
from .utils import generate_commit_sha
def create_deployment(app_name, config_file, self=False):
_logger = SmileDBLogger(self._cr.dbname, self._name, self.id, self._uid)
# Configs can be set in Configuration class directly or using helper
# utility. If no argument provided, the config will be loaded from
# default location.
try:
data2 = yaml.safe_load(config_file)
config.load_kube_config_from_dict(data2)
except config.config_exception.ConfigException as e:
_logger.error(str(e))
raise UserError("Unable to Connect K8s Cluster")
if app_name:
deploy_odoo_components(app_name=app_name, namespace="default", self=self)
else:
_logger.error("Cant find App Name")
raise UserError("Cant find App Name")
def delete_app_with_options(self, delete_db, delete_pv, delete_svc, delete_ing, delete_deployment):
_logger = SmileDBLogger(self._cr.dbname, self._name, self.id, self._uid)
try:
data = yaml.safe_load(self.configuration.config_file)
config.load_kube_config_from_dict(data)
except config.config_exception.ConfigException as e:
_logger.error(str(e))
raise UserError("Unable to Connect K8s Cluster")
if self.app_name:
delete_odoo_components_from_options(app_name=self.app_name, namespace="default", self=self, delete_db=delete_db,
delete_pv=delete_pv, delete_svc=delete_svc,
delete_ing=delete_ing, delete_deployment=delete_deployment)
if delete_db:
delete_databases(self)
else:
_logger.error("Cant find App Name")
raise UserError("Cant find App Name")
def update_app(self):
_logger = SmileDBLogger(self._cr.dbname, self._name, self.id, self._uid)
try:
data = yaml.safe_load(self.configuration.config_file)
config.load_kube_config_from_dict(data)
except config.config_exception.ConfigException as e:
_logger.error(str(e))
raise UserError("Unable to Connect K8s Cluster")
if self.app_name:
update_odoo_components(app_name=self.app_name, namespace="default", self=self)
else:
_logger.error("Cant find App Name")
raise UserError("Cant find App Name")
def fetch_secrets_from_cluster(self):
_logger = SmileDBLogger(self._cr.dbname, self._name, self.id, self._uid)
try:
data2 = yaml.safe_load(self.configuration.config_file)
config.load_kube_config_from_dict(data2)
except config.config_exception.ConfigException as e:
_logger.error(str(e))
raise UserError("Unable to Connect K8s Cluster")
secs = []
if self.app_name:
core_v1_api = client.CoreV1Api()
secrs = core_v1_api.list_namespaced_secret(namespace='default')
for sec in secrs.items:
secs.append(sec.metadata.name)
return secs
def deploy_apps_from_git(self):
"""
To pull code from github inside running container
"""
_logger = SmileDBLogger(self._cr.dbname, self._name, self.id, self._uid)
try:
data2 = yaml.safe_load(self.configuration.config_file)
config.load_kube_config_from_dict(data2)
except config.config_exception.ConfigException as e:
_logger.error(str(e))
raise UserError("Unable to Connect K8s Cluster")
if self.app_name:
core_v1_api = client.CoreV1Api()
pod = core_v1_api.list_namespaced_pod(namespace='default', label_selector='app={}'.format(self.app_name))
if self.is_extra_addon and self.extra_addons and pod and pod.items:
base_version = self.docker_image.base_version
clone_path = "/var/lib/odoo/addons/" + str(base_version)
if self.is_private_repo and self.git_token:
url = self.extra_addons
url = url.replace("http://", "")
url = url.replace("https://", "")
url = url.replace("www.", "")
git_url = "https://oauth2:{0}@{1}".format(self.git_token, url)
else:
git_url = self.extra_addons
is_clone_error = False
error = ''
exec_command = ['git', '-C', clone_path, 'pull']
resp = stream(core_v1_api.connect_get_namespaced_pod_exec,
pod.items[0].metadata.name,
'default',
command=exec_command,
stderr=True, stdin=True,
stdout=True, tty=False,
_preload_content=False)
while resp.is_open():
resp.update(timeout=10)
if resp.peek_stdout():
_logger.info(str(resp.read_stdout()))
if resp.peek_stderr():
is_clone_error = True
error = resp.read_stderr()
_logger.error(str(error))
break
resp.close()
if is_clone_error:
if error and "not a git repository (or any" in error:
resp1 = stream(core_v1_api.connect_get_namespaced_pod_exec,
pod.items[0].metadata.name,
'default',
command=['chmod', '-R', 'ugo+rw', clone_path],
stderr=True, stdin=False,
stdout=True, tty=False,
_preload_content=False)
resp = stream(core_v1_api.connect_get_namespaced_pod_exec,
pod.items[0].metadata.name,
'default',
command=['git', 'clone', git_url, clone_path],
stderr=True, stdin=False,
stdout=True, tty=False,
_preload_content=False)
while resp.is_open():
resp.update(timeout=25)
if resp.peek_stdout():
_logger.info(str(resp.read_stdout()))
if resp.peek_stderr():
error = resp.read_stderr()
_logger.error(str(error))
else:
_logger.info(str(
"No Response"
))
resp.close()
else:
return False
def restart_odoo_service(self):
_logger = SmileDBLogger(self._cr.dbname, self._name, self.id, self._uid)
try:
data2 = yaml.safe_load(self.configuration.config_file)
config.load_kube_config_from_dict(data2)
except config.config_exception.ConfigException as e:
_logger.error(str(e))
raise UserError("Unable to Connect K8s Cluster")
if self.app_name:
core_v1_api = client.CoreV1Api()
pod = core_v1_api.list_namespaced_pod(namespace='default', label_selector='app={}'.format(self.app_name))
exec_command = ['./mnt/restart_odoo.sh']
resp = stream(core_v1_api.connect_get_namespaced_pod_exec,
pod.items[0].metadata.name,
'default',
command=exec_command,
stderr=True, stdin=True,
stdout=True, tty=False,
_preload_content=False)
while resp.is_open():
resp.update(timeout=10)
if resp.peek_stdout():
_logger.info(str(resp.read_stdout()))
if resp.peek_stderr():
error = resp.read_stderr()
_logger.error(str(error))
break
resp.close()
def read_deployment(self, dep_type='odoo'):
_logger = SmileDBLogger(self._cr.dbname, self._name, self.id, self._uid)
try:
data = yaml.safe_load(self.configuration.config_file)
config.load_kube_config_from_dict(data)
except config.config_exception.ConfigException as e:
_logger.error(str(e))
raise UserError("Unable to Connect K8s Cluster")
if self.app_name:
dep_name = self.app_name + "-odoo-deployment"
core_v1_api = client.AppsV1Api()
try:
deployment = core_v1_api.read_namespaced_deployment(name=dep_name, namespace='default')
if deployment:
return deployment
return
except Exception as e:
pass
else:
_logger.error("Cant find App Name")
raise UserError("Cant find App Name")
def update_deployment(self, container_arguments, dep_type='odoo', env_vars=False):
_logger = SmileDBLogger(self._cr.dbname, self._name, self.id, self._uid)
try:
data = yaml.safe_load(self.configuration.config_file)
config.load_kube_config_from_dict(data)
except config.config_exception.ConfigException as e:
_logger.error(str(e))
raise UserError("Unable to Connect K8s Cluster")
if self.app_name:
core_v1_api = client.AppsV1Api()
try:
deployment = read_deployment(self=self)
if container_arguments:
deployment.spec.template.spec.containers[0].args = eval(container_arguments)
if env_vars:
deployment.spec.template.spec.containers[0].env = env_vars
deployment.spec.template.metadata.labels['COMMIT_SHA'] = generate_commit_sha(10)
patched_deployment = core_v1_api.patch_namespaced_deployment(name=deployment.metadata.name,
namespace='default',
body=deployment)
return patched_deployment
except Exception as e:
_logger.error(str(e))
else:
_logger.error("Cant find App Name")
raise UserError("Cant find App Name")