Compare commits
No commits in common. "c8" and "c8s" have entirely different histories.
@ -1,37 +0,0 @@
|
|||||||
3297473a9d57e93ff378eab173990c1b64673c01 SOURCES/Jinja2-3.0.2.tar.gz
|
|
||||||
e1b766b2b1601fde67b3b19ed2f13b9746bb1cca SOURCES/MarkupSafe-2.0.1.tar.gz
|
|
||||||
a8c40a3ae9d4c159382a58db3153d83e5521c51e SOURCES/PyYAML-6.0.tar.gz
|
|
||||||
0a56f6d9ed2014a363486d33b63eca094379be06 SOURCES/aliyun-python-sdk-core-2.13.1.tar.gz
|
|
||||||
c2a98b9a1562d223a76514f05028488ca000c395 SOURCES/aliyun-python-sdk-ecs-4.9.3.tar.gz
|
|
||||||
f14647a4d37a9a254c4e711b95a7654fc418e41e SOURCES/aliyun-python-sdk-vpc-3.0.2.tar.gz
|
|
||||||
2512ff4ef016cad0b916006f6acf2a309f908c4d SOURCES/botocore-1.23.46.tar.gz
|
|
||||||
0d12f48faa727f0979e9ad5c4c80dfa32b73caff SOURCES/cachetools-4.2.4.tar.gz
|
|
||||||
ec7e8dd8ef95edfdb83a1ea040b8b88507b47615 SOURCES/certifi-2023.7.22.tar.gz
|
|
||||||
2384f6cfba4685d901262e073a4455d4cf76d102 SOURCES/chardet-4.0.0.tar.gz
|
|
||||||
865df92e66e5dc7b940144cbad8115c07dc8784f SOURCES/charset-normalizer-2.0.7.tar.gz
|
|
||||||
e2561df8e7ff9113dab118a651371dd88dab0142 SOURCES/fence-agents-4.2.1.tar.gz
|
|
||||||
f4e578dc0ed68d6667d7b36cdfc2647d55e9858f SOURCES/google-auth-2.3.0.tar.gz
|
|
||||||
74ec77d2e2ef6b2ef8503e6e398faa6f3ba298ae SOURCES/httplib2-0.19.1-py3-none-any.whl
|
|
||||||
08c0449533fc94462f78652dea209099754d9ee4 SOURCES/idna-3.3.tar.gz
|
|
||||||
356c48dfea2214dd9e7e2b222a99dddfe9c0d05c SOURCES/jmespath-0.10.0.tar.gz
|
|
||||||
d06a9547b1a87e9c51b0a7c708189d993f2e3d89 SOURCES/kubernetes-12.0.1.tar.gz
|
|
||||||
f6efa66f6106b069b5c0e0cf8cc677e4e96c91ca SOURCES/oauthlib-3.1.1.tar.gz
|
|
||||||
570d69d8c108ebb8aee562389d13b07dfb61ce25 SOURCES/openshift-0.12.1.tar.gz
|
|
||||||
bccbc1bf76a9db46998eb8e1ffa2f2a2baf9237a SOURCES/packaging-21.2-py3-none-any.whl
|
|
||||||
e0fa19f8fda46a1fa2253477499b116b33f67175 SOURCES/pyasn1-0.4.8.tar.gz
|
|
||||||
43b89feb6864fe359aae89120627165219de313b SOURCES/pyasn1-modules-0.2.8.tar.gz
|
|
||||||
c55d177e9484d974c95078d4ae945f89ba2c7251 SOURCES/pycryptodome-3.20.0.tar.gz
|
|
||||||
c8307f47e3b75a2d02af72982a2dfefa3f56e407 SOURCES/pyparsing-2.4.7-py2.py3-none-any.whl
|
|
||||||
c2ba10c775b7a52a4b57cac4d4110a0c0f812a82 SOURCES/python-dateutil-2.8.2.tar.gz
|
|
||||||
1dc2fa004aa6517f1620e55d8a7b8e68a9cf2a47 SOURCES/python-string-utils-1.0.0.tar.gz
|
|
||||||
8c7a89d183d3e9b70bf91ba5b75eccf7111b9d8d SOURCES/requests-2.26.0.tar.gz
|
|
||||||
f139aed770519b6a095b8fdc888d03955cbe9d8e SOURCES/requests-oauthlib-1.3.0.tar.gz
|
|
||||||
e8a53067e03fe1b6682fd99a40a7359396a06daa SOURCES/rsa-4.7.2.tar.gz
|
|
||||||
d1011ff44cd5a045de0460c1b79ec65592e86860 SOURCES/ruamel.yaml-0.17.16.tar.gz
|
|
||||||
27de97227bbbde5a9f571f9fad223578d7bdf7cc SOURCES/ruamel.yaml.clib-0.2.6.tar.gz
|
|
||||||
d5354718cb8c9330d3abc27445467ce8a5ed9d70 SOURCES/setuptools-58.3.0.tar.gz
|
|
||||||
a4f02fddae697614e356cadfddb6241cc7737f38 SOURCES/setuptools_scm-6.3.2.tar.gz
|
|
||||||
06fa0bb50f2a4e2917fd14c21e9d2d5508ce0163 SOURCES/six-1.16.0.tar.gz
|
|
||||||
b42b7960047441db7dc021cc20e14279bd836f8d SOURCES/tomli-1.0.1.tar.gz
|
|
||||||
84e2852d8da1655373f7ce5e7d5d3e256b62b4e4 SOURCES/urllib3-1.26.18.tar.gz
|
|
||||||
540f083782c584989c1a0f69ffd69ba7aae07db6 SOURCES/websocket-client-1.2.1.tar.gz
|
|
47
.gitignore
vendored
47
.gitignore
vendored
@ -1,37 +1,10 @@
|
|||||||
SOURCES/Jinja2-3.0.2.tar.gz
|
/*.tar.?z*
|
||||||
SOURCES/MarkupSafe-2.0.1.tar.gz
|
/*.rpm
|
||||||
SOURCES/PyYAML-6.0.tar.gz
|
/*.txt
|
||||||
SOURCES/aliyun-python-sdk-core-2.13.1.tar.gz
|
/*.whl
|
||||||
SOURCES/aliyun-python-sdk-ecs-4.9.3.tar.gz
|
/*.zip
|
||||||
SOURCES/aliyun-python-sdk-vpc-3.0.2.tar.gz
|
/.*.swp
|
||||||
SOURCES/botocore-1.23.46.tar.gz
|
/.build-*.log
|
||||||
SOURCES/cachetools-4.2.4.tar.gz
|
/*/
|
||||||
SOURCES/certifi-2023.7.22.tar.gz
|
!/tests/
|
||||||
SOURCES/chardet-4.0.0.tar.gz
|
/tests/*.retry
|
||||||
SOURCES/charset-normalizer-2.0.7.tar.gz
|
|
||||||
SOURCES/fence-agents-4.2.1.tar.gz
|
|
||||||
SOURCES/google-auth-2.3.0.tar.gz
|
|
||||||
SOURCES/httplib2-0.19.1-py3-none-any.whl
|
|
||||||
SOURCES/idna-3.3.tar.gz
|
|
||||||
SOURCES/jmespath-0.10.0.tar.gz
|
|
||||||
SOURCES/kubernetes-12.0.1.tar.gz
|
|
||||||
SOURCES/oauthlib-3.1.1.tar.gz
|
|
||||||
SOURCES/openshift-0.12.1.tar.gz
|
|
||||||
SOURCES/packaging-21.2-py3-none-any.whl
|
|
||||||
SOURCES/pyasn1-0.4.8.tar.gz
|
|
||||||
SOURCES/pyasn1-modules-0.2.8.tar.gz
|
|
||||||
SOURCES/pycryptodome-3.20.0.tar.gz
|
|
||||||
SOURCES/pyparsing-2.4.7-py2.py3-none-any.whl
|
|
||||||
SOURCES/python-dateutil-2.8.2.tar.gz
|
|
||||||
SOURCES/python-string-utils-1.0.0.tar.gz
|
|
||||||
SOURCES/requests-2.26.0.tar.gz
|
|
||||||
SOURCES/requests-oauthlib-1.3.0.tar.gz
|
|
||||||
SOURCES/rsa-4.7.2.tar.gz
|
|
||||||
SOURCES/ruamel.yaml-0.17.16.tar.gz
|
|
||||||
SOURCES/ruamel.yaml.clib-0.2.6.tar.gz
|
|
||||||
SOURCES/setuptools-58.3.0.tar.gz
|
|
||||||
SOURCES/setuptools_scm-6.3.2.tar.gz
|
|
||||||
SOURCES/six-1.16.0.tar.gz
|
|
||||||
SOURCES/tomli-1.0.1.tar.gz
|
|
||||||
SOURCES/urllib3-1.26.18.tar.gz
|
|
||||||
SOURCES/websocket-client-1.2.1.tar.gz
|
|
||||||
|
84
RHEL-5397-3-fence_scsi-fix-run_cmd.patch
Normal file
84
RHEL-5397-3-fence_scsi-fix-run_cmd.patch
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
--- a/agents/scsi/fence_scsi.py 2024-01-03 14:06:10.155417318 +0100
|
||||||
|
+++ b/agents/scsi/fence_scsi.py 2024-01-03 14:07:40.737369588 +0100
|
||||||
|
@@ -84,14 +84,14 @@
|
||||||
|
# check if host is ready to execute actions
|
||||||
|
def do_action_monitor(options):
|
||||||
|
# Check if required binaries are installed
|
||||||
|
- if bool(run_cmd(options, options["--sg_persist-path"] + " -V")["err"]):
|
||||||
|
+ if bool(run_cmd(options, options["--sg_persist-path"] + " -V")["rc"]):
|
||||||
|
logging.error("Unable to run " + options["--sg_persist-path"])
|
||||||
|
return 1
|
||||||
|
- elif bool(run_cmd(options, options["--sg_turs-path"] + " -V")["err"]):
|
||||||
|
+ elif bool(run_cmd(options, options["--sg_turs-path"] + " -V")["rc"]):
|
||||||
|
logging.error("Unable to run " + options["--sg_turs-path"])
|
||||||
|
return 1
|
||||||
|
elif ("--devices" not in options and
|
||||||
|
- bool(run_cmd(options, options["--vgs-path"] + " --version")["err"])):
|
||||||
|
+ bool(run_cmd(options, options["--vgs-path"] + " --version")["rc"])):
|
||||||
|
logging.error("Unable to run " + options["--vgs-path"])
|
||||||
|
return 1
|
||||||
|
|
||||||
|
@@ -102,11 +102,13 @@
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
-#run command, returns dict, ret["err"] = exit code; ret["out"] = output
|
||||||
|
+# run command, returns dict, ret["rc"] = exit code; ret["out"] = output;
|
||||||
|
+# ret["err"] = error
|
||||||
|
def run_cmd(options, cmd):
|
||||||
|
ret = {}
|
||||||
|
- (ret["err"], ret["out"], _) = run_command(options, cmd)
|
||||||
|
+ (ret["rc"], ret["out"], ret["err"]) = run_command(options, cmd)
|
||||||
|
ret["out"] = "".join([i for i in ret["out"] if i is not None])
|
||||||
|
+ ret["err"] = "".join([i for i in ret["err"] if i is not None])
|
||||||
|
return ret
|
||||||
|
|
||||||
|
|
||||||
|
@@ -122,11 +124,11 @@
|
||||||
|
def preempt_abort(options, host, dev):
|
||||||
|
reset_dev(options,dev)
|
||||||
|
cmd = options["--sg_persist-path"] + " -n -o -A -T 5 -K " + host + " -S " + options["--key"] + " -d " + dev
|
||||||
|
- return not bool(run_cmd(options, cmd)["err"])
|
||||||
|
+ return not bool(run_cmd(options, cmd)["rc"])
|
||||||
|
|
||||||
|
|
||||||
|
def reset_dev(options, dev):
|
||||||
|
- return run_cmd(options, options["--sg_turs-path"] + " " + dev)["err"]
|
||||||
|
+ return run_cmd(options, options["--sg_turs-path"] + " " + dev)["rc"]
|
||||||
|
|
||||||
|
|
||||||
|
def register_dev(options, dev, key):
|
||||||
|
@@ -171,13 +173,13 @@
|
||||||
|
reset_dev(options, dev)
|
||||||
|
cmd = options["--sg_persist-path"] + " -n -o -I -S " + key + " -d " + dev
|
||||||
|
cmd += " -Z" if "--aptpl" in options else ""
|
||||||
|
- return not bool(run_cmd(options, cmd)["err"])
|
||||||
|
+ return not bool(run_cmd(options, cmd)["rc"])
|
||||||
|
|
||||||
|
|
||||||
|
def reserve_dev(options, dev):
|
||||||
|
reset_dev(options,dev)
|
||||||
|
cmd = options["--sg_persist-path"] + " -n -o -R -T 5 -K " + options["--key"] + " -d " + dev
|
||||||
|
- return not bool(run_cmd(options, cmd)["err"])
|
||||||
|
+ return not bool(run_cmd(options, cmd)["rc"])
|
||||||
|
|
||||||
|
|
||||||
|
def get_reservation_key(options, dev, fail=True):
|
||||||
|
@@ -201,7 +203,7 @@
|
||||||
|
opts = "-y "
|
||||||
|
cmd = options["--sg_persist-path"] + " -n -i " + opts + "-k -d " + dev
|
||||||
|
out = run_cmd(options, cmd)
|
||||||
|
- if out["err"]:
|
||||||
|
+ if out["rc"]:
|
||||||
|
fail_usage("Cannot get registration keys", fail)
|
||||||
|
if not fail:
|
||||||
|
return []
|
||||||
|
@@ -319,7 +321,7 @@
|
||||||
|
"--options vg_attr,pv_name "+\
|
||||||
|
"--config 'global { locking_type = 0 } devices { preferred_names = [ \"^/dev/dm\" ] }'"
|
||||||
|
out = run_cmd(options, cmd)
|
||||||
|
- if out["err"]:
|
||||||
|
+ if out["rc"]:
|
||||||
|
fail_usage("Failed: Cannot get shared devices")
|
||||||
|
for line in out["out"].splitlines():
|
||||||
|
vg_attr, pv_name = line.strip().split(":")
|
381
RHEL-76492-fence_azure_arm-use-azure-identity.patch
Normal file
381
RHEL-76492-fence_azure_arm-use-azure-identity.patch
Normal file
@ -0,0 +1,381 @@
|
|||||||
|
--- a/lib/azure_fence.py.py 2025-01-30 14:47:16.047999700 +0100
|
||||||
|
+++ b/lib/azure_fence.py.py 2025-01-30 12:06:10.847889534 +0100
|
||||||
|
@@ -14,6 +14,9 @@
|
||||||
|
IP_TYPE_DYNAMIC = "Dynamic"
|
||||||
|
MAX_RETRY = 10
|
||||||
|
RETRY_WAIT = 5
|
||||||
|
+NETWORK_MGMT_CLIENT_API_VERSION = "2021-05-01"
|
||||||
|
+AZURE_RHEL8_COMPUTE_VERSION = "27.2.0"
|
||||||
|
+AZURE_COMPUTE_VERSION_5 = "5.0.0"
|
||||||
|
|
||||||
|
class AzureSubResource:
|
||||||
|
Type = None
|
||||||
|
@@ -49,7 +52,7 @@
|
||||||
|
return None
|
||||||
|
|
||||||
|
def get_azure_resource(id):
|
||||||
|
- match = re.match('(/subscriptions/([^/]*)/resourceGroups/([^/]*))(/providers/([^/]*/[^/]*)/([^/]*))?((/([^/]*)/([^/]*))*)', id)
|
||||||
|
+ match = re.match(r'(/subscriptions/([^/]*)/resourceGroups/([^/]*))(/providers/([^/]*/[^/]*)/([^/]*))?((/([^/]*)/([^/]*))*)', id)
|
||||||
|
if not match:
|
||||||
|
fail_usage("{get_azure_resource} cannot parse resource id %s" % id)
|
||||||
|
|
||||||
|
@@ -86,6 +89,59 @@
|
||||||
|
|
||||||
|
return resource
|
||||||
|
|
||||||
|
+def azure_dep_versions(v):
|
||||||
|
+ return tuple(map(int, (v.split("."))))
|
||||||
|
+
|
||||||
|
+# Do azure API call to list all virtual machines in a resource group
|
||||||
|
+def get_vm_list(compute_client,rgName):
|
||||||
|
+ return compute_client.virtual_machines.list(rgName)
|
||||||
|
+
|
||||||
|
+# Do azue API call to shutdown a virtual machine
|
||||||
|
+def do_vm_power_off(compute_client,rgName,vmName, skipShutdown):
|
||||||
|
+ try:
|
||||||
|
+ # Version is not available in azure-mgmt-compute version 14.0.0 until 27.2.0
|
||||||
|
+ from azure.mgmt.compute import __version__
|
||||||
|
+ except ImportError:
|
||||||
|
+ __version__ = "0.0.0"
|
||||||
|
+
|
||||||
|
+ # use different implementation call based on used version
|
||||||
|
+ if (azure_dep_versions(__version__) == azure_dep_versions(AZURE_COMPUTE_VERSION_5)):
|
||||||
|
+ logging.debug("{do_vm_power_off} azure.mgtm.compute version is to old to use 'begin_power_off' use 'power_off' function")
|
||||||
|
+ compute_client.virtual_machines.power_off(rgName, vmName, skip_shutdown=skipShutdown)
|
||||||
|
+ return
|
||||||
|
+
|
||||||
|
+ compute_client.virtual_machines.begin_power_off(rgName, vmName, skip_shutdown=skipShutdown)
|
||||||
|
+
|
||||||
|
+# Do azure API call to start a virtual machine
|
||||||
|
+def do_vm_start(compute_client,rgName,vmName):
|
||||||
|
+ try:
|
||||||
|
+ # Version is not available in azure-mgmt-compute version 14.0.0 until 27.2.0
|
||||||
|
+ from azure.mgmt.compute import __version__
|
||||||
|
+ except ImportError:
|
||||||
|
+ __version__ = "0.0.0"
|
||||||
|
+
|
||||||
|
+ # use different implementation call based on used version
|
||||||
|
+ if (azure_dep_versions(__version__) == azure_dep_versions(AZURE_COMPUTE_VERSION_5)):
|
||||||
|
+ logging.debug("{do_vm_start} azure.mgtm.compute version is to old to use 'begin_start' use 'start' function")
|
||||||
|
+ compute_client.virtual_machines.start(rgName, vmName)
|
||||||
|
+ return
|
||||||
|
+
|
||||||
|
+ compute_client.virtual_machines.begin_start(rgName, vmName)
|
||||||
|
+
|
||||||
|
+def get_vm_resource(compute_client, rgName, vmName):
|
||||||
|
+ try:
|
||||||
|
+ # Version is not available in azure-mgmt-compute version 14.0.0 until 27.2.0
|
||||||
|
+ from azure.mgmt.compute import __version__
|
||||||
|
+ except ImportError:
|
||||||
|
+ __version__ = "0.0.0"
|
||||||
|
+
|
||||||
|
+ # use different implementation call based on used version
|
||||||
|
+ if (azure_dep_versions(__version__) <= azure_dep_versions(AZURE_RHEL8_COMPUTE_VERSION)):
|
||||||
|
+ return compute_client.virtual_machines.get(rgName, vmName, "instanceView")
|
||||||
|
+
|
||||||
|
+ return compute_client.virtual_machines.get(resource_group_name=rgName, vm_name=vmName,expand="instanceView")
|
||||||
|
+
|
||||||
|
+
|
||||||
|
def get_fence_subnet_for_config(ipConfig, network_client):
|
||||||
|
subnetResource = get_azure_resource(ipConfig.subnet.id)
|
||||||
|
logging.debug("{get_fence_subnet_for_config} testing virtual network %s in resource group %s for a fence subnet" %(subnetResource.ResourceName, subnetResource.ResourceGroupName))
|
||||||
|
@@ -152,7 +208,7 @@
|
||||||
|
result = FENCE_STATE_ON
|
||||||
|
|
||||||
|
try:
|
||||||
|
- vm = compute_client.virtual_machines.get(rgName, vmName, "instanceView")
|
||||||
|
+ vm = get_vm_resource(compute_client, rgName, vmName)
|
||||||
|
|
||||||
|
allNICOK = True
|
||||||
|
for nicRef in vm.network_profile.network_interfaces:
|
||||||
|
@@ -179,7 +235,7 @@
|
||||||
|
import msrestazure.azure_exceptions
|
||||||
|
logging.info("{set_network_state} Setting state %s for %s in resource group %s" % (operation, vmName, rgName))
|
||||||
|
|
||||||
|
- vm = compute_client.virtual_machines.get(rgName, vmName, "instanceView")
|
||||||
|
+ vm = get_vm_resource(compute_client,rgName, vmName)
|
||||||
|
|
||||||
|
operations = []
|
||||||
|
for nicRef in vm.network_profile.network_interfaces:
|
||||||
|
@@ -268,10 +324,72 @@
|
||||||
|
|
||||||
|
return config
|
||||||
|
|
||||||
|
+# Function to fetch endpoints from metadata endpoint for azure_stack
|
||||||
|
+def get_cloud_from_arm_metadata_endpoint(arm_endpoint):
|
||||||
|
+ try:
|
||||||
|
+ import requests
|
||||||
|
+ session = requests.Session()
|
||||||
|
+ metadata_endpoint = arm_endpoint + "/metadata/endpoints?api-version=2015-01-01"
|
||||||
|
+ response = session.get(metadata_endpoint)
|
||||||
|
+ if response.status_code == 200:
|
||||||
|
+ metadata = response.json()
|
||||||
|
+ return {
|
||||||
|
+ "resource_manager": arm_endpoint,
|
||||||
|
+ "credential_scopes": [metadata.get("graphEndpoint") + "/.default"],
|
||||||
|
+ "authority_hosts": metadata['authentication'].get('loginEndpoint').replace("https://","")
|
||||||
|
+ }
|
||||||
|
+ else:
|
||||||
|
+ fail_usage("Failed to get cloud from metadata endpoint: %s - %s" % arm_endpoint, e)
|
||||||
|
+ except Exception as e:
|
||||||
|
+ fail_usage("Failed to get cloud from metadata endpoint: %s - %s" % arm_endpoint, e)
|
||||||
|
+
|
||||||
|
+def get_azure_arm_endpoints(cloudName, authority):
|
||||||
|
+ cloudEnvironment = {
|
||||||
|
+ "authority_hosts": authority
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if cloudName == "AZURE_CHINA_CLOUD":
|
||||||
|
+ cloudEnvironment["resource_manager"] = "https://management.chinacloudapi.cn/"
|
||||||
|
+ cloudEnvironment["credential_scopes"] = ["https://management.chinacloudapi.cn/.default"]
|
||||||
|
+ return cloudEnvironment
|
||||||
|
+
|
||||||
|
+ if cloudName == "AZURE_US_GOV_CLOUD":
|
||||||
|
+ cloudEnvironment["resource_manager"] = "https://management.usgovcloudapi.net/"
|
||||||
|
+ cloudEnvironment["credential_scopes"] = ["https://management.core.usgovcloudapi.net/.default"]
|
||||||
|
+ return cloudEnvironment
|
||||||
|
+
|
||||||
|
+ if cloudName == "AZURE_PUBLIC_CLOUD":
|
||||||
|
+ cloudEnvironment["resource_manager"] = "https://management.azure.com/"
|
||||||
|
+ cloudEnvironment["credential_scopes"] = ["https://management.azure.com/.default"]
|
||||||
|
+ return cloudEnvironment
|
||||||
|
+
|
||||||
|
+
|
||||||
|
def get_azure_cloud_environment(config):
|
||||||
|
- cloud_environment = None
|
||||||
|
- if config.Cloud:
|
||||||
|
+ if (config.Cloud is None):
|
||||||
|
+ config.Cloud = "public"
|
||||||
|
+
|
||||||
|
+ try:
|
||||||
|
+ from azure.identity import AzureAuthorityHosts
|
||||||
|
+
|
||||||
|
+ azureCloudName = "AZURE_PUBLIC_CLOUD"
|
||||||
|
+ authorityHosts = AzureAuthorityHosts.AZURE_PUBLIC_CLOUD
|
||||||
|
if (config.Cloud.lower() == "china"):
|
||||||
|
+ azureCloudName = "AZURE_CHINA_CLOUD"
|
||||||
|
+ authorityHosts = AzureAuthorityHosts.AZURE_CHINA
|
||||||
|
+ elif (config.Cloud.lower() == "usgov"):
|
||||||
|
+ azureCloudName = "AZURE_US_GOV_CLOUD"
|
||||||
|
+ authorityHosts = AzureAuthorityHosts.AZURE_GOVERNMENT
|
||||||
|
+ elif (config.Cloud.lower() == "stack"):
|
||||||
|
+ # use custom function to call the azuer stack metadata endpoint to get required configuration.
|
||||||
|
+ return get_cloud_from_arm_metadata_endpoint(config.MetadataEndpoint)
|
||||||
|
+
|
||||||
|
+ return get_azure_arm_endpoints(azureCloudName, authorityHosts)
|
||||||
|
+
|
||||||
|
+ except ImportError:
|
||||||
|
+ if (config.Cloud.lower() == "public"):
|
||||||
|
+ from msrestazure.azure_cloud import AZURE_PUBLIC_CLOUD
|
||||||
|
+ cloud_environment = AZURE_PUBLIC_CLOUD
|
||||||
|
+ elif (config.Cloud.lower() == "china"):
|
||||||
|
from msrestazure.azure_cloud import AZURE_CHINA_CLOUD
|
||||||
|
cloud_environment = AZURE_CHINA_CLOUD
|
||||||
|
elif (config.Cloud.lower() == "germany"):
|
||||||
|
@@ -284,31 +402,43 @@
|
||||||
|
from msrestazure.azure_cloud import get_cloud_from_metadata_endpoint
|
||||||
|
cloud_environment = get_cloud_from_metadata_endpoint(config.MetadataEndpoint)
|
||||||
|
|
||||||
|
- return cloud_environment
|
||||||
|
+ authority_hosts = cloud_environment.endpoints.active_directory.replace("http://","")
|
||||||
|
+ return {
|
||||||
|
+ "resource_manager": cloud_environment.endpoints.resource_manager,
|
||||||
|
+ "credential_scopes": [cloud_environment.endpoints.active_directory_resource_id + "/.default"],
|
||||||
|
+ "authority_hosts": authority_hosts,
|
||||||
|
+ "cloud_environment": cloud_environment,
|
||||||
|
+ }
|
||||||
|
|
||||||
|
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)
|
||||||
|
- elif config.UseMSI:
|
||||||
|
- from msrestazure.azure_active_directory import MSIAuthentication
|
||||||
|
- credentials = MSIAuthentication()
|
||||||
|
- elif cloud_environment:
|
||||||
|
- from azure.common.credentials import ServicePrincipalCredentials
|
||||||
|
- credentials = ServicePrincipalCredentials(
|
||||||
|
+ if config.UseMSI:
|
||||||
|
+ try:
|
||||||
|
+ from azure.identity import ManagedIdentityCredential
|
||||||
|
+ credentials = ManagedIdentityCredential(authority=cloud_environment["authority_hosts"])
|
||||||
|
+ except ImportError:
|
||||||
|
+ from msrestazure.azure_active_directory import MSIAuthentication
|
||||||
|
+ credentials = MSIAuthentication(cloud_environment=cloud_environment["cloud_environment"])
|
||||||
|
+ return credentials
|
||||||
|
+
|
||||||
|
+ try:
|
||||||
|
+ # try to use new libraries ClientSecretCredential (azure.identity, based on azure.core)
|
||||||
|
+ from azure.identity import ClientSecretCredential
|
||||||
|
+ credentials = ClientSecretCredential(
|
||||||
|
client_id = config.ApplicationId,
|
||||||
|
- secret = config.ApplicationKey,
|
||||||
|
- tenant = config.Tenantid,
|
||||||
|
- cloud_environment=cloud_environment
|
||||||
|
+ client_secret = config.ApplicationKey,
|
||||||
|
+ tenant_id = config.Tenantid,
|
||||||
|
+ authority=cloud_environment["authority_hosts"]
|
||||||
|
)
|
||||||
|
- else:
|
||||||
|
+ except ImportError:
|
||||||
|
+ # use old libraries ServicePrincipalCredentials (azure.common) if new one is not available
|
||||||
|
from azure.common.credentials import ServicePrincipalCredentials
|
||||||
|
credentials = ServicePrincipalCredentials(
|
||||||
|
client_id = config.ApplicationId,
|
||||||
|
secret = config.ApplicationKey,
|
||||||
|
- tenant = config.Tenantid
|
||||||
|
+ tenant = config.Tenantid,
|
||||||
|
+ cloud_environment=cloud_environment["cloud_environment"]
|
||||||
|
)
|
||||||
|
|
||||||
|
return credentials
|
||||||
|
@@ -317,40 +447,75 @@
|
||||||
|
from azure.mgmt.compute import ComputeManagementClient
|
||||||
|
|
||||||
|
cloud_environment = get_azure_cloud_environment(config)
|
||||||
|
- if cloud_environment and config.Cloud.lower() == "stack" and not config.MetadataEndpoint:
|
||||||
|
- fail_usage("metadata-endpoint not specified")
|
||||||
|
credentials = get_azure_credentials(config)
|
||||||
|
|
||||||
|
- if cloud_environment:
|
||||||
|
+ # Try to read the default used api version from the installed package.
|
||||||
|
+ try:
|
||||||
|
+ compute_api_version = ComputeManagementClient.LATEST_PROFILE.get_profile_dict()["azure.mgmt.compute.ComputeManagementClient"]["virtual_machines"]
|
||||||
|
+ except Exception as e:
|
||||||
|
+ compute_api_version = ComputeManagementClient.DEFAULT_API_VERSION
|
||||||
|
+ logging.debug("{get_azure_compute_client} Failed to get the latest profile: %s using the default api version %s" % (e, compute_api_version))
|
||||||
|
+
|
||||||
|
+ logging.debug("{get_azure_compute_client} use virtual_machine api version: %s" %(compute_api_version))
|
||||||
|
+
|
||||||
|
+ if (config.Cloud.lower() == "stack") and not config.MetadataEndpoint:
|
||||||
|
+ fail_usage("metadata-endpoint not specified")
|
||||||
|
+
|
||||||
|
+ try:
|
||||||
|
+ from azure.profiles import KnownProfiles
|
||||||
|
+ if (config.Cloud.lower() == "stack"):
|
||||||
|
+ client_profile = KnownProfiles.v2020_09_01_hybrid
|
||||||
|
+ else:
|
||||||
|
+ client_profile = KnownProfiles.default
|
||||||
|
compute_client = ComputeManagementClient(
|
||||||
|
credentials,
|
||||||
|
config.SubscriptionId,
|
||||||
|
- base_url=cloud_environment.endpoints.resource_manager
|
||||||
|
+ base_url=cloud_environment["resource_manager"],
|
||||||
|
+ profile=client_profile,
|
||||||
|
+ credential_scopes=cloud_environment["credential_scopes"],
|
||||||
|
+ api_version=compute_api_version
|
||||||
|
)
|
||||||
|
- else:
|
||||||
|
+ except TypeError:
|
||||||
|
compute_client = ComputeManagementClient(
|
||||||
|
credentials,
|
||||||
|
- config.SubscriptionId
|
||||||
|
+ config.SubscriptionId,
|
||||||
|
+ base_url=cloud_environment["resource_manager"],
|
||||||
|
+ api_version=compute_api_version
|
||||||
|
)
|
||||||
|
+
|
||||||
|
return compute_client
|
||||||
|
|
||||||
|
def get_azure_network_client(config):
|
||||||
|
from azure.mgmt.network import NetworkManagementClient
|
||||||
|
|
||||||
|
cloud_environment = get_azure_cloud_environment(config)
|
||||||
|
- if cloud_environment and config.Cloud.lower() == "stack" and not config.MetadataEndpoint:
|
||||||
|
- fail_usage("metadata-endpoint not specified")
|
||||||
|
credentials = get_azure_credentials(config)
|
||||||
|
|
||||||
|
- if cloud_environment:
|
||||||
|
+ if (config.Cloud.lower() == "stack") and not config.MetadataEndpoint:
|
||||||
|
+ fail_usage("metadata-endpoint not specified")
|
||||||
|
+
|
||||||
|
+
|
||||||
|
+ from azure.profiles import KnownProfiles
|
||||||
|
+
|
||||||
|
+ if (config.Cloud.lower() == "stack"):
|
||||||
|
+ client_profile = KnownProfiles.v2020_09_01_hybrid
|
||||||
|
+ else:
|
||||||
|
+ client_profile = KnownProfiles.default
|
||||||
|
+
|
||||||
|
+ try:
|
||||||
|
network_client = NetworkManagementClient(
|
||||||
|
credentials,
|
||||||
|
config.SubscriptionId,
|
||||||
|
- base_url=cloud_environment.endpoints.resource_manager
|
||||||
|
+ base_url=cloud_environment["resource_manager"],
|
||||||
|
+ profile=client_profile,
|
||||||
|
+ credential_scopes=cloud_environment["credential_scopes"],
|
||||||
|
+ api_version=NETWORK_MGMT_CLIENT_API_VERSION
|
||||||
|
)
|
||||||
|
- else:
|
||||||
|
+ except TypeError:
|
||||||
|
network_client = NetworkManagementClient(
|
||||||
|
credentials,
|
||||||
|
- config.SubscriptionId
|
||||||
|
+ config.SubscriptionId,
|
||||||
|
+ base_url=cloud_environment["resource_manager"],
|
||||||
|
+ api_version=NETWORK_MGMT_CLIENT_API_VERSION
|
||||||
|
)
|
||||||
|
return network_client
|
||||||
|
--- a/agents/azure_arm/fence_azure_arm.py 2025-01-30 15:28:35.889163377 +0100
|
||||||
|
+++ b/agents/azure_arm/fence_azure_arm.py 2025-01-30 15:28:52.190553135 +0100
|
||||||
|
@@ -7,7 +7,6 @@
|
||||||
|
sys.path.append("@FENCEAGENTSLIBDIR@")
|
||||||
|
from fencing import *
|
||||||
|
from fencing import fail_usage, run_command, run_delay
|
||||||
|
-
|
||||||
|
sys.path.insert(0, '/usr/lib/fence-agents/bundled/azure')
|
||||||
|
import azure_fence
|
||||||
|
|
||||||
|
@@ -17,7 +16,7 @@
|
||||||
|
if clients:
|
||||||
|
compute_client = clients[0]
|
||||||
|
rgName = options["--resourceGroup"]
|
||||||
|
- vms = compute_client.virtual_machines.list(rgName)
|
||||||
|
+ vms = azure_fence.get_vm_list(compute_client,rgName)
|
||||||
|
try:
|
||||||
|
for vm in vms:
|
||||||
|
result[vm.name] = ("", None)
|
||||||
|
@@ -33,7 +32,7 @@
|
||||||
|
rgName = options["--resourceGroup"]
|
||||||
|
|
||||||
|
try:
|
||||||
|
- vms = compute_client.virtual_machines.list(rgName)
|
||||||
|
+ vms = azure_fence.get_vm_list(compute_client,rgName)
|
||||||
|
except Exception as e:
|
||||||
|
fail_usage("Failed: %s" % e)
|
||||||
|
|
||||||
|
@@ -74,7 +73,7 @@
|
||||||
|
|
||||||
|
powerState = "unknown"
|
||||||
|
try:
|
||||||
|
- vmStatus = compute_client.virtual_machines.get(rgName, vmName, "instanceView")
|
||||||
|
+ vmStatus = azure_fence.get_vm_resource(compute_client, rgName, vmName)
|
||||||
|
except Exception as e:
|
||||||
|
fail_usage("Failed: %s" % e)
|
||||||
|
|
||||||
|
@@ -117,11 +116,10 @@
|
||||||
|
|
||||||
|
if (options["--action"]=="off"):
|
||||||
|
logging.info("Poweroff " + vmName + " in resource group " + rgName)
|
||||||
|
- compute_client.virtual_machines.power_off(rgName, vmName, skip_shutdown=True)
|
||||||
|
+ azure_fence.do_vm_power_off(compute_client, rgName, vmName, True)
|
||||||
|
elif (options["--action"]=="on"):
|
||||||
|
logging.info("Starting " + vmName + " in resource group " + rgName)
|
||||||
|
- compute_client.virtual_machines.start(rgName, vmName)
|
||||||
|
-
|
||||||
|
+ azure_fence.do_vm_start(compute_client, rgName, vmName)
|
||||||
|
|
||||||
|
def define_new_opts():
|
||||||
|
all_opt["resourceGroup"] = {
|
||||||
|
@@ -241,7 +239,7 @@
|
||||||
|
except ImportError:
|
||||||
|
fail_usage("Azure Resource Manager Python SDK not found or not accessible")
|
||||||
|
except Exception as e:
|
||||||
|
- fail_usage("Failed: %s" % re.sub("^, ", "", str(e)))
|
||||||
|
+ fail_usage("Failed: %s" % re.sub(r"^, ", r"", str(e)))
|
||||||
|
|
||||||
|
if "--network-fencing" in options:
|
||||||
|
# use off-action to quickly return off once network is fenced instead of
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user