File 0002-fence_gce-set-project-and-zone-as-not-required.patch of Package fence-agents.10129
From bb34acd8b0b150599c393d56dd81a7d8185b27d3 Mon Sep 17 00:00:00 2001
From: Helen Koike <helen.koike@collabora.com>
Date: Tue, 26 Jun 2018 10:44:41 -0300
Subject: [PATCH 2/7] fence_gce: set project and zone as not required
Try to retrieve the GCE project if the script is being executed inside a
GCE machine if --project is not provided.
Try to retrieve the zone automatically from GCE if --zone is not
provided.
---
agents/gce/fence_gce.py | 63 +++++++++++++++++++++++++++++++++++++--
tests/data/metadata/fence_gce.xml | 4 +--
2 files changed, 63 insertions(+), 4 deletions(-)
diff --git a/fence/agents/gce/fence_gce.py b/fence/agents/gce/fence_gce.py
index 3af5bfc8..e53dc5a6 100644
--- a/fence/agents/gce/fence_gce.py
+++ b/fence/agents/gce/fence_gce.py
@@ -12,6 +12,8 @@ from fencing import fail_usage, run_delay, all_opt, atexit_handler, check_input,
LOGGER = logging
+METADATA_SERVER = 'http://metadata.google.internal/computeMetadata/v1/'
+METADATA_HEADERS = {'Metadata-Flavor': 'Google'}
def translate_status(instance_status):
@@ -81,13 +83,56 @@ def set_power_status(conn, options):
fail_usage("Failed: set_power_status: {}".format(str(err)))
+def get_instance(conn, project, zone, instance):
+ request = conn.instances().get(
+ project=project, zone=zone, instance=instance)
+ return request.execute()
+
+
+def get_zone(conn, project, instance):
+ request = conn.instances().aggregatedList(project=project)
+ while request is not None:
+ response = request.execute()
+ zones = response.get('items', {})
+ for zone in zones.values():
+ for inst in zone.get('instances', []):
+ if inst['name'] == instance:
+ return inst['zone'].split("/")[-1]
+ request = conn.instances().aggregatedList_next(
+ previous_request=request, previous_response=response)
+ raise Exception("Unable to find instance %s" % (instance))
+
+
+def get_metadata(metadata_key, params=None, timeout=None):
+ """Performs a GET request with the metadata headers.
+
+ Args:
+ metadata_key: string, the metadata to perform a GET request on.
+ params: dictionary, the query parameters in the GET request.
+ timeout: int, timeout in seconds for metadata requests.
+
+ Returns:
+ HTTP response from the GET request.
+
+ Raises:
+ urlerror.HTTPError: raises when the GET request fails.
+ """
+ timeout = timeout or 60
+ metadata_url = os.path.join(METADATA_SERVER, metadata_key)
+ params = urlparse.urlencode(params or {})
+ url = '%s?%s' % (metadata_url, params)
+ request = urlrequest.Request(url, headers=METADATA_HEADERS)
+ request_opener = urlrequest.build_opener(urlrequest.ProxyHandler({}))
+ return request_opener.open(request, timeout=timeout * 1.1).read()
+
+
def define_new_opts():
all_opt["zone"] = {
"getopt" : ":",
"longopt" : "zone",
"help" : "--zone=[name] Zone, e.g. us-central1-b",
"shortdesc" : "Zone.",
- "required" : "1",
+ "required" : "0",
"order" : 2
}
all_opt["project"] = {
@@ -95,7 +140,7 @@ def define_new_opts():
"longopt" : "project",
"help" : "--project=[name] Project ID",
"shortdesc" : "Project ID.",
- "required" : "1",
+ "required" : "0",
"order" : 3
}
all_opt["logging"] = {
@@ -109,6 +154,7 @@ def define_new_opts():
"order" : 4
}
+
def main():
conn = None
global LOGGER
@@ -165,6 +211,19 @@ def main():
except Exception as err:
fail_usage("Failed: Create GCE compute v1 connection: {}".format(str(err)))
+ # Get project and zone
+ if not options.get("--project"):
+ try:
+ options["--project"] = get_metadata('project/project-id')
+ except Exception as err:
+ fail_usage("Failed retrieving GCE project. Please provide --project option: {}".format(str(err)))
+
+ if not options.get("--zone"):
+ try:
+ options["--zone"] = get_zone(conn, options['--project'], options['--plug'])
+ except Exception as err:
+ fail_usage("Failed retrieving GCE zone. Please provide --zone option: {}".format(str(err)))
+
# Operate the fencing device
result = fence_action(conn, options, set_power_status, get_power_status, get_nodes_list)
sys.exit(result)
diff --git a/tests/data/metadata/fence_gce.xml b/tests/data/metadata/fence_gce.xml
index 805ecc6b..507b8385 100644
--- a/tests/data/metadata/fence_gce.xml
+++ b/tests/data/metadata/fence_gce.xml
@@ -20,12 +20,12 @@ For instructions see: https://cloud.google.com/compute/docs/tutorials/python-gui
<content type="string" />
<shortdesc lang="en">Physical plug number on device, UUID or identification of machine</shortdesc>
</parameter>
- <parameter name="zone" unique="0" required="1">
+ <parameter name="zone" unique="0" required="0">
<getopt mixed="--zone=[name]" />
<content type="string" />
<shortdesc lang="en">Zone.</shortdesc>
</parameter>
- <parameter name="project" unique="0" required="1">
+ <parameter name="project" unique="0" required="0">
<getopt mixed="--project=[name]" />
<content type="string" />
<shortdesc lang="en">Project ID.</shortdesc>
--
2.16.4