Blob Blame History Raw
--- 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