250 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
			
		
		
	
	
			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")
 |