diff --git a/RHEL-76492-fence_azure_arm-use-azure-identity.patch b/RHEL-76492-fence_azure_arm-use-azure-identity.patch new file mode 100644 index 0000000..d42847d --- /dev/null +++ b/RHEL-76492-fence_azure_arm-use-azure-identity.patch @@ -0,0 +1,381 @@ +--- a/lib/azure_fence.py.py 2025-01-28 11:38:59.877243912 +0100 ++++ b/lib/azure_fence.py.py 2025-01-28 09:54:15.746703761 +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(identity_config={"resource_id": cloud_environment["resource_manager"]}) ++ except ImportError: ++ from msrestazure.azure_active_directory import MSIAuthentication ++ credentials = MSIAuthentication(cloud_environment=cloud_environment["cloud_environment"]) ++ return ++ ++ 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-28 11:38:59.880243982 +0100 ++++ b/agents/azure_arm/fence_azure_arm.py 2025-01-28 11:43:16.290189381 +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 diff --git a/fence-agents.spec b/fence-agents.spec index acbb0d5..72f02f2 100644 --- a/fence-agents.spec +++ b/fence-agents.spec @@ -87,7 +87,7 @@ Name: fence-agents Summary: Set of unified programs capable of host isolation ("fencing") Version: 4.2.1 -Release: 129%{?alphatag:.%{alphatag}}%{?dist}.5 +Release: 129%{?alphatag:.%{alphatag}}%{?dist}.6 License: GPLv2+ and LGPLv2+ Group: System Environment/Base URL: https://github.com/ClusterLabs/fence-agents @@ -133,10 +133,40 @@ Source30: %{reqstsoauthlib}-%{reqstsoauthlib_version}.tar.gz Source31: %{oauthlib}-%{oauthlib_version}.tar.gz Source32: %{ruamelyaml}-%{ruamelyaml_version}.tar.gz Source33: %{setuptools}-%{setuptools_version}.tar.gz +# azure +Source34: requirements-azure.txt +Source35: azure-common-1.1.28.zip +Source36: azure-core-1.24.2.zip +Source37: azure-mgmt-compute-27.2.0.zip +Source38: azure-mgmt-core-1.3.2.zip +Source39: azure-mgmt-network-20.0.0.zip +Source40: azure-identity-1.10.0.zip +Source41: isodate-0.6.1.tar.gz +Source42: msrest-0.7.1.zip +Source43: oauthlib-3.2.2.tar.gz +Source44: PyJWT-2.4.0.tar.gz +Source45: requests-2.27.1.tar.gz +Source46: requests-oauthlib-2.0.0.tar.gz +Source47: msal-1.27.0.tar.gz +Source48: msal-extensions-1.0.0.tar.gz +Source49: portalocker-2.7.0.tar.gz +Source50: cryptography-3.3.2.tar.gz +Source51: cffi-1.15.1.tar.gz +Source52: typing_extensions-4.1.1.tar.gz +## msrestazure specific +Source54: msrestazure-0.6.4.tar.gz +Source55: adal-1.2.7.tar.gz ## required for installation -Source34: setuptools_scm-6.3.2.tar.gz -Source35: packaging-21.2-py3-none-any.whl -Source36: tomli-1.0.1.tar.gz +Source100: setuptools_scm-6.4.2.tar.gz +Source101: packaging-21.2-py3-none-any.whl +Source102: tomli-1.1.0.tar.gz +Source103: pycparser-2.20.tar.gz +Source104: wheel-0.37.1.tar.gz +Source105: pip-21.3.1.tar.gz +## azure +Source106: flit_core-3.10.1.tar.gz +## msrestazure +Source107: poetry-core-1.0.8.tar.gz ### END Patch0: fence_impilan-fence_ilo_ssh-add-ilo5-support.patch @@ -284,6 +314,7 @@ Patch141: RHEL-5397-4-fence_scsi-log-err.patch Patch142: RHEL-14343-fence_zvmip-2-fix-manpage-formatting.patch Patch143: RHEL-7734-fence_eps-add-fence_epsr2-for-ePowerSwitch-R2-and-newer.patch Patch144: RHEL-56840-fence_scsi-only-preempt-once-for-mpath-devices.patch +Patch145: RHEL-76492-fence_azure_arm-use-azure-identity.patch ### HA support libs/utils ### # all archs @@ -360,7 +391,7 @@ BuildRequires: libxslt ## establishing proper paths to particular programs BuildRequires: gnutls-utils ## Python dependencies -BuildRequires: python3-devel +BuildRequires: python3-devel python3-pycparser libffi-devel openssl-devel BuildRequires: python3-pexpect python3-pycurl python3-requests BuildRequires: python3-suds openwsman-python3 python3-boto3 BuildRequires: python3-google-api-client python3-pip python3-wheel python3-jinja2 @@ -517,6 +548,7 @@ BuildRequires: python3-google-api-client python3-pip python3-wheel python3-jinja %patch -p1 -P 142 %patch -p1 -P 143 -F1 %patch -p1 -P 144 +%patch -p1 -P 145 # prevent compilation of something that won't get used anyway sed -i.orig 's|FENCE_ZVM=1|FENCE_ZVM=0|' configure.ac @@ -616,17 +648,22 @@ popd # aws/kubevirt %{__python3} -m pip install --user --no-index --find-links %{_sourcedir} setuptools-scm -# aws -%ifarch x86_64 -%{__python3} -m pip install --user --no-index --find-links %{_sourcedir} jmespath -%{__python3} -m pip install --target %{buildroot}/usr/lib/fence-agents/%{bundled_lib_dir}/aws --no-index --find-links %{_sourcedir} botocore -%{__python3} -m pip install --target %{buildroot}/usr/lib/fence-agents/%{bundled_lib_dir}/aws --no-index --find-links %{_sourcedir} requests -%endif - # kubevirt %{__python3} -m pip install --target %{buildroot}/usr/lib/fence-agents/%{bundled_lib_dir}/kubevirt --no-index --find-links %{_sourcedir} openshift rm -rf %{buildroot}/usr/lib/fence-agents/%{bundled_lib_dir}/kubevirt/rsa* +%ifarch x86_64 +# aws +%{__python3} -m pip install --user --no-index --find-links %{_sourcedir} jmespath +%{__python3} -m pip install --target %{buildroot}/usr/lib/fence-agents/%{bundled_lib_dir}/aws --no-index --find-links %{_sourcedir} botocore +%{__python3} -m pip install --target %{buildroot}/usr/lib/fence-agents/%{bundled_lib_dir}/aws --no-index --find-links %{_sourcedir} requests + +# azure +%{__python3} -m pip install --user --upgrade --no-index --find-links %{_sourcedir} pip setuptools + +%{__python3} -m pip install --target %{buildroot}/usr/lib/fence-agents/%{bundled_lib_dir}/azure --no-index --find-links %{_sourcedir} -r %{_sourcedir}/requirements-azure.txt +%endif + # regular patch doesnt work in build-section pushd %{buildroot}/usr/lib/fence-agents/%{bundled_lib_dir} /usr/bin/patch --no-backup-if-mismatch -p1 --fuzz=0 < %{PATCH1000} @@ -822,13 +859,41 @@ Fence agent for Amazon AWS instances. %ifarch x86_64 %package azure-arm -License: GPLv2+ and LGPLv2+ +License: GPLv2+ and LGPLv2+ and MIT and MPL-2.0 and Apache-2.0 and BSD and PSF-2.0 and BSD-3-Clause and ISC Group: System Environment/Base Summary: Fence agent for Azure Resource Manager Requires: fence-agents-common >= %{version}-%{release} -Requires: python3-azure-sdk >= 4.0.0-9 +# azure +Provides: bundled(python3-adal) = 1.2.7 +Provides: bundled(python3-azure-common) = 1.1.28 +Provides: bundled(python3-azure-core) = 1.24.2 +Provides: bundled(python3-azure-identity) = 1.10.0 +Provides: bundled(python3-azure-mgmt-compute) = 27.2.0 +Provides: bundled(python3-azure-mgmt-core) = 1.3.2 +Provides: bundled(python3-azure-mgmt-network) = 20.0.0 +Provides: bundled(python3-certifi) = 2023.7.22 +Provides: bundled(python3-cffi) = 1.15.1 +Provides: bundled(python3-charset-normalizer) = 2.0.7 +Provides: bundled(python3-cryptography) = 3.3.2 +Provides: bundled(python3-%{dateutil}) = %{dateutil_version} +Provides: bundled(python3-%{idna}) = %{idna_version} +Provides: bundled(python3-isodate) = 0.6.1 +Provides: bundled(python3-msal) = 1.27.0 +Provides: bundled(python3-msal-extensions) = 1.0.0 +Provides: bundled(python3-msrest) = 0.7.1 +Provides: bundled(python3-msrestazure) = 0.6.4 +Provides: bundled(python3-oauthlib) = 3.2.2 +Provides: bundled(python3-portalocker) = 2.7.0 +Provides: bundled(python3-pycparser) = 2.20 +Provides: bundled(python3-PyJWT) = 2.4.0 +Provides: bundled(python3-requests) = 2.27.1 +Provides: bundled(python3-requests-oauthlib) = 2.0.0 +Provides: bundled(python3-six) = 1.16.0 +Provides: bundled(python3-typing-extensions) = 4.1.1 +Provides: bundled(python3-urllib3) = 1.26.18 Obsoletes: %{name} < %{version}-%{release} -BuildArch: noarch +Provides: python3-azure-sdk = 4.0.0-10 +Obsoletes: python3-azure-sdk < 4.0.0-10 %description azure-arm Fence agent for Azure Resource Manager instances. %files azure-arm @@ -836,6 +901,8 @@ Fence agent for Azure Resource Manager instances. %{_datadir}/fence/azure_fence.py* %{_datadir}/fence/__pycache__/azure_fence.* %{_mandir}/man8/fence_azure_arm.8* +# bundled libraries +/usr/lib/fence-agents/%{bundled_lib_dir}/azure %endif %package bladecenter @@ -1528,6 +1595,11 @@ Fence agent for IBM z/VM over IP. %endif %changelog +* Wed Jan 29 2025 Oyvind Albrigtsen - 4.2.1-129.6 +- fence_azure_arm: use azure-identity instead of msrestazure, which has + been deprecated + Resolves: RHEL-76492 + * Tue Sep 24 2024 Oyvind Albrigtsen - 4.2.1-129.5 - fence_scsi: preempt clears all devices on the mpath device, so only run it for the first device diff --git a/sources b/sources index 55be67a..9760fb7 100644 --- a/sources +++ b/sources @@ -30,8 +30,34 @@ SHA512 (rsa-4.7.2.tar.gz) = 63f561774dbaa10511167cba31e0f852e32b3250f2803edaa272 SHA512 (ruamel.yaml-0.17.16.tar.gz) = 61780127c23a2fa20c6ce29b27790b72538b5ea0370906d38f4cfe760c30a3756022a385d3f241dd88199358ff152d624dc372fbe7e1fd6d2959f873daf1263d SHA512 (ruamel.yaml.clib-0.2.6.tar.gz) = 12307a3c3bae09cf65d9672894c9a869a7ed5483ca3afb9ee39d8bcbf1948b012a0dbf570e315cc8b9a8b55184de9e10324953ec4819d214379e01522ee13b20 SHA512 (setuptools-58.3.0.tar.gz) = 5a38231c2ce361ad45befbd0de34dd7dde9d15f25e7fe2b8cf595d43eeee86fb3c2400e5b2676b547a025217aad85e63b1db6d9778baa412eefb25b22170c587 -SHA512 (setuptools_scm-6.3.2.tar.gz) = 9a16552803ef92367ad71007cf322737b5baa58b924083f04c860875bf6cb2e2bb4f43a7f89778b040c2eb55c5d32de479a918056519339820c6d0f1a6a386f0 +SHA512 (setuptools_scm-6.4.2.tar.gz) = 224dfe543e8658e7d8b7272d18eb657fac1774a206d079d65bb6e22bfa68b35e618a31b3671418d095f8b7b492339ea18491a1711be3a87eeecf50c6703a4096 SHA512 (six-1.16.0.tar.gz) = 076fe31c8f03b0b52ff44346759c7dc8317da0972403b84dfe5898179f55acdba6c78827e0f8a53ff20afe8b76432c6fe0d655a75c24259d9acbaa4d9e8015c0 -SHA512 (tomli-1.0.1.tar.gz) = 2731ff827bda17471bf75a44b445062bd4c43adfc9f0fdab4f8953e559f60708bc3e3500b424bf914c5e472fc9afbab72316c5a3b47c3a7654b2eb5343e62d21 +SHA512 (tomli-1.1.0.tar.gz) = d30bca3e2341d50f5dca29e101a0c9d32214e33b3154a71bebe31a38aee51977681ea6757ed9f1bd39c302f093073b589fe35c801512b0e6bb92a2dc6a783d62 SHA512 (urllib3-1.26.18.tar.gz) = c89e93a032bf6b11375c06ef7c5abc1868f93e7655cfdca09e9bd939ad415d206ea159fe151ecd2e5f725e0e18a831c7a5382ad01dbc32264154fc8af7aec156 SHA512 (websocket-client-1.2.1.tar.gz) = fdbeb7ac2add27478a17b388ac62e9378094a368f29749d8b63c274ee41836506369dddd083956f42f1f2d74948392b3ddd59b801c98f9e028c126bdb54c636b +SHA512 (requirements-azure.txt) = 8071c96bb3e2b82852b10fd68b77b69a7fce6153ab315298ceb07456fe66f3aca056d3273f11eb87ff30049759e8b4fddf62e39acb91953d36e933e44dce8c9b +SHA512 (azure-common-1.1.28.zip) = cfa8d08e11ff7d855342a589f9780ba1b2386fd63cddcbcc04d83be8d4d8e41dceba494b617e27ed4e3da4366b9f1203819ec391ef4466a6700cc2c8b85f0c38 +SHA512 (azure-core-1.24.2.zip) = 1c4a865a2e3c2f83a9ced54da258fbf034166796724824dcdd80b2fd75e902c3b87c9860de441e5047a9acf13396f170ea9e663aced2adf0dae28a970a8ba89f +SHA512 (azure-mgmt-compute-27.2.0.zip) = c0c3dc5a3c9dcc93aa67fc9ca6a03bee048c8e857fd2d746e55f6026056817c77d6aec8676ab771e7e40ff921edaa5b74cbc3eb2fa612288d65a75866eefccbd +SHA512 (azure-mgmt-core-1.3.2.zip) = d984448e63ac33eda768b07d69fbdde1dcfb106f26949f0fa56ccc36bf48a7112e5126008280eba40724121bab5c05cb0e08d6d3302109b3381b580a795300eb +SHA512 (azure-mgmt-network-20.0.0.zip) = 75869f1f01bdf289afbeb70c3e73677d0618256ad4fecf7ee88bcb26434c9f15e3a1d071858f7c8c7de218942d284206a84117638f5f47eac195c49fbe9e4496 +SHA512 (azure-identity-1.10.0.zip) = 66551765ac0a4d43dc95cb755be3bfc31e2e7afa7eebf72c061c6c7d1dd0cf88988d88a39c2c1463fe27caced7ccd72da6520a9e977bfed0ee5f495fe00fab6a +SHA512 (isodate-0.6.1.tar.gz) = 437e420ec7ee68dedded825f30d3289eeb0da526208443e5a8e50fe70f12309515e1285b21132d26e6d4c1683f90dfa1d401582042b5e4381fe7ab0e34af26b6 +SHA512 (msrest-0.7.1.zip) = 430e982adf89c79356e59182587c62ecb935e983f2e339738b54c48d0cd3cfa66ab48aad52d342b3efe5938d5e02693f24d603a4d637e3e5818bac6d03cc19db +SHA512 (oauthlib-3.2.2.tar.gz) = c147b96e0ab0d1a8845f525e80831cfd04495134dd1f17fd95eac62f3a95c91e6dca9d38e34206537d77f3c12dd5b553252239318ba39546979c350e96536b8b +SHA512 (PyJWT-2.4.0.tar.gz) = 6c60afe62f9341c0fd889be227cd9e44260bc88696a93d0c3398547e159001f04e402d207d2230641f0f3d37cfd7e6f9e50a42dadfb011d7087c32a864c792a4 +SHA512 (requests-2.27.1.tar.gz) = e51916abea8125254c5ee72c97e84a73e6981cab09961486873387522d2ce041ee3fe8fa2ff0b9bbe6707eefdc05145e9adcf127bcd999dea127acdfabd5312f +SHA512 (requests-oauthlib-2.0.0.tar.gz) = f15851aa27a19053c1bd6ccc7e1fcbc24b5c9e3e4ced736754e34ff8121a3d9be9f4f9ff878cbd2a75ca5803e25522807b4ace19cb0f64a88844158fdf7d098f +SHA512 (msal-1.27.0.tar.gz) = 9dbd023b36705129d562768fda71f05149205c837e1b073e2f8d2831c435a85c804ab4dec4b8526ddb141cd09ea9447488c77f5c2918c1103cd67b7c942d96b8 +SHA512 (msal-extensions-1.0.0.tar.gz) = 5dc22a64a535ac9c7488d0d1e85e2f8320cb5c9e4cb5891599c8fc07060ff1eac310fe93ef42416142600ade8666ac4f0a3614a3e81950311f6d752cac5de959 +SHA512 (portalocker-2.7.0.tar.gz) = 9f6dc31fda36f2fcc7088134b5249c6ec4a92a1fa2e85bf55c700469f183d29ed1a1bd522b65909844c85dfe6872d83809d21b78dc89886533db2692cc709ed2 +SHA512 (cryptography-3.3.2.tar.gz) = 55f6ee13342b3209b1fcb310f4c4d33d22856ee785cb2347e6ad36c34e9b42f6e0d5bece8e458b09663a5b78e34c4567fe7a211b51ca71f55ccc93e3f62dc5e4 +SHA512 (cffi-1.15.1.tar.gz) = e99cafcb029076abc29e435b490fa0573ee2856f4051b7ca8a5b38cd125d56dd9dae8b189f59ceb3d728a675da8ee83239e09e19f8b0feeddea4b186ab5173a5 +SHA512 (typing_extensions-4.1.1.tar.gz) = 7f05952fe12fcacbe9226524816657cf7f433a56f30629a9f2c8565b5f7d392a4a9d64a9f7f9d16b0405d3a511f85ab3ac56cb629466412e65ef683a87a1b441 +SHA512 (msrestazure-0.6.4.tar.gz) = a3a652a47b5a08a72fb07882286ac20a209afcb18be1159e7036dab255ba056ec05c444275c505ee9055f948109b3027bc0ca468abf8b9e41a7edf56c35d2de2 +SHA512 (adal-1.2.7.tar.gz) = b46dd3ebb72123e9c2d2eb75eae17b1175f09908b44430131251b0deb0f96f4f3646aa5c0553894c89e664d448ad90bf7436a0a48e18b6a2eff491dad3d8a8a8 +SHA512 (poetry-core-1.0.8.tar.gz) = d00925acb1aa3bcbe65e83855706cc983ad4174c838df380e517c41b81c466333eb98946971c80723c6c91f2d7488780bdc6088dc6daacb3c5cc36f1a4611db5 +SHA512 (pycparser-2.20.tar.gz) = ff0853c9f981b43b4f2e879350715c07b02cf9dab223d4980d8fe0a3138c98041b5f848a9355ae4f1cb45e7f137c03a88843008e18d77af9250e0d9c55f5ca1b +SHA512 (wheel-0.37.1.tar.gz) = c977a740c17abd1fa4b4c2382a33f3ff887baa4231c36990d988cb8531496074e39744786ef6ac0da9c9af4977bce5b2da145377a3ac15eea918f8125bff66ec +SHA512 (pip-21.3.1.tar.gz) = cc8cb13a7f4f53ddcaa1bf10586d0caa51bc334728bbd664f7085b3bfbfd09d082c2f01f4d1ecd6a69d7228976058a965087f1852da6d1155526fac1f107bf13 +SHA512 (flit_core-3.10.1.tar.gz) = ac0d39b6ee35b553fc8f7f3f6e558fdc32714ed64d6c506da7913ef95d00780b5f86894d9b042f32cdc51d38ec515fa02f1154b0edbc81d8e53475788c444b08