import fence-agents-4.10.0-30.el9

This commit is contained in:
CentOS Sources 2022-11-15 01:34:36 -05:00 committed by Stepan Oksanichenko
parent cd38770861
commit e4e00581c8
15 changed files with 1574 additions and 201 deletions

View File

@ -2,7 +2,6 @@
e1b766b2b1601fde67b3b19ed2f13b9746bb1cca SOURCES/MarkupSafe-2.0.1.tar.gz
e1fb5dc6f95a85e7d1f93c6701b331201e8b5479 SOURCES/PyJWT-2.1.0-py3-none-any.whl
53fc16036940089ceadd4127381e40fd6106a7ed SOURCES/PyYAML-5.1.tar.gz
a8c40a3ae9d4c159382a58db3153d83e5521c51e SOURCES/PyYAML-6.0.tar.gz
b53cba68215f389dffaa51ee2afe10c943278646 SOURCES/adal-1.2.7-py2.py3-none-any.whl
bda476965c380701795849179ed91e9d8134ec7c SOURCES/aliyun-python-sdk-core-2.11.5.tar.gz
2a3e6ee5713a3cfb47e63a739cc9a05580d95dd6 SOURCES/aliyun_python_sdk_ecs-4.24.7-py2.py3-none-any.whl
@ -25,11 +24,9 @@ b13e22d55867e2ca5f92e5289cfdc21ba6e343aa SOURCES/certifi-2021.10.8.tar.gz
96faab7de7e9a71b37f22adb64daf2898e967e3e SOURCES/chardet-3.0.4-py2.py3-none-any.whl
e9eb83c71c09b3c8249bd7d6d2619b65fff03874 SOURCES/chardet-4.0.0-py2.py3-none-any.whl
865df92e66e5dc7b940144cbad8115c07dc8784f SOURCES/charset-normalizer-2.0.7.tar.gz
9fa96037a1a985fe7dda81c0e1e35ae015163d88 SOURCES/charset_normalizer-2.0.4-py3-none-any.whl
a8ee91adf4644bbdccfc73ead88f4cd0df7e3552 SOURCES/colorama-0.3.3.tar.gz
444d5ea320f95cd6205535a1be2805598847191b SOURCES/colorama-0.4.3-py2.py3-none-any.whl
536a57d70d505e4de8595650603d7e2ecc58b34b SOURCES/cryptography-3.3.2-cp36-abi3-manylinux2010_x86_64.whl
dfabded3494bffe6965b1bf3d37383736e642bdb SOURCES/debtcollector-2.2.0-py3-none-any.whl
4b50bebad4c5036c030a78cbb869d039bc91c4ec SOURCES/distro-1.5.0-py2.py3-none-any.whl
aafeddc912b74557754b2aaece3f1364be8e9f6a SOURCES/docutils-0.15.2-py3-none-any.whl
1ec823f807b73a377cdd47d12e2e34f046bfc889 SOURCES/fence-agents-4.10.0.tar.gz
@ -41,33 +38,19 @@ ac160113ba8b78b0688edda9f9a088c0b4b5ded2 SOURCES/google_api_core-1.30.0-py2.py3-
dc553afa7a3f23b92ee9ecd27d0b15153c0e9f75 SOURCES/googleapis_common_protos-1.53.0-py2.py3-none-any.whl
74ec77d2e2ef6b2ef8503e6e398faa6f3ba298ae SOURCES/httplib2-0.19.1-py3-none-any.whl
999b6718b4d789d8ca0d2ddf7c07826154291825 SOURCES/idna-2.10-py2.py3-none-any.whl
e3a19aca36f6631ba9e33e66b855835776e8e120 SOURCES/idna-3.2-py3-none-any.whl
08c0449533fc94462f78652dea209099754d9ee4 SOURCES/idna-3.3.tar.gz
8672ed298c51abba24fdf5298ddeef7b16027071 SOURCES/iso8601-0.1.16-py2.py3-none-any.whl
240cc4206740fafacb74bbf0d0c4ff70e41c8a85 SOURCES/isodate-0.6.0-py2.py3-none-any.whl
68904717c48e95adb47d815178fff8d80f39b2ab SOURCES/jmespath-0.7.1-py2.py3-none-any.whl
22a38dbc79cc3cbe53c2bf306ad22a472be1a6f4 SOURCES/keystoneauth1-4.3.1-py3-none-any.whl
d06a9547b1a87e9c51b0a7c708189d993f2e3d89 SOURCES/kubernetes-12.0.1.tar.gz
194b341fe37fe6ce992c637a728484e3cee47394 SOURCES/msgpack-1.0.2.tar.gz
ba59fbd147307e7ef92a1fad259e7dc0b07e79e0 SOURCES/msrest-0.6.21-py2.py3-none-any.whl
3d65a50b68e3aa506b6af42be485ed2710afa9da SOURCES/msrestazure-0.6.4-py2.py3-none-any.whl
ee77c30d5350378e9ca9932b724d1a26c9cc164b SOURCES/netaddr-0.8.0-py2.py3-none-any.whl
c1dd2b481a0101eb518bf47bdf40ea53ab61ca62 SOURCES/netifaces-0.11.0.tar.gz
0b5ba4c47bdd7ff17ca4954349d7213a95d03f25 SOURCES/oauthlib-3.1.1-py2.py3-none-any.whl
f6efa66f6106b069b5c0e0cf8cc677e4e96c91ca SOURCES/oauthlib-3.1.1.tar.gz
570d69d8c108ebb8aee562389d13b07dfb61ce25 SOURCES/openshift-0.12.1.tar.gz
2b0aea8c7985b474f0719b916a1b6475caedf42f SOURCES/os_service_types-1.7.0-py2.py3-none-any.whl
e26e191810fd455958aa3fcf7c7447180c14de8d SOURCES/oslo.config-8.7.1-py3-none-any.whl
7375d2b1c5d3b13d5637a00b9514104069bca329 SOURCES/oslo.i18n-5.0.1-py3-none-any.whl
8a4aab8b645772fa6132df1ce23267b2fae356d3 SOURCES/oslo.serialization-4.2.0-py3-none-any.whl
b302350fda92e8b96a402fbb4cdf639f06192b62 SOURCES/oslo.utils-4.10.0-py3-none-any.whl
2b10cb7681bc678ba4ff3be524b28d783e4095ce SOURCES/packaging-20.9-py2.py3-none-any.whl
f712c7731d0d65cfc8fc7c61afeeeeca4b84b549 SOURCES/packaging-21.0-py3-none-any.whl
bccbc1bf76a9db46998eb8e1ffa2f2a2baf9237a SOURCES/packaging-21.2-py3-none-any.whl
d3d07b885ca4d10994a30682106e37785e6e780c SOURCES/pbr-5.6.0-py2.py3-none-any.whl
0c3fc83ca045abeec9ce82bb7ee3e77f0390bca4 SOURCES/pexpect-4.8.0-py2.py3-none-any.whl
18659a0dea5600df33eab90dec1b597e2437aebd SOURCES/poetry-core-1.0.7.tar.gz
5ad34ad3dbfaf6d4e72860287043120c641e4524 SOURCES/prettytable-2.2.0-py3-none-any.whl
b09c4655a4c8bd24c54a078e960750ec9e8688d6 SOURCES/prompt_toolkit-2.0.10-py3-none-any.whl
5a90b79a9630873c7f2db79544c46146bb6af5e8 SOURCES/protobuf-3.17.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl
0827aaa6fdc3dc4256e06fa1c3991fb4ed20a693 SOURCES/ptyprocess-0.7.0-py2.py3-none-any.whl
@ -90,15 +73,11 @@ e58f6fa56f1baf766ba147dbc9fbfc67fa92e234 SOURCES/pyroute2.ethtool-0.6.4.tar.gz
c2ba10c775b7a52a4b57cac4d4110a0c0f812a82 SOURCES/python-dateutil-2.8.2.tar.gz
1dc2fa004aa6517f1620e55d8a7b8e68a9cf2a47 SOURCES/python-string-utils-1.0.0.tar.gz
3005ff67df93ee276fb8631e17c677df852254ad SOURCES/python_dateutil-2.8.1-py2.py3-none-any.whl
e10df4212f19d34774bb329e8b497dafa4d099d5 SOURCES/python_keystoneclient-4.2.0-py3-none-any.whl
2c61c4407646813e5e5dd6f09586704efca371f0 SOURCES/python_novaclient-17.5.0-py3-none-any.whl
b97c6966fb8fd273f0bc8533cf0dee4978b9f373 SOURCES/pytz-2021.1-py2.py3-none-any.whl
b1009d9fd6acadc64e1a3cecb6f0083fe047e753 SOURCES/requests-2.25.1-py2.py3-none-any.whl
d20e2df000dd43249c3a9eed041f08a812a93423 SOURCES/requests-2.26.0-py2.py3-none-any.whl
8c7a89d183d3e9b70bf91ba5b75eccf7111b9d8d SOURCES/requests-2.26.0.tar.gz
f139aed770519b6a095b8fdc888d03955cbe9d8e SOURCES/requests-oauthlib-1.3.0.tar.gz
25d5667d7a61586f5ddaac7e08cc3053db3d8661 SOURCES/requests_oauthlib-1.3.0-py2.py3-none-any.whl
b8e2041ff9ad37dba2f78e4b59b57cbed5f1b8ff SOURCES/rfc3986-1.5.0-py2.py3-none-any.whl
c0d5be2edf538122d35fe06c29d2d7a5f22f3117 SOURCES/rsa-4.7.2-py3-none-any.whl
e8a53067e03fe1b6682fd99a40a7359396a06daa SOURCES/rsa-4.7.2.tar.gz
abf532a0cc31ea224e3895f60025e7466b16d7ae SOURCES/ruamel.yaml-0.15.100.tar.gz
@ -110,14 +89,11 @@ d5354718cb8c9330d3abc27445467ce8a5ed9d70 SOURCES/setuptools-58.3.0.tar.gz
a4f02fddae697614e356cadfddb6241cc7737f38 SOURCES/setuptools_scm-6.3.2.tar.gz
79e6f2e4f9e24898f1896df379871b9c9922f147 SOURCES/six-1.16.0-py2.py3-none-any.whl
06fa0bb50f2a4e2917fd14c21e9d2d5508ce0163 SOURCES/six-1.16.0.tar.gz
c612ea4b006feec1444ac61c233632f7e4852380 SOURCES/stevedore-3.4.0-py3-none-any.whl
47a980b20875d1a1714e921552b5bb0eda190f37 SOURCES/suds_community-0.8.5-py3-none-any.whl
b42b7960047441db7dc021cc20e14279bd836f8d SOURCES/tomli-1.0.1.tar.gz
83be56610e5f824bb05ff7a5618d6d4df9b6cc08 SOURCES/uritemplate-3.0.1-py2.py3-none-any.whl
206b17697417cbf5fc55f1e39c7ceb2197fe3e63 SOURCES/urllib3-1.26.6-py2.py3-none-any.whl
eb35c3fd8b0867ae988a15917d6b80e8bdf60222 SOURCES/urllib3-1.26.7.tar.gz
7126323614cada181bc8b06436e80ef372ff8656 SOURCES/wcwidth-0.1.9-py2.py3-none-any.whl
6cbb5d6384f6d2c8667fb3c5710ecf90dbf9e7fc SOURCES/wcwidth-0.2.5-py2.py3-none-any.whl
540f083782c584989c1a0f69ffd69ba7aae07db6 SOURCES/websocket-client-1.2.1.tar.gz
b6c48d8714e043524be7a869d1db0adcd8441cd4 SOURCES/wheel-0.37.0-py2.py3-none-any.whl
6c18d34144c6faba208509b8091d35acc9842081 SOURCES/wrapt-1.12.1.tar.gz

24
.gitignore vendored
View File

@ -2,7 +2,6 @@ SOURCES/Jinja2-3.0.2.tar.gz
SOURCES/MarkupSafe-2.0.1.tar.gz
SOURCES/PyJWT-2.1.0-py3-none-any.whl
SOURCES/PyYAML-5.1.tar.gz
SOURCES/PyYAML-6.0.tar.gz
SOURCES/adal-1.2.7-py2.py3-none-any.whl
SOURCES/aliyun-python-sdk-core-2.11.5.tar.gz
SOURCES/aliyun_python_sdk_ecs-4.24.7-py2.py3-none-any.whl
@ -25,11 +24,9 @@ SOURCES/cffi-1.14.5-cp39-cp39-manylinux1_x86_64.whl
SOURCES/chardet-3.0.4-py2.py3-none-any.whl
SOURCES/chardet-4.0.0-py2.py3-none-any.whl
SOURCES/charset-normalizer-2.0.7.tar.gz
SOURCES/charset_normalizer-2.0.4-py3-none-any.whl
SOURCES/colorama-0.3.3.tar.gz
SOURCES/colorama-0.4.3-py2.py3-none-any.whl
SOURCES/cryptography-3.3.2-cp36-abi3-manylinux2010_x86_64.whl
SOURCES/debtcollector-2.2.0-py3-none-any.whl
SOURCES/distro-1.5.0-py2.py3-none-any.whl
SOURCES/docutils-0.15.2-py3-none-any.whl
SOURCES/fence-agents-4.10.0.tar.gz
@ -41,33 +38,19 @@ SOURCES/google_auth_httplib2-0.1.0-py2.py3-none-any.whl
SOURCES/googleapis_common_protos-1.53.0-py2.py3-none-any.whl
SOURCES/httplib2-0.19.1-py3-none-any.whl
SOURCES/idna-2.10-py2.py3-none-any.whl
SOURCES/idna-3.2-py3-none-any.whl
SOURCES/idna-3.3.tar.gz
SOURCES/iso8601-0.1.16-py2.py3-none-any.whl
SOURCES/isodate-0.6.0-py2.py3-none-any.whl
SOURCES/jmespath-0.7.1-py2.py3-none-any.whl
SOURCES/keystoneauth1-4.3.1-py3-none-any.whl
SOURCES/kubernetes-12.0.1.tar.gz
SOURCES/msgpack-1.0.2.tar.gz
SOURCES/msrest-0.6.21-py2.py3-none-any.whl
SOURCES/msrestazure-0.6.4-py2.py3-none-any.whl
SOURCES/netaddr-0.8.0-py2.py3-none-any.whl
SOURCES/netifaces-0.11.0.tar.gz
SOURCES/oauthlib-3.1.1-py2.py3-none-any.whl
SOURCES/oauthlib-3.1.1.tar.gz
SOURCES/openshift-0.12.1.tar.gz
SOURCES/os_service_types-1.7.0-py2.py3-none-any.whl
SOURCES/oslo.config-8.7.1-py3-none-any.whl
SOURCES/oslo.i18n-5.0.1-py3-none-any.whl
SOURCES/oslo.serialization-4.2.0-py3-none-any.whl
SOURCES/oslo.utils-4.10.0-py3-none-any.whl
SOURCES/packaging-20.9-py2.py3-none-any.whl
SOURCES/packaging-21.0-py3-none-any.whl
SOURCES/packaging-21.2-py3-none-any.whl
SOURCES/pbr-5.6.0-py2.py3-none-any.whl
SOURCES/pexpect-4.8.0-py2.py3-none-any.whl
SOURCES/poetry-core-1.0.7.tar.gz
SOURCES/prettytable-2.2.0-py3-none-any.whl
SOURCES/prompt_toolkit-2.0.10-py3-none-any.whl
SOURCES/protobuf-3.17.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl
SOURCES/ptyprocess-0.7.0-py2.py3-none-any.whl
@ -90,15 +73,11 @@ SOURCES/pyroute2.nslink-0.6.4.tar.gz
SOURCES/python-dateutil-2.8.2.tar.gz
SOURCES/python-string-utils-1.0.0.tar.gz
SOURCES/python_dateutil-2.8.1-py2.py3-none-any.whl
SOURCES/python_keystoneclient-4.2.0-py3-none-any.whl
SOURCES/python_novaclient-17.5.0-py3-none-any.whl
SOURCES/pytz-2021.1-py2.py3-none-any.whl
SOURCES/requests-2.25.1-py2.py3-none-any.whl
SOURCES/requests-2.26.0-py2.py3-none-any.whl
SOURCES/requests-2.26.0.tar.gz
SOURCES/requests-oauthlib-1.3.0.tar.gz
SOURCES/requests_oauthlib-1.3.0-py2.py3-none-any.whl
SOURCES/rfc3986-1.5.0-py2.py3-none-any.whl
SOURCES/rsa-4.7.2-py3-none-any.whl
SOURCES/rsa-4.7.2.tar.gz
SOURCES/ruamel.yaml-0.15.100.tar.gz
@ -110,14 +89,11 @@ SOURCES/setuptools-58.3.0.tar.gz
SOURCES/setuptools_scm-6.3.2.tar.gz
SOURCES/six-1.16.0-py2.py3-none-any.whl
SOURCES/six-1.16.0.tar.gz
SOURCES/stevedore-3.4.0-py3-none-any.whl
SOURCES/suds_community-0.8.5-py3-none-any.whl
SOURCES/tomli-1.0.1.tar.gz
SOURCES/uritemplate-3.0.1-py2.py3-none-any.whl
SOURCES/urllib3-1.26.6-py2.py3-none-any.whl
SOURCES/urllib3-1.26.7.tar.gz
SOURCES/wcwidth-0.1.9-py2.py3-none-any.whl
SOURCES/wcwidth-0.2.5-py2.py3-none-any.whl
SOURCES/websocket-client-1.2.1.tar.gz
SOURCES/wheel-0.37.0-py2.py3-none-any.whl
SOURCES/wrapt-1.12.1.tar.gz

View File

@ -0,0 +1,139 @@
From e339f304d4423a0e661d915f72ba88553b21d74a Mon Sep 17 00:00:00 2001
From: MSSedusch <sedusch@microsoft.com>
Date: Tue, 28 Sep 2021 12:23:37 +0000
Subject: [PATCH 1/2] add support for sovereign clouds and MSI
---
lib/azure_fence.py.py | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/lib/azure_fence.py.py b/lib/azure_fence.py.py
index 1f38bd4ea..75b63fdad 100644
--- a/lib/azure_fence.py.py
+++ b/lib/azure_fence.py.py
@@ -286,11 +286,11 @@ def get_azure_credentials(config):
credentials = None
cloud_environment = get_azure_cloud_environment(config)
if config.UseMSI and cloud_environment:
- from msrestazure.azure_active_directory import MSIAuthentication
- credentials = MSIAuthentication(cloud_environment=cloud_environment)
+ from azure.identity import ManagedIdentityCredential
+ credentials = ManagedIdentityCredential(cloud_environment=cloud_environment)
elif config.UseMSI:
- from msrestazure.azure_active_directory import MSIAuthentication
- credentials = MSIAuthentication()
+ from azure.identity import ManagedIdentityCredential
+ credentials = ManagedIdentityCredential()
elif cloud_environment:
try:
# try to use new libraries ClientSecretCredential (azure.identity, based on azure.core)
@@ -340,7 +340,8 @@ def get_azure_compute_client(config):
compute_client = ComputeManagementClient(
credentials,
config.SubscriptionId,
- base_url=cloud_environment.endpoints.resource_manager
+ base_url=cloud_environment.endpoints.resource_manager,
+ credential_scopes=[cloud_environment.endpoints.resource_manager + "/.default"]
)
else:
compute_client = ComputeManagementClient(
@@ -359,7 +360,8 @@ def get_azure_network_client(config):
network_client = NetworkManagementClient(
credentials,
config.SubscriptionId,
- base_url=cloud_environment.endpoints.resource_manager
+ base_url=cloud_environment.endpoints.resource_manager,
+ credential_scopes=[cloud_environment.endpoints.resource_manager + "/.default"]
)
else:
network_client = NetworkManagementClient(
From f08f02a7561e78dd9c95c66ccdcf6246c5ee7d6a Mon Sep 17 00:00:00 2001
From: MSSedusch <sedusch@microsoft.com>
Date: Fri, 1 Oct 2021 15:28:39 +0000
Subject: [PATCH 2/2] compatiblity fix
---
lib/azure_fence.py.py | 54 ++++++++++++++++++++++++++++++-------------
1 file changed, 38 insertions(+), 16 deletions(-)
diff --git a/lib/azure_fence.py.py b/lib/azure_fence.py.py
index 75b63fdad..5ca71eb42 100644
--- a/lib/azure_fence.py.py
+++ b/lib/azure_fence.py.py
@@ -286,11 +286,19 @@ def get_azure_credentials(config):
credentials = None
cloud_environment = get_azure_cloud_environment(config)
if config.UseMSI and cloud_environment:
- from azure.identity import ManagedIdentityCredential
- credentials = ManagedIdentityCredential(cloud_environment=cloud_environment)
+ try:
+ from azure.identity import ManagedIdentityCredential
+ credentials = ManagedIdentityCredential(cloud_environment=cloud_environment)
+ except ImportError:
+ from msrestazure.azure_active_directory import MSIAuthentication
+ credentials = MSIAuthentication(cloud_environment=cloud_environment)
elif config.UseMSI:
- from azure.identity import ManagedIdentityCredential
- credentials = ManagedIdentityCredential()
+ try:
+ from azure.identity import ManagedIdentityCredential
+ credentials = ManagedIdentityCredential()
+ except ImportError:
+ from msrestazure.azure_active_directory import MSIAuthentication
+ credentials = MSIAuthentication()
elif cloud_environment:
try:
# try to use new libraries ClientSecretCredential (azure.identity, based on azure.core)
@@ -337,12 +345,19 @@ def get_azure_compute_client(config):
credentials = get_azure_credentials(config)
if cloud_environment:
- compute_client = ComputeManagementClient(
- credentials,
- config.SubscriptionId,
- base_url=cloud_environment.endpoints.resource_manager,
- credential_scopes=[cloud_environment.endpoints.resource_manager + "/.default"]
- )
+ try:
+ compute_client = ComputeManagementClient(
+ credentials,
+ config.SubscriptionId,
+ base_url=cloud_environment.endpoints.resource_manager,
+ credential_scopes=[cloud_environment.endpoints.resource_manager + "/.default"]
+ )
+ except TypeError:
+ compute_client = ComputeManagementClient(
+ credentials,
+ config.SubscriptionId,
+ base_url=cloud_environment.endpoints.resource_manager
+ )
else:
compute_client = ComputeManagementClient(
credentials,
@@ -357,12 +372,19 @@ def get_azure_network_client(config):
credentials = get_azure_credentials(config)
if cloud_environment:
- network_client = NetworkManagementClient(
- credentials,
- config.SubscriptionId,
- base_url=cloud_environment.endpoints.resource_manager,
- credential_scopes=[cloud_environment.endpoints.resource_manager + "/.default"]
- )
+ try:
+ network_client = NetworkManagementClient(
+ credentials,
+ config.SubscriptionId,
+ base_url=cloud_environment.endpoints.resource_manager,
+ credential_scopes=[cloud_environment.endpoints.resource_manager + "/.default"]
+ )
+ except TypeError:
+ network_client = NetworkManagementClient(
+ credentials,
+ config.SubscriptionId,
+ base_url=cloud_environment.endpoints.resource_manager
+ )
else:
network_client = NetworkManagementClient(
credentials,

View File

@ -0,0 +1,22 @@
From fbca33a536413565108374dd4ed3237b6f7896bd Mon Sep 17 00:00:00 2001
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
Date: Mon, 15 Aug 2022 10:40:19 +0200
Subject: [PATCH] fencing: source_env(): dont process empty lines
---
lib/fencing.py.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/lib/fencing.py.py b/lib/fencing.py.py
index fc3679e33..940bd01d1 100644
--- a/lib/fencing.py.py
+++ b/lib/fencing.py.py
@@ -1264,7 +1264,7 @@ def source_env(env_file):
executable="/bin/sh")
# replace env
os.environ.clear()
- os.environ.update(line.partition('=')[::2] for line in output.decode("utf-8").split('\0'))
+ os.environ.update(line.partition('=')[::2] for line in output.decode("utf-8").split('\0') if not re.match("^\s*$", line))
# Convert array of format [[key1, value1], [key2, value2], ... [keyN, valueN]] to dict, where key is
# in format a.b.c.d...z and returned dict has key only z

View File

@ -0,0 +1,291 @@
From 999f2f8b4dc7d258679daf8c3f13d9b317ff4435 Mon Sep 17 00:00:00 2001
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
Date: Thu, 7 Apr 2022 13:11:12 +0200
Subject: [PATCH] all agents: unify ssl parameters to avoid having to use --ssl
when using --ssl-secure/--ssl-insecure for some agents
THIS MIGHT BREAK SETUPS USING fence_docker or fence_pve!
---
agents/cisco_ucs/fence_cisco_ucs.py | 9 +++++----
agents/docker/fence_docker.py | 9 ++++++---
agents/ibmz/fence_ibmz.py | 4 ++--
agents/rhevm/fence_rhevm.py | 8 ++++----
agents/skalar/fence_skalar.py | 2 +-
agents/vmware_rest/fence_vmware_rest.py | 8 ++++----
agents/vmware_soap/fence_vmware_soap.py | 2 +-
agents/vmware_vcloud/fence_vmware_vcloud.py | 4 ++--
agents/zvm/fence_zvmip.py | 8 +++++---
lib/fencing.py.py | 6 ++++++
tests/data/metadata/fence_docker.xml | 4 ++--
13 files changed, 64 insertions(+), 31 deletions(-)
diff --git a/agents/cisco_ucs/fence_cisco_ucs.py b/agents/cisco_ucs/fence_cisco_ucs.py
index 2280dbbc7..b85379a73 100644
--- a/agents/cisco_ucs/fence_cisco_ucs.py
+++ b/agents/cisco_ucs/fence_cisco_ucs.py
@@ -99,7 +99,7 @@ def get_list(conn, options):
def send_command(opt, command, timeout):
## setup correct URL
- if "--ssl" in opt or "--ssl-secure" in opt or "--ssl-insecure" in opt:
+ if "--ssl-secure" in opt or "--ssl-insecure" in opt:
url = "https:"
else:
url = "http:"
@@ -114,13 +114,14 @@ def send_command(opt, command, timeout):
conn.setopt(pycurl.POSTFIELDS, command.encode("ascii"))
conn.setopt(pycurl.WRITEFUNCTION, web_buffer.write)
conn.setopt(pycurl.TIMEOUT, timeout)
- if "--ssl" in opt or "--ssl-secure" in opt:
+
+ if "--ssl-secure" in opt:
conn.setopt(pycurl.SSL_VERIFYPEER, 1)
conn.setopt(pycurl.SSL_VERIFYHOST, 2)
-
- if "--ssl-insecure" in opt:
+ elif "--ssl-insecure" in opt:
conn.setopt(pycurl.SSL_VERIFYPEER, 0)
conn.setopt(pycurl.SSL_VERIFYHOST, 0)
+
conn.perform()
result = web_buffer.getvalue().decode()
diff --git a/agents/docker/fence_docker.py b/agents/docker/fence_docker.py
index fef87da86..004402518 100644
--- a/agents/docker/fence_docker.py
+++ b/agents/docker/fence_docker.py
@@ -43,7 +43,7 @@ def get_list(conn, options):
def send_cmd(options, cmd, post = False):
- url = "http%s://%s:%s/v%s/%s" % ("s" if "--ssl" in options else "", options["--ip"], options["--ipport"], options["--api-version"], cmd)
+ url = "http%s://%s:%s/v%s/%s" % ("s" if "--ssl-secure" in options or "--ssl-insecure" in options else "", options["--ip"], options["--ipport"], options["--api-version"], cmd)
conn = pycurl.Curl()
output_buffer = io.BytesIO()
if logging.getLogger().getEffectiveLevel() < logging.WARNING:
@@ -55,7 +55,8 @@ def send_cmd(options, cmd, post = False):
conn.setopt(pycurl.POSTFIELDSIZE, 0)
conn.setopt(pycurl.WRITEFUNCTION, output_buffer.write)
conn.setopt(pycurl.TIMEOUT, int(options["--shell-timeout"]))
- if "--ssl" in options:
+
+ if "--ssl-secure" in options:
if not (set(("--tlscert", "--tlskey", "--tlscacert")) <= set(options)):
fail_usage("Failed. If --ssl option is used, You have to also \
specify: --tlscert, --tlskey and --tlscacert")
@@ -63,7 +64,7 @@ def send_cmd(options, cmd, post = False):
conn.setopt(pycurl.SSLCERT, options["--tlscert"])
conn.setopt(pycurl.SSLKEY, options["--tlskey"])
conn.setopt(pycurl.CAINFO, options["--tlscacert"])
- else:
+ elif "--ssl-insecure" in options:
conn.setopt(pycurl.SSL_VERIFYPEER, 0)
conn.setopt(pycurl.SSL_VERIFYHOST, 0)
@@ -136,6 +137,8 @@ def main():
device_opt = ["ipaddr", "no_password", "no_login", "port", "method", "web", "tlscert", "tlskey", "tlscacert", "ssl", "api_version"]
+ all_opt["ssl"]["default"] = "1"
+
options = check_input(device_opt, process_input(device_opt))
docs = { }
diff --git a/agents/ibmz/fence_ibmz.py b/agents/ibmz/fence_ibmz.py
index 47408ccf4..d477adeb9 100644
--- a/agents/ibmz/fence_ibmz.py
+++ b/agents/ibmz/fence_ibmz.py
@@ -534,7 +534,7 @@ def main():
requests_log.propagate = True
if "--verbose" in options:
requests_log.setLevel(logging.DEBUG)
- if "--ssl-secure" not in options:
+ if "--ssl-insecure" in options:
urllib3.disable_warnings(
category=urllib3.exceptions.InsecureRequestWarning)
@@ -548,7 +548,7 @@ def main():
'connect_timeout': int(options['--connect-timeout']),
'read_timeout': int(options['--read-timeout']),
'port': int(options['--ipport']),
- 'ssl_verify': bool('--ssl-secure' in options),
+ 'ssl_verify': bool('--ssl-insecure' not in options),
}
try:
conn = APIClient(hmc_address, hmc_userid, hmc_password, config)
diff --git a/agents/rhevm/fence_rhevm.py b/agents/rhevm/fence_rhevm.py
index 25aecbe58..5f74d06f6 100644
--- a/agents/rhevm/fence_rhevm.py
+++ b/agents/rhevm/fence_rhevm.py
@@ -85,7 +85,7 @@ def send_command(opt, command, method="GET"):
logging.debug("auto-detected API version: " + opt["--api-version"])
## setup correct URL
- if "--ssl" in opt or "--ssl-secure" in opt or "--ssl-insecure" in opt:
+ if "--ssl-secure" in opt or "--ssl-insecure" in opt:
url = "https:"
else:
url = "http:"
@@ -126,11 +126,11 @@ def send_command(opt, command, method="GET"):
conn.setopt(pycurl.COOKIEJAR, cookie_file)
conn.setopt(pycurl.TIMEOUT, int(opt["--shell-timeout"]))
- if "--ssl" in opt or "--ssl-secure" in opt:
+
+ if "--ssl-secure" in opt:
conn.setopt(pycurl.SSL_VERIFYPEER, 1)
conn.setopt(pycurl.SSL_VERIFYHOST, 2)
-
- if "--ssl-insecure" in opt:
+ elif "--ssl-insecure" in opt:
conn.setopt(pycurl.SSL_VERIFYPEER, 0)
conn.setopt(pycurl.SSL_VERIFYHOST, 0)
diff --git a/agents/skalar/fence_skalar.py b/agents/skalar/fence_skalar.py
index 959527411..0e11d83f9 100644
--- a/agents/skalar/fence_skalar.py
+++ b/agents/skalar/fence_skalar.py
@@ -200,7 +200,7 @@ def main():
run_delay(options)
proto = "https://"
- if "--ssl" in options or "--ssl-secure" in options:
+ if "--ssl-secure" in options:
ssl_verify = True
elif "--ssl-insecure" in options:
ssl_verify = False
diff --git a/agents/vmware_rest/fence_vmware_rest.py b/agents/vmware_rest/fence_vmware_rest.py
index e49fd5663..4b884fc62 100644
--- a/agents/vmware_rest/fence_vmware_rest.py
+++ b/agents/vmware_rest/fence_vmware_rest.py
@@ -69,7 +69,7 @@ def connect(opt):
conn = pycurl.Curl()
## setup correct URL
- if "--ssl" in opt or "--ssl-secure" in opt or "--ssl-insecure" in opt:
+ if "--ssl-secure" in opt or "--ssl-insecure" in opt:
conn.base_url = "https:"
else:
conn.base_url = "http:"
@@ -89,11 +89,11 @@ def connect(opt):
conn.setopt(pycurl.USERPWD, opt["--username"] + ":" + opt["--password"])
conn.setopt(pycurl.TIMEOUT, int(opt["--shell-timeout"]))
- if "--ssl" in opt or "--ssl-secure" in opt:
+
+ if "--ssl-secure" in opt:
conn.setopt(pycurl.SSL_VERIFYPEER, 1)
conn.setopt(pycurl.SSL_VERIFYHOST, 2)
-
- if "--ssl-insecure" in opt:
+ elif "--ssl-insecure" in opt:
conn.setopt(pycurl.SSL_VERIFYPEER, 0)
conn.setopt(pycurl.SSL_VERIFYHOST, 0)
diff --git a/agents/vmware_soap/fence_vmware_soap.py b/agents/vmware_soap/fence_vmware_soap.py
index 2cd45e0b3..51fb0f147 100644
--- a/agents/vmware_soap/fence_vmware_soap.py
+++ b/agents/vmware_soap/fence_vmware_soap.py
@@ -34,7 +34,7 @@ def send(self, request):
def soap_login(options):
run_delay(options)
- if "--ssl" in options or "--ssl-secure" in options or "--ssl-insecure" in options:
+ if "--ssl-secure" in options or "--ssl-insecure" in options:
if "--ssl-insecure" in options:
import ssl
import urllib3
diff --git a/agents/vmware_vcloud/fence_vmware_vcloud.py b/agents/vmware_vcloud/fence_vmware_vcloud.py
index 42372a83d..7626b82bb 100644
--- a/agents/vmware_vcloud/fence_vmware_vcloud.py
+++ b/agents/vmware_vcloud/fence_vmware_vcloud.py
@@ -60,7 +60,7 @@ def connect(opt):
conn = pycurl.Curl()
## setup correct URL
- if "--ssl" in opt or "--ssl-secure" in opt or "--ssl-insecure" in opt:
+ if "--ssl-secure" in opt or "--ssl-insecure" in opt:
conn.base_url = "https:"
else:
conn.base_url = "http:"
@@ -76,7 +76,7 @@ def connect(opt):
conn.setopt(pycurl.USERPWD, opt["--username"] + ":" + opt["--password"])
conn.setopt(pycurl.TIMEOUT, int(opt["--shell-timeout"]))
- if "--ssl" in opt or "--ssl-secure" in opt:
+ if "--ssl-secure" in opt:
conn.setopt(pycurl.SSL_VERIFYPEER, 1)
conn.setopt(pycurl.SSL_VERIFYHOST, 2)
elif "--ssl-insecure" in opt:
diff --git a/agents/zvm/fence_zvmip.py b/agents/zvm/fence_zvmip.py
index e8f849eda..90ca95d45 100644
--- a/agents/zvm/fence_zvmip.py
+++ b/agents/zvm/fence_zvmip.py
@@ -26,7 +26,7 @@ def open_socket(options):
except socket.gaierror:
fail(EC_LOGIN_DENIED)
- if "--ssl" in options:
+ if "--ssl-secure" in options or "--ssl-insecure" in options:
import ssl
sock = socket.socket()
sslcx = ssl.create_default_context()
@@ -132,7 +132,7 @@ def get_list_of_images(options, command, data_as_plug):
images = set()
if output_len > 3*INT4:
- recvflag = socket.MSG_WAITALL if "--ssl" not in options else 0
+ recvflag = socket.MSG_WAITALL if "--ssl-secure" not in options and "--ssl-insecure" not in options else 0
array_len = struct.unpack("!i", conn.recv(INT4))[0]
data = ""
@@ -182,7 +182,9 @@ def main():
options = check_input(device_opt, process_input(device_opt), other_conditions=True)
if "--disable-ssl" in options or options["--ssl"] == "0":
- del options["--ssl"]
+ for k in ["--ssl", "--ssl-secure", "--ssl-insecure"]:
+ if k in options:
+ del options[k]
if len(options.get("--plug", "")) > 8:
fail_usage("Failed: Name of image can not be longer than 8 characters")
diff --git a/lib/fencing.py.py b/lib/fencing.py.py
index 696388d55..b746ede8b 100644
--- a/lib/fencing.py.py
+++ b/lib/fencing.py.py
@@ -789,6 +789,12 @@ def check_input(device_opt, opt, other_conditions = False):
if "--password-script" in options:
options["--password"] = os.popen(options["--password-script"]).read().rstrip()
+ if "--ssl-secure" in options or "--ssl-insecure" in options:
+ options["--ssl"] = ""
+
+ if "--ssl" in options and "--ssl-insecure" not in options:
+ options["--ssl-secure"] = ""
+
if os.environ.get("PCMK_service") == "pacemaker-fenced" and "--disable-timeout" not in options:
options["--disable-timeout"] = "1"
diff --git a/tests/data/metadata/fence_docker.xml b/tests/data/metadata/fence_docker.xml
index 723e72280..51c7c470a 100644
--- a/tests/data/metadata/fence_docker.xml
+++ b/tests/data/metadata/fence_docker.xml
@@ -20,7 +20,7 @@
</parameter>
<parameter name="ipport" unique="0" required="0">
<getopt mixed="-u, --ipport=[port]" />
- <content type="integer" default="80" />
+ <content type="integer" default="443" />
<shortdesc lang="en">TCP/UDP port to use for connection with device</shortdesc>
</parameter>
<parameter name="method" unique="0" required="0">
@@ -43,7 +43,7 @@
</parameter>
<parameter name="ssl" unique="0" required="0">
<getopt mixed="-z, --ssl" />
- <content type="boolean" />
+ <content type="boolean" default="1" />
<shortdesc lang="en">Use SSL connection with verifying certificate</shortdesc>
</parameter>
<parameter name="ssl_insecure" unique="0" required="0">

View File

@ -0,0 +1,30 @@
From 6430104318b4bf349425b08636183bf839812e04 Mon Sep 17 00:00:00 2001
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
Date: Tue, 31 May 2022 08:55:25 +0200
Subject: [PATCH] fence_zvmip: show unable to connect error instead of full
stacktrace, e.g. when not using --ssl for SSL devices
---
agents/zvm/fence_zvmip.py | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/agents/zvm/fence_zvmip.py b/agents/zvm/fence_zvmip.py
index 90ca95d45..4f538e10d 100644
--- a/agents/zvm/fence_zvmip.py
+++ b/agents/zvm/fence_zvmip.py
@@ -127,8 +127,13 @@ def get_list_of_images(options, command, data_as_plug):
conn.send(packet)
- request_id = struct.unpack("!i", conn.recv(INT4))[0]
- (output_len, request_id, return_code, reason_code) = struct.unpack("!iiii", conn.recv(INT4 * 4))
+ try:
+ request_id = struct.unpack("!i", conn.recv(INT4))[0]
+ (output_len, request_id, return_code, reason_code) = struct.unpack("!iiii", conn.recv(INT4 * 4))
+ except struct.error:
+ logging.debug(sys.exc_info())
+ fail_usage("Failed: Unable to connect to {} port: {} SSL: {} \n".format(options["--ip"], options["--ipport"], bool("--ssl" in options)))
+
images = set()
if output_len > 3*INT4:

View File

@ -0,0 +1,410 @@
--- fence-agents-4.10.0/agents/gce/fence_gce.py 2022-04-29 10:13:50.317888041 +0200
+++ fence-agents-4.10.0/agents/gce/fence_gce.py2 2022-04-29 10:17:54.813248566 +0200
@@ -2,10 +2,10 @@
#
# 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 python3-oauth2client-gce
+# RHEL 7.x: google-api-python-client==1.6.7 python-gflags==2.0 pyasn1==0.4.8 rsa==3.4.2 pysocks==1.7.1 httplib2==0.19.0
+# RHEL 8.x: pysocks==1.7.1 httplib2==0.19.0
+# SLES 12.x: python-google-api-python-client python-oauth2client python-oauth2client-gce pysocks==1.7.1 httplib2==0.19.0
+# SLES 15.x: python3-google-api-python-client python3-oauth2client pysocks==1.7.1 httplib2==0.19.0
#
import atexit
@@ -27,7 +27,7 @@
import urllib2 as urlrequest
sys.path.append("@FENCEAGENTSLIBDIR@")
-from fencing import fail_usage, run_delay, all_opt, atexit_handler, check_input, process_input, show_docs, fence_action
+from fencing import fail_usage, run_delay, all_opt, atexit_handler, check_input, process_input, show_docs, fence_action, run_command
try:
sys.path.insert(0, '/usr/lib/fence-agents/support/google')
import httplib2
@@ -42,6 +42,19 @@
METADATA_SERVER = 'http://metadata.google.internal/computeMetadata/v1/'
METADATA_HEADERS = {'Metadata-Flavor': 'Google'}
+INSTANCE_LINK = 'https://www.googleapis.com/compute/v1/projects/{}/zones/{}/instances/{}'
+
+def run_on_fail(options):
+ if "--runonfail" in options:
+ run_command(options, options["--runonfail"])
+
+def fail_fence_agent(options, message):
+ run_on_fail(options)
+ fail_usage(message)
+
+def raise_fence_agent(options, message):
+ run_on_fail(options)
+ raise Exception(message)
#
# Will use baremetalsolution setting or the environment variable
@@ -66,7 +79,7 @@
{
"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/v1/projects/\\1/locations/\\2/instances/\\3:resetInstance\\4"
})
for uri_replacement in uri_replacements:
# each uri_replacement should have matchlength, match, and replace
@@ -121,14 +134,17 @@
def get_nodes_list(conn, options):
result = {}
+ if "--zone" not in options:
+ fail_fence_agent(options, "Failed: get_nodes_list: Please specify the --zone in the command")
try:
- instanceList = retry_api_execute(options, conn.instances().list(
- project=options["--project"],
- zone=options["--zone"]))
- for instance in instanceList["items"]:
- result[instance["id"]] = (instance["name"], translate_status(instance["status"]))
+ for zone in options["--zone"].split(","):
+ instanceList = retry_api_execute(options, conn.instances().list(
+ project=options["--project"],
+ zone=zone))
+ for instance in instanceList["items"]:
+ result[instance["id"]] = (instance["name"], translate_status(instance["status"]))
except Exception as err:
- fail_usage("Failed: get_nodes_list: {}".format(str(err)))
+ fail_fence_agent(options, "Failed: get_nodes_list: {}".format(str(err)))
return result
@@ -142,23 +158,54 @@
return "off"
else:
return "on"
+ # If zone is not listed for an entry we attempt to get it automatically
+ instance = options["--plug"]
+ zone = get_zone(conn, options, instance) if "--plugzonemap" not in options else options["--plugzonemap"][instance]
+ instance_status = get_instance_power_status(conn, options, instance, zone)
+ # If any of the instances do not match the intended status we return the
+ # the opposite status so that the fence agent can change it.
+ if instance_status != options.get("--action"):
+ return instance_status
+
+ return options.get("--action")
+
+
+def get_instance_power_status(conn, options, instance, zone):
try:
- instance = retry_api_execute(options, conn.instances().get(
- project=options["--project"],
- zone=options["--zone"],
- instance=options["--plug"]))
+ instance = retry_api_execute(
+ options,
+ conn.instances().get(project=options["--project"], zone=zone, instance=instance))
return translate_status(instance["status"])
except Exception as err:
- fail_usage("Failed: get_power_status: {}".format(str(err)))
+ fail_fence_agent(options, "Failed: get_instance_power_status: {}".format(str(err)))
-def wait_for_operation(conn, options, operation):
+def check_for_existing_operation(conn, options, instance, zone, operation_type):
+ logging.debug("check_for_existing_operation")
+ if "--baremetalsolution" in options:
+ # There is no API for checking in progress operations
+ return False
+
+ project = options["--project"]
+ target_link = INSTANCE_LINK.format(project, zone, instance)
+ query_filter = '(targetLink = "{}") AND (operationType = "{}") AND (status = "RUNNING")'.format(target_link, operation_type)
+ result = retry_api_execute(
+ options,
+ conn.zoneOperations().list(project=project, zone=zone, filter=query_filter, maxResults=1))
+
+ if "items" in result and result["items"]:
+ logging.info("Existing %s operation found", operation_type)
+ return result["items"][0]
+
+
+def wait_for_operation(conn, options, zone, operation):
if 'name' not in operation:
logging.warning('Cannot wait for operation to complete, the'
' requested operation will continue asynchronously')
- return
+ return False
+
+ wait_time = 0
project = options["--project"]
- zone = options["--zone"]
while True:
result = retry_api_execute(options, conn.zoneOperations().get(
project=project,
@@ -166,56 +213,93 @@
operation=operation['name']))
if result['status'] == 'DONE':
if 'error' in result:
- raise Exception(result['error'])
- return
+ raise_fence_agent(options, result['error'])
+ return True
+
+ if "--errortimeout" in options and wait_time > int(options["--errortimeout"]):
+ raise_fence_agent(options, "Operation did not complete before the timeout.")
+
+ if "--warntimeout" in options and wait_time > int(options["--warntimeout"]):
+ logging.warning("Operation did not complete before the timeout.")
+ if "--runonwarn" in options:
+ run_command(options, options["--runonwarn"])
+ return False
+
+ wait_time = wait_time + 1
time.sleep(1)
def set_power_status(conn, options):
- logging.debug("set_power_status");
+ logging.debug("set_power_status")
+ instance = options["--plug"]
+ # If zone is not listed for an entry we attempt to get it automatically
+ zone = get_zone(conn, options, instance) if "--plugzonemap" not in options else options["--plugzonemap"][instance]
+ set_instance_power_status(conn, options, instance, zone, options["--action"])
+
+
+def set_instance_power_status(conn, options, instance, zone, action):
+ logging.info("Setting power status of %s in zone %s", instance, zone)
+ project = options["--project"]
+
try:
- if options["--action"] == "off":
- logging.info("Issuing poweroff of %s in zone %s" % (options["--plug"], options["--zone"]))
- operation = retry_api_execute(options, conn.instances().stop(
- project=options["--project"],
- zone=options["--zone"],
- instance=options["--plug"]))
+ if action == "off":
+ logging.info("Issuing poweroff of %s in zone %s", instance, zone)
+ operation = check_for_existing_operation(conn, options, instance, zone, "stop")
+ if operation and "--earlyexit" in options:
+ return
+ if not operation:
+ operation = retry_api_execute(
+ options,
+ conn.instances().stop(project=project, zone=zone, instance=instance))
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":
- logging.info("Issuing poweron of %s in zone %s" % (options["--plug"], options["--zone"]))
- operation = retry_api_execute(options, conn.instances().start(
- project=options["--project"],
- zone=options["--zone"],
- instance=options["--plug"]))
- wait_for_operation(conn, options, operation)
- logging.info("Poweron of %s in zone %s complete" % (options["--plug"], options["--zone"]))
+ if wait_for_operation(conn, options, zone, operation):
+ logging.info("Poweroff of %s in zone %s complete", instance, zone)
+ elif action == "on":
+ logging.info("Issuing poweron of %s in zone %s", instance, zone)
+ operation = check_for_existing_operation(conn, options, instance, zone, "start")
+ if operation and "--earlyexit" in options:
+ return
+ if not operation:
+ operation = retry_api_execute(
+ options,
+ conn.instances().start(project=project, zone=zone, instance=instance))
+ if wait_for_operation(conn, options, zone, operation):
+ logging.info("Poweron of %s in zone %s complete", instance, zone)
except Exception as err:
- fail_usage("Failed: set_power_status: {}".format(str(err)))
-
+ fail_fence_agent(options, "Failed: set_instance_power_status: {}".format(str(err)))
def power_cycle(conn, options):
- logging.debug("power_cycle");
+ logging.debug("power_cycle")
+ instance = options["--plug"]
+ # If zone is not listed for an entry we attempt to get it automatically
+ zone = get_zone(conn, options, instance) if "--plugzonemap" not in options else options["--plugzonemap"][instance]
+ return power_cycle_instance(conn, options, instance, zone)
+
+
+def power_cycle_instance(conn, options, instance, zone):
+ logging.info("Issuing reset of %s in zone %s", instance, zone)
+ project = options["--project"]
+
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"]))
+ operation = check_for_existing_operation(conn, options, instance, zone, "reset")
+ if operation and "--earlyexit" in options:
+ return True
+ if not operation:
+ operation = retry_api_execute(
+ options,
+ conn.instances().reset(project=project, zone=zone, instance=instance))
+ logging.info("Reset command sent, waiting for the operation to complete")
+ if wait_for_operation(conn, options, zone, operation):
+ logging.info("Reset of %s in zone %s complete", instance, zone)
return True
except Exception as err:
- logging.error("Failed: power_cycle: {}".format(str(err)))
- return False
+ logging.exception("Failed: power_cycle")
+ raise err
-def get_zone(conn, options):
+def get_zone(conn, options, instance):
logging.debug("get_zone");
project = options['--project']
- instance = options['--plug']
fl = 'name="%s"' % instance
request = replace_api_uri(options, conn.instances().aggregatedList(project=project, filter=fl))
while request is not None:
@@ -227,7 +311,7 @@
return inst['zone'].split("/")[-1]
request = replace_api_uri(options, conn.instances().aggregatedList_next(
previous_request=request, previous_response=response))
- raise Exception("Unable to find instance %s" % (instance))
+ raise_fence_agent(options, "Unable to find instance %s" % (instance))
def get_metadata(metadata_key, params=None, timeout=None):
@@ -326,13 +410,21 @@
"required" : "0",
"order" : 9
}
+ all_opt["plugzonemap"] = {
+ "getopt" : ":",
+ "longopt" : "plugzonemap",
+ "help" : "--plugzonemap=[plugzonemap] Comma separated zone map when fencing multiple plugs",
+ "shortdesc" : "Comma separated zone map when fencing multiple plugs.",
+ "required" : "0",
+ "order" : 10
+ }
all_opt["proxyhost"] = {
"getopt" : ":",
"longopt" : "proxyhost",
"help" : "--proxyhost=[proxy_host] The proxy host to use, if one is needed to access the internet (Example: 10.122.0.33)",
"shortdesc" : "If a proxy is used for internet access, the proxy host should be specified.",
"required" : "0",
- "order" : 10
+ "order" : 11
}
all_opt["proxyport"] = {
"getopt" : ":",
@@ -341,7 +433,49 @@
"help" : "--proxyport=[proxy_port] The proxy port to use, if one is needed to access the internet (Example: 3127)",
"shortdesc" : "If a proxy is used for internet access, the proxy port should be specified.",
"required" : "0",
- "order" : 11
+ "order" : 12
+ }
+ all_opt["earlyexit"] = {
+ "getopt" : "",
+ "longopt" : "earlyexit",
+ "help" : "--earlyexit Return early if reset is already in progress",
+ "shortdesc" : "If an existing reset operation is detected, the fence agent will return before the operation completes with a 0 return code.",
+ "required" : "0",
+ "order" : 13
+ }
+ all_opt["warntimeout"] = {
+ "getopt" : ":",
+ "type" : "second",
+ "longopt" : "warntimeout",
+ "help" : "--warntimeout=[warn_timeout] Timeout seconds before logging a warning and returning a 0 status code",
+ "shortdesc" : "If the operation is not completed within the timeout, the cluster operations are allowed to continue.",
+ "required" : "0",
+ "order" : 14
+ }
+ all_opt["errortimeout"] = {
+ "getopt" : ":",
+ "type" : "second",
+ "longopt" : "errortimeout",
+ "help" : "--errortimeout=[error_timeout] Timeout seconds before failing and returning a non-zero status code",
+ "shortdesc" : "If the operation is not completed within the timeout, cluster is notified of the operation failure.",
+ "required" : "0",
+ "order" : 15
+ }
+ all_opt["runonwarn"] = {
+ "getopt" : ":",
+ "longopt" : "runonwarn",
+ "help" : "--runonwarn=[run_on_warn] If a timeout occurs and warning is generated, run the supplied command",
+ "shortdesc" : "If a timeout would occur while running the agent, then the supplied command is run.",
+ "required" : "0",
+ "order" : 16
+ }
+ all_opt["runonfail"] = {
+ "getopt" : ":",
+ "longopt" : "runonfail",
+ "help" : "--runonfail=[run_on_fail] If a failure occurs, run the supplied command",
+ "shortdesc" : "If a failure would occur while running the agent, then the supplied command is run.",
+ "required" : "0",
+ "order" : 17
}
@@ -350,7 +484,8 @@
device_opt = ["port", "no_password", "zone", "project", "stackdriver-logging",
"method", "baremetalsolution", "apitimeout", "retries", "retrysleep",
- "serviceaccount", "proxyhost", "proxyport"]
+ "serviceaccount", "plugzonemap", "proxyhost", "proxyport", "earlyexit",
+ "warntimeout", "errortimeout", "runonwarn", "runonfail"]
atexit.register(atexit_handler)
@@ -431,22 +566,39 @@
conn = googleapiclient.discovery.build(
'compute', 'v1', credentials=credentials, cache_discovery=False)
except Exception as err:
- fail_usage("Failed: Create GCE compute v1 connection: {}".format(str(err)))
+ fail_fence_agent(options, "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)))
+ fail_fence_agent(options, "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)
- except Exception as err:
- fail_usage("Failed retrieving GCE zone. Please provide --zone option: {}".format(str(err)))
+
+ # Populates zone automatically if missing from the command
+ zones = [] if not "--zone" in options else options["--zone"].split(",")
+ options["--plugzonemap"] = {}
+ if "--plug" in options:
+ for i, instance in enumerate(options["--plug"].split(",")):
+ if len(zones) == 1:
+ # If only one zone is specified, use it across all plugs
+ options["--plugzonemap"][instance] = zones[0]
+ continue
+
+ if len(zones) - 1 >= i:
+ # If we have enough zones specified with the --zone flag use the zone at
+ # the same index as the plug
+ options["--plugzonemap"][instance] = zones[i]
+ continue
+
+ try:
+ # In this case we do not have a zone specified so we attempt to detect it
+ options["--plugzonemap"][instance] = get_zone(conn, options, instance)
+ except Exception as err:
+ fail_fence_agent(options, "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, power_cycle)

View File

@ -0,0 +1,65 @@
From d0254345472c9415af1e06e9e8df2fe0ce464db0 Mon Sep 17 00:00:00 2001
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
Date: Mon, 2 May 2022 11:14:42 +0200
Subject: [PATCH] fence_ibm_vpc: remove unused instance parameter and make
limit optional
---
agents/ibm_vpc/fence_ibm_vpc.py | 11 +----------
tests/data/metadata/fence_ibm_vpc.xml | 7 +------
2 files changed, 2 insertions(+), 16 deletions(-)
diff --git a/agents/ibm_vpc/fence_ibm_vpc.py b/agents/ibm_vpc/fence_ibm_vpc.py
index 9f84f7b2d..9e38e8301 100755
--- a/agents/ibm_vpc/fence_ibm_vpc.py
+++ b/agents/ibm_vpc/fence_ibm_vpc.py
@@ -161,14 +161,6 @@ def define_new_opts():
"shortdesc" : "API Key",
"order" : 0
}
- all_opt["instance"] = {
- "getopt" : ":",
- "longopt" : "instance",
- "help" : "--instance=[instance] Cloud Instance",
- "required" : "1",
- "shortdesc" : "Cloud Instance",
- "order" : 0
- }
all_opt["region"] = {
"getopt" : ":",
"longopt" : "region",
@@ -181,7 +173,7 @@ def define_new_opts():
"getopt" : ":",
"longopt" : "limit",
"help" : "--limit=[number] Limit number of nodes returned by API",
- "required" : "1",
+ "required" : "0",
"default": 50,
"shortdesc" : "Number of nodes returned by API",
"order" : 0
@@ -191,7 +183,6 @@ def define_new_opts():
def main():
device_opt = [
"apikey",
- "instance",
"region",
"limit",
"port",
diff --git a/tests/data/metadata/fence_ibm_vpc.xml b/tests/data/metadata/fence_ibm_vpc.xml
index 926efcaa0..ee7151673 100644
--- a/tests/data/metadata/fence_ibm_vpc.xml
+++ b/tests/data/metadata/fence_ibm_vpc.xml
@@ -8,12 +8,7 @@
<content type="string" />
<shortdesc lang="en">API Key</shortdesc>
</parameter>
- <parameter name="instance" unique="0" required="1">
- <getopt mixed="--instance=[instance]" />
- <content type="string" />
- <shortdesc lang="en">Cloud Instance</shortdesc>
- </parameter>
- <parameter name="limit" unique="0" required="1">
+ <parameter name="limit" unique="0" required="0">
<getopt mixed="--limit=[number]" />
<content type="string" default="50" />
<shortdesc lang="en">Number of nodes returned by API</shortdesc>

View File

@ -0,0 +1,62 @@
From be409554bbc99df2bba22cb01e8a6df634af896d Mon Sep 17 00:00:00 2001
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
Date: Tue, 31 May 2022 15:46:40 +0200
Subject: [PATCH] fence_ibm_vpc: add proxy support
---
agents/ibm_vpc/fence_ibm_vpc.py | 11 +++++++++++
tests/data/metadata/fence_ibm_vpc.xml | 5 +++++
2 files changed, 16 insertions(+)
diff --git a/agents/ibm_vpc/fence_ibm_vpc.py b/agents/ibm_vpc/fence_ibm_vpc.py
index 9e38e8301..3da3ce056 100755
--- a/agents/ibm_vpc/fence_ibm_vpc.py
+++ b/agents/ibm_vpc/fence_ibm_vpc.py
@@ -88,6 +88,7 @@ def connect(opt):
conn.setopt(pycurl.TIMEOUT, int(opt["--shell-timeout"]))
conn.setopt(pycurl.SSL_VERIFYPEER, 1)
conn.setopt(pycurl.SSL_VERIFYHOST, 2)
+ conn.setopt(pycurl.PROXY, "{}".format(opt["--proxy"]))
# get bearer token
bearer_token = get_bearer_token(conn, opt)
@@ -169,6 +170,15 @@ def define_new_opts():
"shortdesc" : "Region",
"order" : 0
}
+ all_opt["proxy"] = {
+ "getopt" : ":",
+ "longopt" : "proxy",
+ "help" : "--proxy=[http://<URL>:<PORT>] Proxy: 'http://<URL>:<PORT>'",
+ "required" : "0",
+ "default": "",
+ "shortdesc" : "Network proxy",
+ "order" : 0
+ }
all_opt["limit"] = {
"getopt" : ":",
"longopt" : "limit",
@@ -185,6 +195,7 @@ def main():
"apikey",
"region",
"limit",
+ "proxy",
"port",
"no_password",
]
diff --git a/tests/data/metadata/fence_ibm_vpc.xml b/tests/data/metadata/fence_ibm_vpc.xml
index ee7151673..09da0e303 100644
--- a/tests/data/metadata/fence_ibm_vpc.xml
+++ b/tests/data/metadata/fence_ibm_vpc.xml
@@ -13,6 +13,11 @@
<content type="string" default="50" />
<shortdesc lang="en">Number of nodes returned by API</shortdesc>
</parameter>
+ <parameter name="proxy" unique="0" required="0">
+ <getopt mixed="--proxy=[http://&lt;URL&gt;:&lt;PORT&gt;]" />
+ <content type="string" default="" />
+ <shortdesc lang="en">Network proxy</shortdesc>
+ </parameter>
<parameter name="region" unique="0" required="1">
<getopt mixed="--region=[region]" />
<content type="string" />

View File

@ -0,0 +1,455 @@
From 98fec5c6d55369ad681abc0cde0d8677835957ab Mon Sep 17 00:00:00 2001
From: Arnold Beilmann <arnoldbeilmann@macbook-pro.speedport.ip>
Date: Thu, 5 May 2022 15:26:22 +0200
Subject: [PATCH 1/2] modified for PowerVS
---
agents/ibm_powervs/fence_ibm_powervs.py | 108 +++++++++++++++++++-----
1 file changed, 89 insertions(+), 19 deletions(-)
diff --git a/agents/ibm_powervs/fence_ibm_powervs.py b/agents/ibm_powervs/fence_ibm_powervs.py
index 6649771ea..727009220 100755
--- a/agents/ibm_powervs/fence_ibm_powervs.py
+++ b/agents/ibm_powervs/fence_ibm_powervs.py
@@ -1,10 +1,11 @@
-#!@PYTHON@ -tt
+#!/usr/libexec/platform-python -tt
import sys
import pycurl, io, json
import logging
import atexit
-sys.path.append("@FENCEAGENTSLIBDIR@")
+import time
+sys.path.append("/usr/share/fence")
from fencing import *
from fencing import fail, run_delay, EC_LOGIN_DENIED, EC_STATUS
@@ -14,16 +15,30 @@
"ERROR": "unknown"
}
+def get_token(conn, options):
+
+ try:
+ command = "identity/token"
+ action = "grant_type=urn%3Aibm%3Aparams%3Aoauth%3Agrant-type%3Aapikey&apikey={}".format(options["--token"])
+ res = send_command(conn, command, "POST", action, printResult=False)
+ except Exception as e:
+ logging.debug("Failed: {}".format(e))
+ return "TOKEN_IS_MISSING_OR_WRONG"
+
+ #if "--verbose" in options:
+ # logging.debug(json.dumps(res, indent=2))
+
+ return res["access_token"]
+
def get_list(conn, options):
outlets = {}
-
+
try:
command = "cloud-instances/{}/pvm-instances".format(options["--instance"])
res = send_command(conn, command)
except Exception as e:
logging.debug("Failed: {}".format(e))
return outlets
-
for r in res["pvmInstances"]:
if "--verbose" in options:
logging.debug(json.dumps(r, indent=2))
@@ -32,6 +47,7 @@ def get_list(conn, options):
return outlets
def get_power_status(conn, options):
+
try:
command = "cloud-instances/{}/pvm-instances/{}".format(
options["--instance"], options["--plug"])
@@ -40,10 +56,11 @@ def get_power_status(conn, options):
except KeyError as e:
logging.debug("Failed: Unable to get status for {}".format(e))
fail(EC_STATUS)
-
+
return result
def set_power_status(conn, options):
+
action = {
"on" : '{"action" : "start"}',
"off" : '{"action" : "immediate-shutdown"}',
@@ -56,35 +73,63 @@ def set_power_status(conn, options):
logging.debug("Failed: Unable to set power to {} for {}".format(options["--action"], e))
fail(EC_STATUS)
-def connect(opt):
+def connect(opt, token):
conn = pycurl.Curl()
## setup correct URL
- conn.base_url = "https://" + opt["--region"] + ".power-iaas.cloud.ibm.com/pcloud/v1/"
+ conn.base_url = "https://private." + opt["--region"] + ".power-iaas.cloud.ibm.com/pcloud/v1/"
+ if opt["--api-type"] == "public":
+ conn.base_url = "https://" + opt["--region"] + ".power-iaas.cloud.ibm.com/pcloud/v1/"
if opt["--verbose-level"] > 1:
- conn.setopt(pycurl.VERBOSE, 1)
+ conn.setopt(pycurl.VERBOSE, 0)
+ conn.setopt(pycurl.CONNECTTIMEOUT,int(opt["--shell-timeout"]))
conn.setopt(pycurl.TIMEOUT, int(opt["--shell-timeout"]))
conn.setopt(pycurl.SSL_VERIFYPEER, 1)
conn.setopt(pycurl.SSL_VERIFYHOST, 2)
+ conn.setopt(pycurl.PROXY, "{}".format(opt["--proxy"]))
# set auth token for later requests
conn.setopt(pycurl.HTTPHEADER, [
"Content-Type: application/json",
- "Authorization: Bearer {}".format(opt["--token"]),
+ "Authorization: Bearer {}".format(token),
"CRN: {}".format(opt["--crn"]),
"User-Agent: curl",
])
+
+ return conn
+
+def auth_connect(opt):
+ conn = pycurl.Curl()
+
+ # setup correct URL
+ conn.base_url = "https://iam.cloud.ibm.com/"
+
+ if opt["--verbose-level"] > 1:
+ conn.setopt(pycurl.VERBOSE, 1)
+
+ conn.setopt(pycurl.CONNECTTIMEOUT,int(opt["--shell-timeout"]))
+ conn.setopt(pycurl.TIMEOUT, int(opt["--shell-timeout"]))
+ conn.setopt(pycurl.SSL_VERIFYPEER, 1)
+ conn.setopt(pycurl.SSL_VERIFYHOST, 2)
+ conn.setopt(pycurl.PROXY, "{}".format(opt["--proxy"]))
+
+ # set auth token for later requests
+ conn.setopt(pycurl.HTTPHEADER, [
+ "Content-type: application/x-www-form-urlencoded",
+ "Accept: application/json",
+ "User-Agent: curl",
+ ])
return conn
def disconnect(conn):
conn.close()
-def send_command(conn, command, method="GET", action=None):
+def send_command(conn, command, method="GET", action=None, printResult=True):
url = conn.base_url + command
-
+
conn.setopt(pycurl.URL, url.encode("ascii"))
web_buffer = io.BytesIO()
@@ -99,8 +144,10 @@ def send_command(conn, command, method="GET", action=None):
conn.setopt(pycurl.WRITEFUNCTION, web_buffer.write)
try:
+ time.sleep(3)
conn.perform()
except Exception as e:
+ logging.error("ADD_DEBUG: {}".format(e))
raise(e)
rc = conn.getinfo(pycurl.HTTP_CODE)
@@ -110,8 +157,7 @@ def send_command(conn, command, method="GET", action=None):
if rc != 200:
if len(result) > 0:
- raise Exception("{}: {}".format(rc,
- result["value"]["messages"][0]["default_message"]))
+ raise Exception("{}: {}".format(rc,result))
else:
raise Exception("Remote returned {} for request to {}".format(rc, url))
@@ -121,7 +167,8 @@ def send_command(conn, command, method="GET", action=None):
logging.debug("url: {}".format(url))
logging.debug("method: {}".format(method))
logging.debug("response code: {}".format(rc))
- logging.debug("result: {}\n".format(result))
+ if printResult:
+ logging.debug("result: {}\n".format(result))
return result
@@ -129,9 +176,9 @@ def define_new_opts():
all_opt["token"] = {
"getopt" : ":",
"longopt" : "token",
- "help" : "--token=[token] Bearer Token",
+ "help" : "--token=[token] API Token",
"required" : "1",
- "shortdesc" : "Bearer Token",
+ "shortdesc" : "API Token",
"order" : 0
}
all_opt["crn"] = {
@@ -158,6 +205,22 @@ def define_new_opts():
"shortdesc" : "Region",
"order" : 0
}
+ all_opt["api-type"] = {
+ "getopt" : ":",
+ "longopt" : "api-type",
+ "help" : "--api-type=[private|public] API-type: 'private' (default) or 'public'",
+ "required" : "0",
+ "shortdesc" : "API-type (private|public)",
+ "order" : 0
+ }
+ all_opt["proxy"] = {
+ "getopt" : ":",
+ "longopt" : "proxy",
+ "help" : "--proxy=[http://<URL>:<PORT>] Proxy: 'http://<URL>:<PORT>'",
+ "required" : "0",
+ "shortdesc" : "Network proxy",
+ "order" : 0
+ }
def main():
@@ -166,6 +229,8 @@ def main():
"crn",
"instance",
"region",
+ "api-type",
+ "proxy",
"port",
"no_password",
]
@@ -173,9 +238,11 @@ def main():
atexit.register(atexit_handler)
define_new_opts()
- all_opt["shell_timeout"]["default"] = "15"
+ all_opt["shell_timeout"]["default"] = "500"
all_opt["power_timeout"]["default"] = "30"
all_opt["power_wait"]["default"] = "1"
+ all_opt["api-type"]["default"] = "private"
+ all_opt["proxy"]["default"] = ""
options = check_input(device_opt, process_input(device_opt))
@@ -190,8 +257,11 @@ def main():
## Fence operations
####
run_delay(options)
-
- conn = connect(options)
+
+ auth_conn = auth_connect(options)
+ token = get_token(auth_conn, options)
+ disconnect(auth_conn)
+ conn = connect(options, token)
atexit.register(disconnect, conn)
result = fence_action(conn, options, set_power_status, get_power_status, get_list)
From fbe9a539ac8f40686a8027b7e768d9f7b799e485 Mon Sep 17 00:00:00 2001
From: Oyvind Albrigtsen <oalbrigt@redhat.com>
Date: Fri, 6 May 2022 11:22:47 +0200
Subject: [PATCH 2/2] fence_ibm_powervs: cleanup and fixes
---
agents/ibm_powervs/fence_ibm_powervs.py | 37 ++++++++++-------------
tests/data/metadata/fence_ibm_powervs.xml | 19 ++++++++++--
2 files changed, 33 insertions(+), 23 deletions(-)
diff --git a/agents/ibm_powervs/fence_ibm_powervs.py b/agents/ibm_powervs/fence_ibm_powervs.py
index 727009220..819ab8896 100755
--- a/agents/ibm_powervs/fence_ibm_powervs.py
+++ b/agents/ibm_powervs/fence_ibm_powervs.py
@@ -1,11 +1,11 @@
-#!/usr/libexec/platform-python -tt
+#!@PYTHON@ -tt
import sys
import pycurl, io, json
import logging
import atexit
import time
-sys.path.append("/usr/share/fence")
+sys.path.append("@FENCEAGENTSLIBDIR@")
from fencing import *
from fencing import fail, run_delay, EC_LOGIN_DENIED, EC_STATUS
@@ -16,7 +16,6 @@
}
def get_token(conn, options):
-
try:
command = "identity/token"
action = "grant_type=urn%3Aibm%3Aparams%3Aoauth%3Agrant-type%3Aapikey&apikey={}".format(options["--token"])
@@ -25,20 +24,18 @@ def get_token(conn, options):
logging.debug("Failed: {}".format(e))
return "TOKEN_IS_MISSING_OR_WRONG"
- #if "--verbose" in options:
- # logging.debug(json.dumps(res, indent=2))
-
return res["access_token"]
def get_list(conn, options):
outlets = {}
-
+
try:
command = "cloud-instances/{}/pvm-instances".format(options["--instance"])
res = send_command(conn, command)
except Exception as e:
logging.debug("Failed: {}".format(e))
return outlets
+
for r in res["pvmInstances"]:
if "--verbose" in options:
logging.debug(json.dumps(r, indent=2))
@@ -47,7 +44,6 @@ def get_list(conn, options):
return outlets
def get_power_status(conn, options):
-
try:
command = "cloud-instances/{}/pvm-instances/{}".format(
options["--instance"], options["--plug"])
@@ -56,11 +52,10 @@ def get_power_status(conn, options):
except KeyError as e:
logging.debug("Failed: Unable to get status for {}".format(e))
fail(EC_STATUS)
-
+
return result
def set_power_status(conn, options):
-
action = {
"on" : '{"action" : "start"}',
"off" : '{"action" : "immediate-shutdown"}',
@@ -77,11 +72,11 @@ def connect(opt, token):
conn = pycurl.Curl()
## setup correct URL
- conn.base_url = "https://private." + opt["--region"] + ".power-iaas.cloud.ibm.com/pcloud/v1/"
- if opt["--api-type"] == "public":
- conn.base_url = "https://" + opt["--region"] + ".power-iaas.cloud.ibm.com/pcloud/v1/"
+ conn.base_url = "https://" + opt["--region"] + ".power-iaas.cloud.ibm.com/pcloud/v1/"
+ if opt["--api-type"] == "private":
+ conn.base_url = "https://private." + opt["--region"] + ".power-iaas.cloud.ibm.com/pcloud/v1/"
- if opt["--verbose-level"] > 1:
+ if opt["--verbose-level"] < 3:
conn.setopt(pycurl.VERBOSE, 0)
conn.setopt(pycurl.CONNECTTIMEOUT,int(opt["--shell-timeout"]))
@@ -129,7 +124,7 @@ def disconnect(conn):
def send_command(conn, command, method="GET", action=None, printResult=True):
url = conn.base_url + command
-
+
conn.setopt(pycurl.URL, url.encode("ascii"))
web_buffer = io.BytesIO()
@@ -144,10 +139,9 @@ def send_command(conn, command, method="GET", action=None, printResult=True):
conn.setopt(pycurl.WRITEFUNCTION, web_buffer.write)
try:
- time.sleep(3)
conn.perform()
except Exception as e:
- logging.error("ADD_DEBUG: {}".format(e))
+ logging.error("send_command(): {}".format(e))
raise(e)
rc = conn.getinfo(pycurl.HTTP_CODE)
@@ -208,9 +202,9 @@ def define_new_opts():
all_opt["api-type"] = {
"getopt" : ":",
"longopt" : "api-type",
- "help" : "--api-type=[private|public] API-type: 'private' (default) or 'public'",
+ "help" : "--api-type=[public|private] API-type: 'public' (default) or 'private'",
"required" : "0",
- "shortdesc" : "API-type (private|public)",
+ "shortdesc" : "API-type (public|private)",
"order" : 0
}
all_opt["proxy"] = {
@@ -238,9 +232,10 @@ def main():
atexit.register(atexit_handler)
define_new_opts()
- all_opt["shell_timeout"]["default"] = "500"
+ all_opt["shell_timeout"]["default"] = "15"
all_opt["power_timeout"]["default"] = "30"
all_opt["power_wait"]["default"] = "1"
+ all_opt["stonith_status_sleep"]["default"] = "3"
all_opt["api-type"]["default"] = "private"
all_opt["proxy"]["default"] = ""
@@ -257,7 +252,7 @@ def main():
## Fence operations
####
run_delay(options)
-
+
auth_conn = auth_connect(options)
token = get_token(auth_conn, options)
disconnect(auth_conn)
diff --git a/tests/data/metadata/fence_ibm_powervs.xml b/tests/data/metadata/fence_ibm_powervs.xml
index fe86331bd..81cea4379 100644
--- a/tests/data/metadata/fence_ibm_powervs.xml
+++ b/tests/data/metadata/fence_ibm_powervs.xml
@@ -3,6 +3,16 @@
<longdesc>fence_ibm_powervs is an I/O Fencing agent which can be used with IBM PowerVS to fence virtual machines.</longdesc>
<vendor-url>https://www.ibm.com</vendor-url>
<parameters>
+ <parameter name="api-type" unique="0" required="0" deprecated="1">
+ <getopt mixed="--api-type=[public|private]" />
+ <content type="string" default="private" />
+ <shortdesc lang="en">API-type (public|private)</shortdesc>
+ </parameter>
+ <parameter name="api_type" unique="0" required="0" obsoletes="api-type">
+ <getopt mixed="--api-type=[public|private]" />
+ <content type="string" default="private" />
+ <shortdesc lang="en">API-type (public|private)</shortdesc>
+ </parameter>
<parameter name="crn" unique="0" required="1">
<getopt mixed="--crn=[crn]" />
<content type="string" />
@@ -13,6 +23,11 @@
<content type="string" />
<shortdesc lang="en">PowerVS Instance</shortdesc>
</parameter>
+ <parameter name="proxy" unique="0" required="0">
+ <getopt mixed="--proxy=[http://&lt;URL&gt;:&lt;PORT&gt;]" />
+ <content type="string" default="" />
+ <shortdesc lang="en">Network proxy</shortdesc>
+ </parameter>
<parameter name="region" unique="0" required="1">
<getopt mixed="--region=[region]" />
<content type="string" />
@@ -21,7 +36,7 @@
<parameter name="token" unique="0" required="1">
<getopt mixed="--token=[token]" />
<content type="string" />
- <shortdesc lang="en">Bearer Token</shortdesc>
+ <shortdesc lang="en">API Token</shortdesc>
</parameter>
<parameter name="action" unique="0" required="1">
<getopt mixed="-o, --action=[action]" />
@@ -110,7 +125,7 @@
</parameter>
<parameter name="stonith_status_sleep" unique="0" required="0">
<getopt mixed="--stonith-status-sleep=[seconds]" />
- <content type="second" default="1" />
+ <content type="second" default="3" />
<shortdesc lang="en">Sleep X seconds between status calls during a STONITH action</shortdesc>
</parameter>
<parameter name="retry_on" unique="0" required="0">

View File

@ -1,30 +0,0 @@
--- a/agents/compute/fence_compute.py 2021-03-04 15:11:13.867362945 +0100
+++ b/agents/compute/fence_compute.py 2021-03-04 15:11:11.480357409 +0100
@@ -253,6 +253,7 @@
nova = None
try:
+ sys.path.insert(0, '/usr/lib/fence-agents/support/openstack')
from novaclient import client
from novaclient.exceptions import NotAcceptable
except ImportError:
--- a/agents/evacuate/fence_evacuate.py 2021-03-04 15:11:48.267442726 +0100
+++ b/agents/evacuate/fence_evacuate.py 2021-03-04 15:11:45.397436069 +0100
@@ -189,6 +189,7 @@
nova = None
try:
+ sys.path.insert(0, '/usr/lib/fence-agents/support/openstack')
from novaclient import client
from novaclient.exceptions import NotAcceptable
except ImportError:
--- a/agents/openstack/fence_openstack.py 2021-06-03 11:48:01.000000000 +0200
+++ b/agents/openstack/fence_openstack.py 2021-06-30 09:13:16.598937530 +0200
@@ -11,6 +11,7 @@
from fencing import fail_usage, run_delay
try:
+ sys.path.insert(0, '/usr/lib/fence-agents/support/openstack')
from novaclient import client
from novaclient.exceptions import Conflict, NotFound
except ImportError:

View File

@ -1,3 +0,0 @@
python-novaclient
python-keystoneclient
PyYAML==5.1

View File

@ -28,7 +28,7 @@
%global dateutil dateutil
%global dateutil_version 2.8.2
%global pyyaml PyYAML
%global pyyaml_version 6.0
%global pyyaml_version 5.1
%global six six
%global six_version 1.16.0
%global urllib3 urllib3
@ -59,7 +59,7 @@
Name: fence-agents
Summary: Set of unified programs capable of host isolation ("fencing")
Version: 4.10.0
Release: 20%{?alphatag:.%{alphatag}}%{?dist}.2
Release: 30%{?alphatag:.%{alphatag}}%{?dist}
License: GPLv2+ and LGPLv2+
URL: https://github.com/ClusterLabs/fence-agents
Source0: https://fedorahosted.org/releases/f/e/fence-agents/%{name}-%{version}.tar.gz
@ -68,8 +68,7 @@ Source100: requirements-aliyun.txt
Source101: requirements-aws.txt
Source102: requirements-azure.txt
Source103: requirements-google.txt
Source104: requirements-openstack.txt
Source105: requirements-common.txt
Source104: requirements-common.txt
### HA support libs/utils ###
# awscli 2+ is only available from github (and needs to be renamed from aws-cli... to awscli)
Source900: awscli-2.2.15.tar.gz
@ -145,81 +144,56 @@ Source1059: pytz-2021.1-py2.py3-none-any.whl
Source1060: rsa-4.7.2-py3-none-any.whl
Source1061: setuptools-57.0.0-py3-none-any.whl
Source1062: uritemplate-3.0.1-py2.py3-none-any.whl
# openstack
Source1063: PyYAML-5.1.tar.gz
Source1064: charset_normalizer-2.0.4-py3-none-any.whl
Source1065: debtcollector-2.2.0-py3-none-any.whl
Source1066: idna-3.2-py3-none-any.whl
Source1067: iso8601-0.1.16-py2.py3-none-any.whl
Source1068: keystoneauth1-4.3.1-py3-none-any.whl
Source1069: msgpack-1.0.2.tar.gz
Source1070: netaddr-0.8.0-py2.py3-none-any.whl
Source1071: netifaces-0.11.0.tar.gz
Source1072: oslo.config-8.7.1-py3-none-any.whl
Source1073: oslo.i18n-5.0.1-py3-none-any.whl
Source1074: oslo.serialization-4.2.0-py3-none-any.whl
Source1075: oslo.utils-4.10.0-py3-none-any.whl
Source1076: os_service_types-1.7.0-py2.py3-none-any.whl
Source1077: pbr-5.6.0-py2.py3-none-any.whl
Source1078: packaging-21.0-py3-none-any.whl
Source1079: prettytable-2.2.0-py3-none-any.whl
Source1080: python_keystoneclient-4.2.0-py3-none-any.whl
Source1081: python_novaclient-17.5.0-py3-none-any.whl
Source1082: requests-2.26.0-py2.py3-none-any.whl
Source1083: rfc3986-1.5.0-py2.py3-none-any.whl
Source1084: stevedore-3.4.0-py3-none-any.whl
Source1085: wcwidth-0.2.5-py2.py3-none-any.whl
Source1086: wheel-0.37.0-py2.py3-none-any.whl
Source1087: wrapt-1.12.1.tar.gz
# common (pexpect / suds)
Source1088: pexpect-4.8.0-py2.py3-none-any.whl
Source1089: ptyprocess-0.7.0-py2.py3-none-any.whl
Source1090: suds_community-0.8.5-py3-none-any.whl
Source1063: pexpect-4.8.0-py2.py3-none-any.whl
Source1064: ptyprocess-0.7.0-py2.py3-none-any.whl
Source1065: suds_community-0.8.5-py3-none-any.whl
### END ###
# kubevirt
## pip download --no-binary :all: openshift "ruamel.yaml.clib>=0.1.2"
### BEGIN
Source1091: %{openshift}-%{openshift_version}.tar.gz
Source1092: %{ruamelyamlclib}-%{ruamelyamlclib_version}.tar.gz
Source1093: %{kubernetes}-%{kubernetes_version}.tar.gz
Source1094: %{certifi}-%{certifi_version}.tar.gz
Source1095: %{googleauth}-%{googleauth_version}.tar.gz
Source1096: %{cachetools}-%{cachetools_version}.tar.gz
Source1097: %{pyasn1modules}-%{pyasn1modules_version}.tar.gz
Source1098: %{pyasn1}-%{pyasn1_version}.tar.gz
Source1099: python-%{dateutil}-%{dateutil_version}.tar.gz
Source1100: %{pyyaml}-%{pyyaml_version}.tar.gz
Source1066: %{openshift}-%{openshift_version}.tar.gz
Source1067: %{ruamelyamlclib}-%{ruamelyamlclib_version}.tar.gz
Source1068: %{kubernetes}-%{kubernetes_version}.tar.gz
Source1069: %{certifi}-%{certifi_version}.tar.gz
Source1070: %{googleauth}-%{googleauth_version}.tar.gz
Source1071: %{cachetools}-%{cachetools_version}.tar.gz
Source1072: %{pyasn1modules}-%{pyasn1modules_version}.tar.gz
Source1073: %{pyasn1}-%{pyasn1_version}.tar.gz
Source1074: python-%{dateutil}-%{dateutil_version}.tar.gz
Source1075: %{pyyaml}-%{pyyaml_version}.tar.gz
## rsa is dependency for "pip install",
## but gets removed to use cryptography lib instead
Source1101: rsa-4.7.2.tar.gz
Source1102: %{six}-%{six_version}.tar.gz
Source1103: %{urllib3}-%{urllib3_version}.tar.gz
Source1104: %{websocketclient}-%{websocketclient_version}.tar.gz
Source1105: %{jinja2}-%{jinja2_version}.tar.gz
Source1106: %{markupsafe}-%{markupsafe_version}.tar.gz
Source1107: python-%{stringutils}-%{stringutils_version}.tar.gz
Source1108: %{requests}-%{requests_version}.tar.gz
Source1109: %{chrstnormalizer}-%{chrstnormalizer_version}.tar.gz
Source1110: %{idna}-%{idna_version}.tar.gz
Source1111: %{reqstsoauthlib}-%{reqstsoauthlib_version}.tar.gz
Source1112: %{oauthlib}-%{oauthlib_version}.tar.gz
Source1113: %{ruamelyaml}-%{ruamelyaml_version}.tar.gz
Source1114: %{setuptools}-%{setuptools_version}.tar.gz
Source1076: rsa-4.7.2.tar.gz
Source1077: %{six}-%{six_version}.tar.gz
Source1078: %{urllib3}-%{urllib3_version}.tar.gz
Source1079: %{websocketclient}-%{websocketclient_version}.tar.gz
Source1080: %{jinja2}-%{jinja2_version}.tar.gz
Source1081: %{markupsafe}-%{markupsafe_version}.tar.gz
Source1082: python-%{stringutils}-%{stringutils_version}.tar.gz
Source1083: %{requests}-%{requests_version}.tar.gz
Source1084: %{chrstnormalizer}-%{chrstnormalizer_version}.tar.gz
Source1085: %{idna}-%{idna_version}.tar.gz
Source1086: %{reqstsoauthlib}-%{reqstsoauthlib_version}.tar.gz
Source1087: %{oauthlib}-%{oauthlib_version}.tar.gz
Source1088: %{ruamelyaml}-%{ruamelyaml_version}.tar.gz
Source1089: %{setuptools}-%{setuptools_version}.tar.gz
## required for installation
Source1115: setuptools_scm-6.3.2.tar.gz
Source1116: packaging-21.2-py3-none-any.whl
Source1117: poetry-core-1.0.7.tar.gz
Source1118: pyparsing-3.0.1.tar.gz
Source1119: tomli-1.0.1.tar.gz
Source1090: setuptools_scm-6.3.2.tar.gz
Source1091: packaging-21.2-py3-none-any.whl
Source1092: poetry-core-1.0.7.tar.gz
Source1093: pyparsing-3.0.1.tar.gz
Source1094: tomli-1.0.1.tar.gz
Source1095: wheel-0.37.0-py2.py3-none-any.whl
### END
Patch0: ha-cloud-support-aliyun.patch
Patch1: ha-cloud-support-aws.patch
Patch2: ha-cloud-support-azure.patch
Patch3: ha-cloud-support-google.patch
Patch4: ha-openstack-support.patch
Patch5: bundled-pexpect.patch
Patch6: bundled-suds.patch
Patch4: bundled-pexpect.patch
Patch5: bundled-suds.patch
Patch6: bz2010652-fence_azure_arm-fix-sovereign-cloud-msi-support.patch
Patch7: bz2010709-1-fence_amt_ws-fix-or-causing-dead-code.patch
Patch8: bz2010709-2-fence_amt_ws-boot-option.patch
Patch9: bz2000954-1-configure-fix-virt.patch
@ -232,8 +206,15 @@ Patch15: bz2041933-bz2041935-1-fence_openstack-clouds-openrc.patch
Patch16: bz2041933-bz2041935-2-fence_openstack-clouds-openrc.patch
Patch17: bz2042496-fence_ibm_vpc-fence_ibm_powervs.patch
Patch18: bz2022334-fence_zvmip-add-disable-ssl.patch
Patch19: bz2086839-1-fence_apc-fence_ilo_moonshot-import-logging.patch
Patch20: bz2086839-2-fence_lpar-fix-import-fail_usage.patch
Patch19: bz2065114-fence_lpar-refactor.patch
Patch20: bz2072420-1-all-agents-unify-ssl-parameters.patch
Patch21: bz2079889-fence_gce-update.patch
Patch22: bz2081235-fence_ibm_vpc-fix-parameters.patch
Patch23: bz2086559-fence_apc-fence_ilo_moonshot-import-logging.patch
Patch24: bz2072420-2-fence_zvmip-connect-error.patch
Patch25: bz2092385-fence_ibm_vpc-add-proxy-support.patch
Patch26: bz2093216-fence_ibm_powervs-proxy-private-api-servers.patch
Patch27: bz2041933-bz2041935-3-fencing-source_env-dont-process-empty-lines.patch
%global supportedagents amt_ws apc apc_snmp bladecenter brocade cisco_mds cisco_ucs compute drac5 eaton_snmp emerson eps evacuate hpblade ibmblade ibm_powervs ibm_vpc ifmib ilo ilo_moonshot ilo_mp ilo_ssh intelmodular ipdu ipmilan kdump kubevirt lpar mpath redfish rhevm rsa rsb sbd scsi vmware_rest vmware_soap wti
%ifarch x86_64
@ -365,6 +346,13 @@ BuildRequires: %{systemd_units}
%patch18 -p1
%patch19 -p1
%patch20 -p1
%patch21 -p1
%patch22 -p1
%patch23 -p1
%patch24 -p1
%patch25 -p1
%patch26 -p1
%patch27 -p1
# prevent compilation of something that won't get used anyway
sed -i.orig 's|FENCE_ZVM=1|FENCE_ZVM=0|' configure.ac
@ -379,10 +367,7 @@ sed -i.orig 's|FENCE_ZVM=1|FENCE_ZVM=0|' configure.ac
LIBS="%{_sourcedir}/requirements-*.txt"
echo "awscli" >> %{_sourcedir}/requirements-awscli.txt
%endif
%ifarch ppc64le
LIBS="%{_sourcedir}/requirements-openstack.txt %{_sourcedir}/requirements-common.txt"
%endif
%ifnarch x86_64 ppc64le
%ifnarch x86_64
LIBS="%{_sourcedir}/requirements-common.txt"
%endif
for x in $LIBS; do
@ -399,7 +384,7 @@ sed -i -e "/^import awscli.clidriver/isys.path.insert(0, '/usr/lib/%{name}/suppo
%endif
./autogen.sh
%{configure} --disable-libvirt-qmf-plugin PYTHONPATH="support/aliyun:support/aws:support/azure:support/google:support/openstack:support/common" --with-agents='%{supportedagents} %{testagents}'
%{configure} --disable-libvirt-qmf-plugin PYTHONPATH="support/aliyun:support/aws:support/azure:support/google:support/common" --with-agents='%{supportedagents} %{testagents}'
CFLAGS="$(echo '%{optflags}')" make %{_smp_mflags}
%install
@ -585,45 +570,9 @@ Support libraries for Fence Agents.
%files -n ha-cloud-support
%dir %{_usr}/lib/%{name}
%{_usr}/lib/%{name}/support
%exclude %{_usr}/lib/%{name}/support/openstack
%exclude %{_usr}/lib/%{name}/support/common
%endif
%ifarch x86_64 ppc64le
%package -n ha-openstack-support
License: GPLv2+ and LGPLv2+
Summary: Support libraries for OpenStack agents
Provides: bundled(python-PyYAML) = 5.1
Provides: bundled(python-charset-normalizer) = 2.0.4
Provides: bundled(python-debtcollector) = 2.2.0
Provides: bundled(python-idna) = 3.2
Provides: bundled(python-iso8601) = 0.1.16
Provides: bundled(python-keystoneauth1) = 4.3.1
Provides: bundled(python-msgpack) = 1.0.2
Provides: bundled(python-netaddr) = 0.8.0
Provides: bundled(python-netifaces) = 0.11.0
Provides: bundled(python-oslo-config) = 8.7.1
Provides: bundled(python-oslo-i18n) = 5.0.1
Provides: bundled(python-oslo-serialization) = 4.2.0
Provides: bundled(python-oslo-utils) = 4.10.0
Provides: bundled(python-os-service-types) = 1.7.0
Provides: bundled(python-packaging) = 21.0
Provides: bundled(python-pbr) = 5.6.0
Provides: bundled(python-prettytable) = 2.2.0
Provides: bundled(python-keystoneclient) = 4.2.0
Provides: bundled(python-novaclient) = 17.5.0
Provides: bundled(python-requests) = 2.26.0
Provides: bundled(python-rfc3986) = 1.5.0
Provides: bundled(python-stevedore) = 3.4.0
Provides: bundled(python-wcwidth) = 0.2.5
Provides: bundled(python-wrapt) = 1.12.1
%description -n ha-openstack-support
Support libraries for Fence Agents.
%files -n ha-openstack-support
%dir %{_usr}/lib/%{name}
%{_usr}/lib/%{name}/support/openstack
%endif
%package all
License: GPLv2+ and LGPLv2+ and ASL 2.0
Summary: Set of unified programs capable of host isolation ("fencing")
@ -826,7 +775,7 @@ Requires: python3-requests
Requires: python-requests
%endif
Requires: fence-agents-common = %{version}-%{release}
Requires: ha-openstack-support = %{version}-%{release}
Obsoletes: ha-openstack-support <= %{version}-%{release}
%description compute
Fence agent for Nova compute nodes.
%files compute
@ -1202,7 +1151,7 @@ Requires: python3-requests
Requires: python-requests
%endif
Requires: fence-agents-common = %{version}-%{release}
Requires: ha-openstack-support = %{version}-%{release}
Obsoletes: ha-openstack-support <= %{version}-%{release}
%description openstack
Fence agent for OpenStack's Nova service.
%files openstack
@ -1456,13 +1405,49 @@ are located on corosync cluster nodes.
%endif
%changelog
* Tue May 17 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-20.2
- fence_apc/fence_ilo_moonshot/fence_lpar: add missing "import logging"
Resolves: rhbz#2086839
* Tue Aug 16 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-30
- fence_openstack: add support for reading config from clouds.yaml
and openrc
Resolves: rhbz#2041933, rhbz#2041935
* Wed Mar 9 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-20
* Wed Jun 22 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-27
- fence_ibm_powervs: add support for proxy, private API servers and
get token via API key
Resolves: rhbz#2093216
* Wed Jun 1 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-26
- fence_ibm_vpc: add proxy support
Resolves: rhbz#2092385
* Tue May 31 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-25
- all agents: unify ssl parameters to avoid having to use --ssl when
using --ssl-secure/--ssl-insecure for some agents
Resolves: rhbz#2072420
* Tue May 17 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-24
- fence_apc/fence_ilo_moonshot: add missing "import logging"
Resolves: rhbz#2086559
* Thu May 5 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-23
- fence_ibm_vpc: remove unused instance parameter and make limit
optional
Resolves: rhbz#2081235
* Fri Apr 29 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-22
- fence_gce: update fence agent
Resolves: rhbz#2079889
* Wed Apr 6 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-21
- fence_lpar: refactor to avoid duplicate code
Resolves: rhbz#2065114
* Wed Mar 30 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-20
- fence_azure_arm: fix sovereign cloud and MSI support
Resolves: rhbz#2010652
* Mon Mar 7 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-19
- fence_ibm_vpc: new fence agent
Resolves: rhbz#2060562
Resolves: rhbz#2061321
* Fri Feb 11 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-18
- fence_zvmip: add SSL/TLS support
@ -1472,11 +1457,6 @@ are located on corosync cluster nodes.
- fence_ibm_powervs: new fence agent
Resolves: rhbz#2042496
* Wed Jan 19 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-16
- fence_openstack: add support for reading config from clouds.yaml
and openrc
Resolves: rhbz#2041933, rhbz#2041935
* Mon Jan 17 2022 Oyvind Albrigtsen <oalbrigt@redhat.com> - 4.10.0-15
- fence_kubevirt: new fence agent
Resolves: rhbz#2000954