From 76c17c4c3700c801be0e3d3c0dfa42ca75d849ac Mon Sep 17 00:00:00 2001 From: MarioRobres Date: Fri, 7 Jun 2024 10:52:35 +0200 Subject: [PATCH] F OpenNebula/one-aiops#70: get kubecfg from master node --- lithops/serverless/backends/one/config.py | 57 +++---------------- lithops/serverless/backends/one/one.py | 36 ++++++++++-- .../serverless/backends/one/one_config.yaml | 3 +- 3 files changed, 39 insertions(+), 57 deletions(-) diff --git a/lithops/serverless/backends/one/config.py b/lithops/serverless/backends/one/config.py index d73d7f5c1..f54e43ed5 100644 --- a/lithops/serverless/backends/one/config.py +++ b/lithops/serverless/backends/one/config.py @@ -13,55 +13,6 @@ class OneConfigError(Exception): pass -DEFAULT_ONEKE_CONFIG = """ -{ - "name": "OneKE/1", - "networks_values": [ - {"Public": {"id": "0"}}, - {"Private": {"id": "1"}} - ], - "custom_attrs_values": { - "ONEAPP_VROUTER_ETH0_VIP0": "", - "ONEAPP_VROUTER_ETH1_VIP0": "", - - "ONEAPP_RKE2_SUPERVISOR_EP": "ep0.eth0.vr:9345", - "ONEAPP_K8S_CONTROL_PLANE_EP": "ep0.eth0.vr:6443", - "ONEAPP_K8S_EXTRA_SANS": "localhost,127.0.0.1,ep0.eth0.vr,${vnf.TEMPLATE.CONTEXT.ETH0_IP},k8s.yourdomain.it", - - "ONEAPP_K8S_MULTUS_ENABLED": "NO", - "ONEAPP_K8S_MULTUS_CONFIG": "", - "ONEAPP_K8S_CNI_PLUGIN": "cilium", - "ONEAPP_K8S_CNI_CONFIG": "", - "ONEAPP_K8S_CILIUM_RANGE": "", - - "ONEAPP_K8S_METALLB_ENABLED": "NO", - "ONEAPP_K8S_METALLB_CONFIG": "", - "ONEAPP_K8S_METALLB_RANGE": "", - - "ONEAPP_K8S_LONGHORN_ENABLED": "YES", - "ONEAPP_STORAGE_DEVICE": "/dev/vdb", - "ONEAPP_STORAGE_FILESYSTEM": "xfs", - - "ONEAPP_K8S_TRAEFIK_ENABLED": "YES", - "ONEAPP_VNF_HAPROXY_INTERFACES": "eth0", - "ONEAPP_VNF_HAPROXY_REFRESH_RATE": "30", - "ONEAPP_VNF_HAPROXY_LB0_PORT": "9345", - "ONEAPP_VNF_HAPROXY_LB1_PORT": "6443", - "ONEAPP_VNF_HAPROXY_LB2_PORT": "443", - "ONEAPP_VNF_HAPROXY_LB3_PORT": "80", - - "ONEAPP_VNF_DNS_ENABLED": "YES", - "ONEAPP_VNF_DNS_INTERFACES": "eth1", - "ONEAPP_VNF_DNS_NAMESERVERS": "1.1.1.1,8.8.8.8", - "ONEAPP_VNF_NAT4_ENABLED": "YES", - "ONEAPP_VNF_NAT4_INTERFACES_OUT": "eth0", - "ONEAPP_VNF_ROUTER4_ENABLED": "YES", - "ONEAPP_VNF_ROUTER4_INTERFACES": "eth0,eth1" - } -} -""" - - MANDATORY_CONFIG_KEYS = { "public_network_id", "private_network_id" @@ -120,6 +71,13 @@ class OneConfigError(Exception): """ +# Add OpenNebula defaults +DEFAULT_CONFIG_KEYS = { + 'timeout': 600, + 'kubcfg_path': '/tmp/kube_config' +} + + def load_config(config_data): if 'oneke_config' in config_data['one']: oneke_config = config_data['one']['oneke_config'] @@ -144,7 +102,6 @@ def load_config(config_data): ], "custom_attrs_values": custom_attrs_values } - # Override oneke_config with a valid JSON to update the service config_data['one']['oneke_config'] = json.dumps(oneke_update) diff --git a/lithops/serverless/backends/one/one.py b/lithops/serverless/backends/one/one.py index c65fb5296..f95e47f6a 100644 --- a/lithops/serverless/backends/one/one.py +++ b/lithops/serverless/backends/one/one.py @@ -6,6 +6,7 @@ import os import json import time +import base64 import logging import urllib3 @@ -48,18 +49,23 @@ def __init__(self, one_config, internal_storage): # template_id: instantiate OneKE if 'template_id' in one_config: - service_id = self._instantiate_oneke(one_config['template_id'], one_config['oneke_config']) - self._wait_for_oneke(service_id) + one_config['service_id'] = self._instantiate_oneke(one_config['template_id'], one_config['oneke_config']) + self._wait_for_oneke(one_config['service_id'], one_config['timeout']) # service_id: check deployed OneKE is available elif 'service_id' in one_config: self._check_oneke(one_config['service_id']) else: raise OneError(f"OpenNebula backend must contain 'template_id' or 'service_id'") + # Get and Save kubeconfig from OneKE + kubecfg = self._get_kube_config(one_config['service_id']) + with open(one_config['oneconfig_path'], 'w') as file: + file.write(kubecfg) # Overwrite config values self.name = 'one' - + self.kubecfg_path = one_config['oneconfig_path'] + super().__init__(one_config, internal_storage) @@ -95,7 +101,7 @@ def _instantiate_oneke(self, template_id, oneke_config): return service_id - def _wait_for_oneke(self, service_id, timeout=600): + def _wait_for_oneke(self, service_id, timeout): start_time = time.time() minutes_timeout = int(timeout/60) logger.debug("Initializing OneKE service. Be patient, this process can take up to {} minutes".format(minutes_timeout)) @@ -104,7 +110,7 @@ def _wait_for_oneke(self, service_id, timeout=600): logs = _service_json[service_id]['TEMPLATE']['BODY'].get('log', []) if logs: last_log = logs[-1] - logger.debug(last_log) + logger.debug("Last log: {}".format(last_log)) state = last_log['message'].split(':')[-1].strip() # Check OneKE deployment status if state == 'FAILED_DEPLOYING': @@ -118,4 +124,22 @@ def _wait_for_oneke(self, service_id, timeout=600): if elapsed_time > timeout: raise OneError("Deployment timed out after {} seconds. You can try again once OneKE is in RUNNING state with the service_id option.".format(timeout)) - time.sleep(10) \ No newline at end of file + time.sleep(10) + + + def _get_kube_config(self, service_id): + # Get master VM ID + _service_json = self.client.servicepool[service_id].info() + master_vm_id = next( + (role['nodes'][0]['vm_info']['VM']['ID'] for role in _service_json[str(service_id)]['TEMPLATE']['BODY']['roles'] + if role['name'] == 'master'), + None + ) + if master_vm_id is None: + raise OneError("Master VM ID not found. Please change the name of the master node to 'master' and try again.") + # Get kubeconfig + vm = self.one.vm.info(int(master_vm_id)) + encoded_kubeconfig = vm.USER_TEMPLATE.get('ONEKE_KUBECONFIG') + decoded_kubeconfig = base64.b64decode(encoded_kubeconfig).decode('utf-8') + logger.debug("OpneNebula OneKE Kubeconfig: {}".format(decoded_kubeconfig)) + return decoded_kubeconfig \ No newline at end of file diff --git a/lithops/serverless/backends/one/one_config.yaml b/lithops/serverless/backends/one/one_config.yaml index 4124fb532..741a44d08 100644 --- a/lithops/serverless/backends/one/one_config.yaml +++ b/lithops/serverless/backends/one/one_config.yaml @@ -4,7 +4,8 @@ one: service_id: # oneke service id (means OneKE is already deployed) service_template_id: # oneke_tempalte_id (client has downloaded before) oneconfig_path: # PATH to OneKE JSON config - + timeout: # time to wait for OneKE to be ready + kubcfg_path': # PATH were kubeconfig will be stored oneke_config: public_network_id: # ID for Public vnet private_network_id: # ID for Private vnet (if not passed: create a new one)