Accepting request 868865 from network:ha-clustering:Unstable
- Adds service account authentication to GCE fence agent - Update to version 4.7.0+git.1607346448.17bd8552: * fence_mpath, fence_scsi: Improve logging for failed res/key get * fence_mpath, fence_scsi: Capture stderr in run_cmd() * build: depend on config changes to rebuild when running make after running ./configure * fence_redfish: Fix typo in help. * fence_aws: add support for IMDSv2 * spec: add pkg-config file, and set version for obsoletes to avoid failing to build on Fedora 33 * Add pkg-config file * fence_scsi: dont write key to device if it's already registered, and open file correctly to avoid using regex against end-of-file * fencing: fix run_command() to allow timeout=0 to mean forever * fencing: fix to make timeout(s)=0 be treated as forever for agents using pexpect - Update to version 4.6.0+git.1603723121.a17eb9d4: * Add a fence_crosslink agent * fencing: fix power-timeout when using new disable-timeout parameter * metadata: update for disable_timeout parameter * fencing: add disable-timeout parameter, and make it default when run from Pacemaker (at least 2.0+) * spec: make telnet a weak dependency * Adds baremetal support to GCE fence agent and API call retries (#355) * spec: add -aws and -gce dependency to -all subpackage * spec: fix ibmz subpackage referring to fence_z instead of fence_ibmz * fence_lpar: Reduce code duplication in get_lpar_list OBS-URL: https://build.opensuse.org/request/show/868865 OBS-URL: https://build.opensuse.org/package/show/network:ha-clustering:Factory/fence-agents?expand=0&rev=120
This commit is contained in:
parent
7e973f2b01
commit
309f56f9cb
239
0001-Adds-service-account-authentication-to-GCE-fence-age.patch
Normal file
239
0001-Adds-service-account-authentication-to-GCE-fence-age.patch
Normal file
@ -0,0 +1,239 @@
|
||||
From 877be689d75892fe069154cf3bc02909f3edaf50 Mon Sep 17 00:00:00 2001
|
||||
From: Tim Megela <megela@google.com>
|
||||
Date: Mon, 7 Dec 2020 16:06:38 -0500
|
||||
Subject: [PATCH 1/1] Adds service account authentication to GCE fence agent
|
||||
|
||||
Adds the ability to use a service acount for authentiation using --serviceaccount.
|
||||
Adds additional debug information.
|
||||
---
|
||||
.travis.yml | 1 +
|
||||
agents/gce/fence_gce.py | 65 ++++++++++++++++++++++++++-----
|
||||
configure.ac | 1 +
|
||||
tests/data/metadata/fence_gce.xml | 5 +++
|
||||
4 files changed, 62 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/.travis.yml b/.travis.yml
|
||||
index 03cac18a..8e006e85 100644
|
||||
--- a/.travis.yml
|
||||
+++ b/.travis.yml
|
||||
@@ -24,6 +24,7 @@ before_install:
|
||||
- pip install pexpect
|
||||
- pip install boto3
|
||||
- pip install google-api-python-client
|
||||
+ - pip install oauth2client
|
||||
- pip install python-novaclient
|
||||
- pip install python-keystoneclient
|
||||
|
||||
diff --git a/agents/gce/fence_gce.py b/agents/gce/fence_gce.py
|
||||
index a3d98a01..bf5f5693 100644
|
||||
--- a/agents/gce/fence_gce.py
|
||||
+++ b/agents/gce/fence_gce.py
|
||||
@@ -1,5 +1,13 @@
|
||||
#!@PYTHON@ -tt
|
||||
|
||||
+#
|
||||
+# Requires the googleapiclient and oauth2client
|
||||
+# RHEL 7.x: google-api-python-client==1.6.7 python-gflags==2.0 pyasn1==0.4.8 rsa==3.4.2
|
||||
+# RHEL 8.x: nothing additional needed
|
||||
+# SLES 12.x: python-google-api-python-client python-oauth2client python-oauth2client-gce
|
||||
+# SLES 15.x: python3-google-api-python-client python3-oauth2client
|
||||
+#
|
||||
+
|
||||
import atexit
|
||||
import logging
|
||||
import json
|
||||
@@ -20,7 +28,11 @@ 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
|
||||
-
|
||||
+try:
|
||||
+ from oauth2client.client import GoogleCredentials
|
||||
+ from oauth2client.service_account import ServiceAccountCredentials
|
||||
+except:
|
||||
+ pass
|
||||
|
||||
METADATA_SERVER = 'http://metadata.google.internal/computeMetadata/v1/'
|
||||
METADATA_HEADERS = {'Metadata-Flavor': 'Google'}
|
||||
@@ -33,19 +45,22 @@ def replace_api_uri(options, http_request):
|
||||
uri_replacements = []
|
||||
# put any env var replacements first, then baremetalsolution if in options
|
||||
if "FENCE_GCE_URI_REPLACEMENTS" in os.environ:
|
||||
+ logging.debug("FENCE_GCE_URI_REPLACEMENTS environment variable exists")
|
||||
env_uri_replacements = os.environ["FENCE_GCE_URI_REPLACEMENTS"]
|
||||
try:
|
||||
uri_replacements_json = json.loads(env_uri_replacements)
|
||||
if isinstance(uri_replacements_json, list):
|
||||
uri_replacements = uri_replacements_json
|
||||
+ else:
|
||||
+ logging.warning("FENCE_GCE_URI_REPLACEMENTS exists, but is not a JSON List")
|
||||
except ValueError as e:
|
||||
logging.warning("FENCE_GCE_URI_REPLACEMENTS exists but is not valid JSON")
|
||||
- if options.get('--baremetalsolution') is not None:
|
||||
+ if "--baremetalsolution" in options:
|
||||
uri_replacements.append(
|
||||
{
|
||||
"matchlength": 4,
|
||||
"match": "https://compute.googleapis.com/compute/v1/projects/(.*)/zones/(.*)/instances/(.*)/reset(.*)",
|
||||
- "replace": "https://baremetalsolution.googleapis.com/v1alpha1/projects/\\1/locations/\\2/instances/\\3/resetInstance\\4"
|
||||
+ "replace": "https://baremetalsolution.googleapis.com/v1alpha1/projects/\\1/locations/\\2/instances/\\3:resetInstance\\4"
|
||||
})
|
||||
for uri_replacement in uri_replacements:
|
||||
# each uri_replacement should have matchlength, match, and replace
|
||||
@@ -113,7 +128,14 @@ def get_nodes_list(conn, options):
|
||||
|
||||
|
||||
def get_power_status(conn, options):
|
||||
- logging.info("get_power_status");
|
||||
+ logging.debug("get_power_status")
|
||||
+ # if this is bare metal we need to just send back the opposite of the
|
||||
+ # requested action: if on send off, if off send on
|
||||
+ if "--baremetalsolution" in options:
|
||||
+ if options.get("--action") == "on":
|
||||
+ return "off"
|
||||
+ else:
|
||||
+ return "on"
|
||||
try:
|
||||
instance = retry_api_execute(options, conn.instances().get(
|
||||
project=options["--project"],
|
||||
@@ -125,6 +147,10 @@ def get_power_status(conn, options):
|
||||
|
||||
|
||||
def wait_for_operation(conn, options, operation):
|
||||
+ if 'name' not in operation:
|
||||
+ logging.warning('Cannot wait for operation to complete, the'
|
||||
+ ' requested operation will continue asynchronously')
|
||||
+ return
|
||||
project = options["--project"]
|
||||
zone = options["--zone"]
|
||||
while True:
|
||||
@@ -140,6 +166,7 @@ def wait_for_operation(conn, options, operation):
|
||||
|
||||
|
||||
def set_power_status(conn, options):
|
||||
+ logging.debug("set_power_status");
|
||||
try:
|
||||
if options["--action"] == "off":
|
||||
logging.info("Issuing poweroff of %s in zone %s" % (options["--plug"], options["--zone"]))
|
||||
@@ -147,6 +174,7 @@ def set_power_status(conn, options):
|
||||
project=options["--project"],
|
||||
zone=options["--zone"],
|
||||
instance=options["--plug"]))
|
||||
+ logging.info("Poweroff command completed, waiting for the operation to complete")
|
||||
wait_for_operation(conn, options, operation)
|
||||
logging.info("Poweroff of %s in zone %s complete" % (options["--plug"], options["--zone"]))
|
||||
elif options["--action"] == "on":
|
||||
@@ -162,12 +190,14 @@ def set_power_status(conn, options):
|
||||
|
||||
|
||||
def power_cycle(conn, options):
|
||||
+ logging.debug("power_cycle");
|
||||
try:
|
||||
logging.info('Issuing reset of %s in zone %s' % (options["--plug"], options["--zone"]))
|
||||
operation = retry_api_execute(options, conn.instances().reset(
|
||||
project=options["--project"],
|
||||
zone=options["--zone"],
|
||||
instance=options["--plug"]))
|
||||
+ logging.info("Reset command completed, waiting for the operation to complete")
|
||||
wait_for_operation(conn, options, operation)
|
||||
logging.info('Reset of %s in zone %s complete' % (options["--plug"], options["--zone"]))
|
||||
return True
|
||||
@@ -176,7 +206,8 @@ def power_cycle(conn, options):
|
||||
return False
|
||||
|
||||
|
||||
-def get_zone(conn, options, instance):
|
||||
+def get_zone(conn, options):
|
||||
+ logging.debug("get_zone");
|
||||
project = options['--project']
|
||||
instance = options['--plug']
|
||||
fl = 'name="%s"' % instance
|
||||
@@ -207,6 +238,7 @@ def get_metadata(metadata_key, params=None, timeout=None):
|
||||
Raises:
|
||||
urlerror.HTTPError: raises when the GET request fails.
|
||||
"""
|
||||
+ logging.debug("get_metadata");
|
||||
timeout = timeout or 60
|
||||
metadata_url = os.path.join(METADATA_SERVER, metadata_key)
|
||||
params = urlparse.urlencode(params or {})
|
||||
@@ -280,13 +312,22 @@ def define_new_opts():
|
||||
"default" : 5,
|
||||
"order" : 8
|
||||
}
|
||||
+ all_opt["serviceaccount"] = {
|
||||
+ "getopt" : ":",
|
||||
+ "longopt" : "serviceaccount",
|
||||
+ "help" : "--serviceaccount=[filename] Service account json file location e.g. serviceaccount=/somedir/service_account.json",
|
||||
+ "shortdesc" : "Service Account to use for authentication to the google cloud APIs.",
|
||||
+ "required" : "0",
|
||||
+ "order" : 9
|
||||
+ }
|
||||
|
||||
|
||||
def main():
|
||||
conn = None
|
||||
|
||||
device_opt = ["port", "no_password", "zone", "project", "stackdriver-logging",
|
||||
- "method", "baremetalsolution", "apitimeout", "retries", "retrysleep"]
|
||||
+ "method", "baremetalsolution", "apitimeout", "retries", "retrysleep",
|
||||
+ "serviceaccount"]
|
||||
|
||||
atexit.register(atexit_handler)
|
||||
|
||||
@@ -337,10 +378,12 @@ def main():
|
||||
|
||||
# Prepare cli
|
||||
try:
|
||||
- credentials = None
|
||||
- if tuple(googleapiclient.__version__) < tuple("1.6.0"):
|
||||
- import oauth2client.client
|
||||
- credentials = oauth2client.client.GoogleCredentials.get_application_default()
|
||||
+ if options.get("--serviceaccount"):
|
||||
+ credentials = ServiceAccountCredentials.from_json_keyfile_name(options.get("--serviceaccount"))
|
||||
+ logging.debug("using credentials from service account")
|
||||
+ else:
|
||||
+ credentials = GoogleCredentials.get_application_default()
|
||||
+ logging.debug("using application default credentials")
|
||||
conn = googleapiclient.discovery.build(
|
||||
'compute', 'v1', credentials=credentials, cache_discovery=False)
|
||||
except Exception as err:
|
||||
@@ -353,6 +396,8 @@ def main():
|
||||
except Exception as err:
|
||||
fail_usage("Failed retrieving GCE project. Please provide --project option: {}".format(str(err)))
|
||||
|
||||
+ if "--baremetalsolution" in options:
|
||||
+ options["--zone"] = "none"
|
||||
if not options.get("--zone"):
|
||||
try:
|
||||
options["--zone"] = get_zone(conn, options)
|
||||
diff --git a/configure.ac b/configure.ac
|
||||
index c9016c8a..a21f99e8 100644
|
||||
--- a/configure.ac
|
||||
+++ b/configure.ac
|
||||
@@ -241,6 +241,7 @@ if echo "$AGENTS_LIST" | grep -q -E "ovh|vmware_soap"; then
|
||||
fi
|
||||
if echo "$AGENTS_LIST" | grep -q gce; then
|
||||
AC_PYTHON_MODULE(googleapiclient)
|
||||
+ AC_PYTHON_MODULE(oauth2client)
|
||||
if test "x${HAVE_PYMOD_GOOGLEAPICLIENT}" != xyes; then
|
||||
AGENTS_LIST=$(echo "$AGENTS_LIST" | sed -E "s#gce/fence_gce.py( |$)##")
|
||||
AC_MSG_WARN("Not building fence_ovh and fence_gce")
|
||||
diff --git a/tests/data/metadata/fence_gce.xml b/tests/data/metadata/fence_gce.xml
|
||||
index 78c0b0d6..33478721 100644
|
||||
--- a/tests/data/metadata/fence_gce.xml
|
||||
+++ b/tests/data/metadata/fence_gce.xml
|
||||
@@ -68,6 +68,11 @@ For instructions see: https://cloud.google.com/compute/docs/tutorials/python-gui
|
||||
<content type="second" default="5" />
|
||||
<shortdesc lang="en">Time to sleep in seconds between API retries, default is 5.</shortdesc>
|
||||
</parameter>
|
||||
+ <parameter name="serviceaccount" unique="0" required="0">
|
||||
+ <getopt mixed="--serviceaccount=[filename]" />
|
||||
+ <content type="string" />
|
||||
+ <shortdesc lang="en">Service Account to use for authentication to the google cloud APIs.</shortdesc>
|
||||
+ </parameter>
|
||||
<parameter name="quiet" unique="0" required="0">
|
||||
<getopt mixed="-q, --quiet" />
|
||||
<content type="boolean" />
|
||||
--
|
||||
2.26.2
|
||||
|
2
_service
2
_service
@ -6,7 +6,7 @@
|
||||
<param name="filename">fence-agents</param>
|
||||
<param name="versionformat">@PARENT_TAG@+git.%ct.%h</param>
|
||||
<param name="versionrewrite-pattern">v(.*)</param>
|
||||
<param name="revision">master</param>
|
||||
<param name="revision">v4.7.0</param>
|
||||
<param name="changesgenerate">enable</param>
|
||||
</service>
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
<servicedata>
|
||||
<service name="tar_scm">
|
||||
<param name="url">git://github.com/ClusterLabs/fence-agents.git</param>
|
||||
<param name="changesrevision">e3e3199cbf35855c6ab512ac06d7249df94eb3e7</param></service></servicedata>
|
||||
<param name="changesrevision">d3227d206443b2f33876e3620aa9015b81638d39</param></service></servicedata>
|
@ -1,3 +0,0 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:696d69b923f01a5881103d1b7bf19b2a271ecc3dbac7b486893f54d3c6b31abc
|
||||
size 239904
|
3
fence-agents-4.7.0+git.1607346448.17bd8552.tar.xz
Normal file
3
fence-agents-4.7.0+git.1607346448.17bd8552.tar.xz
Normal file
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:93a5833bfef8c3d129e46909dd289dfeb9527ce8af08a1f3fbeeb95d2d7dd598
|
||||
size 249404
|
@ -1,3 +1,37 @@
|
||||
-------------------------------------------------------------------
|
||||
Thu Jan 21 15:13:20 UTC 2021 - Peter Varkoly <varkoly@suse.com>
|
||||
|
||||
- Adds service account authentication to GCE fence agent
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Jan 21 15:05:26 UTC 2021 - varkoly@suse.com
|
||||
|
||||
- Update to version 4.7.0+git.1607346448.17bd8552:
|
||||
* fence_mpath, fence_scsi: Improve logging for failed res/key get
|
||||
* fence_mpath, fence_scsi: Capture stderr in run_cmd()
|
||||
* build: depend on config changes to rebuild when running make after running ./configure
|
||||
* fence_redfish: Fix typo in help.
|
||||
* fence_aws: add support for IMDSv2
|
||||
* spec: add pkg-config file, and set version for obsoletes to avoid failing to build on Fedora 33
|
||||
* Add pkg-config file
|
||||
* fence_scsi: dont write key to device if it's already registered, and open file correctly to avoid using regex against end-of-file
|
||||
* fencing: fix run_command() to allow timeout=0 to mean forever
|
||||
* fencing: fix to make timeout(s)=0 be treated as forever for agents using pexpect
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Oct 29 13:39:38 UTC 2020 - varkoly@suse.com
|
||||
|
||||
- Update to version 4.6.0+git.1603723121.a17eb9d4:
|
||||
* Add a fence_crosslink agent
|
||||
* fencing: fix power-timeout when using new disable-timeout parameter
|
||||
* metadata: update for disable_timeout parameter
|
||||
* fencing: add disable-timeout parameter, and make it default when run from Pacemaker (at least 2.0+)
|
||||
* spec: make telnet a weak dependency
|
||||
* Adds baremetal support to GCE fence agent and API call retries (#355)
|
||||
* spec: add -aws and -gce dependency to -all subpackage
|
||||
* spec: fix ibmz subpackage referring to fence_z instead of fence_ibmz
|
||||
* fence_lpar: Reduce code duplication in get_lpar_list
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Fri Jun 19 14:34:32 UTC 2020 - dakechi@suse.com
|
||||
|
||||
|
@ -29,11 +29,12 @@ Name: fence-agents
|
||||
Summary: Fence Agents for High Availability
|
||||
License: GPL-2.0-only AND LGPL-2.1-only
|
||||
Group: Productivity/Clustering/HA
|
||||
Version: 4.5.2+git.1592573838.1eee0863
|
||||
Version: 4.7.0+git.1607346448.17bd8552
|
||||
Release: 0
|
||||
Url: https://github.com/ClusterLabs/fence-agents
|
||||
Source0: %{name}-%{version}.tar.xz
|
||||
Patch1: 0001-Use-Python-3-for-all-scripts-bsc-1065966.patch
|
||||
Patch2: 0001-Adds-service-account-authentication-to-GCE-fence-age.patch
|
||||
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||
BuildRequires: %{python_version}
|
||||
@ -139,6 +140,7 @@ development.
|
||||
%if %{python_version} == "python3"
|
||||
%patch1 -p1
|
||||
%endif
|
||||
%patch2 -p1
|
||||
|
||||
%build
|
||||
CFLAGS="${CFLAGS} ${RPM_OPT_FLAGS}"
|
||||
@ -189,6 +191,7 @@ PYTHONPATH=fence/agents/lib %{python_version} fence/agents/lib/tests/test_fencin
|
||||
%exclude %{_mandir}/man8/fence_dummy*
|
||||
%{_mandir}/man8/fence_*
|
||||
%{_libexecdir}/fence_*
|
||||
/usr/share/pkgconfig/fence-agents.pc
|
||||
|
||||
%files amt_ws
|
||||
%{_sbindir}/fence_amt_ws
|
||||
|
Loading…
Reference in New Issue
Block a user