--- fence-agents-4.10.0/agents/kubevirt/fence_kubevirt.py 2021-07-08 13:09:05.000000000 +0200 +++ /home/oalbrigt/rhpkg/fence-agents-8.6/fence-agents-4.2.1/agents/kubevirt/fence_kubevirt.py 2021-11-02 15:35:46.217440426 +0100 @@ -2,24 +2,25 @@ import sys import logging +import atexit sys.path.append("@FENCEAGENTSLIBDIR@") from fencing import * -from fencing import fail, fail_usage, run_delay, EC_STATUS +from fencing import fail, fail_usage, run_delay, EC_STATUS, EC_FETCH_VM_UUID try: + sys.path.insert(0, '/usr/lib/fence-agents/bundled/kubevirt') from kubernetes.client.exceptions import ApiException except ImportError: logging.error("Couldn\'t import kubernetes.client.exceptions.ApiException - not found or not accessible") -API_VERSION='kubevirt.io/v1' - def get_nodes_list(conn, options): logging.debug("Starting list/monitor operation") result = {} try: + apiversion = options.get("--apiversion") namespace = options.get("--namespace") include_uninitialized = True - vm_api = conn.resources.get(api_version=API_VERSION, kind='VirtualMachine') + vm_api = conn.resources.get(api_version=apiversion, kind='VirtualMachine') vm_list = vm_api.get(namespace=namespace) for vm in vm_list.items: result[vm.metadata.name] = ("", None) @@ -30,18 +31,21 @@ def get_power_status(conn, options): logging.debug("Starting get status operation") try: + apiversion = options.get("--apiversion") namespace = options.get("--namespace") name = options.get("--plug") - vmi_api = conn.resources.get(api_version=API_VERSION, + vmi_api = conn.resources.get(api_version=apiversion, kind='VirtualMachineInstance') vmi = vmi_api.get(name=name, namespace=namespace) - if vmi is not None: - phase = vmi.status.phase - if phase == "Running": - return "on" - return "off" + return translate_status(vmi.status.phase) except ApiException as e: if e.status == 404: + try: + vm_api = conn.resources.get(api_version=apiversion, kind='VirtualMachine') + vm = vm_api.get(name=name, namespace=namespace) + except ApiException as e: + logging.error("VM %s doesn't exist", name) + fail(EC_FETCH_VM_UUID) return "off" logging.error("Failed to get power status, with API Exception: %s", e) fail(EC_STATUS) @@ -49,38 +53,53 @@ logging.error("Failed to get power status, with Exception: %s", e) fail(EC_STATUS) +def translate_status(instance_status): + if instance_status == "Running": + return "on" + return "unknown" + def set_power_status(conn, options): logging.debug("Starting set status operation") try: + apiversion= options.get("--apiversion") namespace = options.get("--namespace") name = options.get("--plug") action = 'start' if options["--action"] == "on" else 'stop' - virtctl_vm_action(conn, action, namespace, name) + virtctl_vm_action(conn, action, namespace, name, apiversion) except Exception as e: logging.error("Failed to set power status, with Exception: %s", e) fail(EC_STATUS) def define_new_opts(): - all_opt["namespace"] = { - "getopt" : ":", - "longopt" : "namespace", - "help" : "--namespace=[namespace] Namespace of the KubeVirt machine", - "shortdesc" : "Namespace of the KubeVirt machine.", - "required" : "1", - "order" : 2 - } - all_opt["kubeconfig"] = { - "getopt" : ":", - "longopt" : "kubeconfig", - "help" : "--kubeconfig=[kubeconfig] Kubeconfig file path", - "shortdesc": "Kubeconfig file path", - "required": "0", - "order": 4 - } + all_opt["namespace"] = { + "getopt" : ":", + "longopt" : "namespace", + "help" : "--namespace=[namespace] Namespace of the KubeVirt machine", + "shortdesc" : "Namespace of the KubeVirt machine.", + "required" : "1", + "order" : 2 + } + all_opt["kubeconfig"] = { + "getopt" : ":", + "longopt" : "kubeconfig", + "help" : "--kubeconfig=[kubeconfig] Kubeconfig file path", + "shortdesc": "Kubeconfig file path", + "required": "0", + "order": 4 + } + all_opt["apiversion"] = { + "getopt" : ":", + "longopt" : "apiversion", + "help" : "--apiversion=[apiversion] Version of the KubeVirt API", + "shortdesc" : "Version of the KubeVirt API.", + "required" : "0", + "default" : "kubevirt.io/v1", + "order" : 5 + } -def virtctl_vm_action(conn, action, namespace, name): +def virtctl_vm_action(conn, action, namespace, name, apiversion): path = '/apis/subresources.{api_version}/namespaces/{namespace}/virtualmachines/{name}/{action}' - path = path.format(api_version=API_VERSION, namespace=namespace, name=name, action=action) + path = path.format(api_version=apiversion, namespace=namespace, name=name, action=action) return conn.request('put', path, header_params={'accept': '*/*'}) def validate_options(required_options_list, options): @@ -92,8 +111,13 @@ def main(): conn = None - device_opt = ["port", "namespace", "kubeconfig", "separator", "no_password"] + device_opt = ["port", "namespace", "kubeconfig", "ssl_insecure", "no_password", "apiversion"] + + atexit.register(atexit_handler) define_new_opts() + + all_opt["power_timeout"]["default"] = "40" + options = check_input(device_opt, process_input(device_opt)) docs = {} @@ -106,6 +130,11 @@ validate_options(['--namespace'], options) + # Disable insecure-certificate-warning message + if "--ssl-insecure" in options: + import urllib3 + urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) + try: from kubernetes import config from openshift.dynamic import DynamicClient