File 0001-fence_gce-add-support-for-stackdriver-logging.patch of Package fence-agents.openSUSE_Leap_42.3_Update
From 59ae9d00060da5329d7ca538974498292bbe1d91 Mon Sep 17 00:00:00 2001
From: Helen Koike <helen.koike@collabora.com>
Date: Tue, 26 Jun 2018 10:18:29 -0300
Subject: [PATCH 1/7] fence_gce: add support for stackdriver logging
Add --logging option to enable sending logs to google stackdriver
---
agents/gce/fence_gce.py | 65 +++++++++++++++++++++++++++++++++++++--
tests/data/metadata/fence_gce.xml | 5 +++
2 files changed, 67 insertions(+), 3 deletions(-)
diff --git a/fence/agents/gce/fence_gce.py b/fence/agents/gce/fence_gce.py
index 3abb5207..3af5bfc8 100644
--- a/fence/agents/gce/fence_gce.py
+++ b/fence/agents/gce/fence_gce.py
@@ -1,12 +1,19 @@
#!@PYTHON@ -tt
import atexit
+import logging
+import platform
import sys
+import time
sys.path.append("@FENCEAGENTSLIBDIR@")
import googleapiclient.discovery
from fencing import fail_usage, run_delay, all_opt, atexit_handler, check_input, process_input, show_docs, fence_action
+
+LOGGER = logging
+
+
def translate_status(instance_status):
"Returns on | off | unknown."
if instance_status == "RUNNING":
@@ -27,6 +34,7 @@ def get_nodes_list(conn, options):
return result
+
def get_power_status(conn, options):
try:
instance = conn.instances().get(
@@ -38,18 +46,37 @@ def get_power_status(conn, options):
fail_usage("Failed: get_power_status: {}".format(str(err)))
+def wait_for_operation(conn, project, zone, operation):
+ while True:
+ result = conn.zoneOperations().get(
+ project=project,
+ zone=zone,
+ operation=operation['name']).execute()
+ if result['status'] == 'DONE':
+ if 'error' in result:
+ raise Exception(result['error'])
+ return
+ time.sleep(1)
+
+
def set_power_status(conn, options):
try:
if options["--action"] == "off":
- conn.instances().stop(
+ LOGGER.info("Issuing poweroff of %s in zone %s" % (options["--plug"], options["--zone"]))
+ operation = conn.instances().stop(
project=options["--project"],
zone=options["--zone"],
instance=options["--plug"]).execute()
+ wait_for_operation(conn, options["--project"], options["--zone"], operation)
+ LOGGER.info("Poweroff of %s in zone %s complete" % (options["--plug"], options["--zone"]))
elif options["--action"] == "on":
- conn.instances().start(
+ LOGGER.info("Issuing poweron of %s in zone %s" % (options["--plug"], options["--zone"]))
+ operation = conn.instances().start(
project=options["--project"],
zone=options["--zone"],
instance=options["--plug"]).execute()
+ wait_for_operation(conn, options["--project"], options["--zone"], operation)
+ LOGGER.info("Poweron of %s in zone %s complete" % (options["--plug"], options["--zone"]))
except Exception as err:
fail_usage("Failed: set_power_status: {}".format(str(err)))
@@ -71,11 +98,24 @@ def define_new_opts():
"required" : "1",
"order" : 3
}
+ all_opt["logging"] = {
+ "getopt" : ":",
+ "longopt" : "logging",
+ "help" : "--logging=[bool] Logging, true/false",
+ "shortdesc" : "Stackdriver-logging support.",
+ "longdesc" : "If enabled (set to true), IP failover logs will be posted to stackdriver logging.",
+ "required" : "0",
+ "default" : "false",
+ "order" : 4
+ }
def main():
conn = None
+ global LOGGER
+
+ hostname = platform.node()
- device_opt = ["port", "no_password", "zone", "project"]
+ device_opt = ["port", "no_password", "zone", "project", "logging"]
atexit.register(atexit_handler)
@@ -97,6 +137,25 @@ def main():
run_delay(options)
+ # Prepare logging
+ logging_env = options.get('--logging')
+ if logging_env:
+ logging_env = logging_env.lower()
+ if any(x in logging_env for x in ['yes', 'true', 'enabled']):
+ try:
+ import google.cloud.logging.handlers
+ client = google.cloud.logging.Client()
+ handler = google.cloud.logging.handlers.CloudLoggingHandler(client, name=hostname)
+ formatter = logging.Formatter('gcp:stonish "%(message)s"')
+ LOGGER = logging.getLogger(hostname)
+ handler.setFormatter(formatter)
+ LOGGER.addHandler(handler)
+ LOGGER.setLevel(logging.INFO)
+ except ImportError:
+ LOGGER.error('Couldn\'t import google.cloud.logging, '
+ 'disabling Stackdriver-logging support')
+
+ # Prepare cli
try:
credentials = None
if tuple(googleapiclient.__version__) < tuple("1.6.0"):
diff --git a/tests/data/metadata/fence_gce.xml b/tests/data/metadata/fence_gce.xml
index 2a147f21..805ecc6b 100644
--- a/tests/data/metadata/fence_gce.xml
+++ b/tests/data/metadata/fence_gce.xml
@@ -30,6 +30,11 @@ For instructions see: https://cloud.google.com/compute/docs/tutorials/python-gui
<content type="string" />
<shortdesc lang="en">Project ID.</shortdesc>
</parameter>
+ <parameter name="logging" unique="0" required="0">
+ <getopt mixed="--logging=[bool]" />
+ <content type="string" default="false" />
+ <shortdesc lang="en">Stackdriver-logging support.</shortdesc>
+ </parameter>
<parameter name="quiet" unique="0" required="0">
<getopt mixed="-q, --quiet" />
<content type="boolean" />
--
2.16.4