# Copyright (C) 2013 Adam Stokes # # This file is part of the sos project: https://github.com/sosreport/sos # # This copyrighted material is made available to anyone wishing to use, # modify, copy, or redistribute it subject to the terms and conditions of # version 2 of the GNU General Public License. # # See the LICENSE file in the source distribution for further information. import glob import json import os from urllib.error import URLError from urllib.request import Request, urlopen from sos.report.plugins import Plugin, UbuntuPlugin, RedHatPlugin IMDS_URL = ("http://169.254.169.254/metadata/instance?" "api-version=2025-04-07&format=json") class Azure(Plugin, UbuntuPlugin): short_desc = 'Microsoft Azure client' plugin_name = 'azure' profiles = ('virt',) packages = ('WALinuxAgent',) def setup(self): self.add_copy_spec([ "/var/log/waagent*", "/var/lib/cloud", "/etc/default/kv-kvp-daemon-init", "/etc/waagent.conf", "/sys/module/hv_netvsc/parameters/ring_size", "/sys/module/hv_storvsc/parameters/storvsc_ringbuffer_size", "/var/lib/AzureEnhancedMonitor" ]) # Adds all files under /var/log/azure to the sos report # os.walk is used because /var/log/azure is used by multiple Azure # extensions and there is no standard log filename format limit = self.get_option("log_size") for path, _, files in os.walk("/var/log/azure"): for name in files: self.add_copy_spec(self.path_join(path, name), sizelimit=limit) def collect(self): with self.collection_file('instance_metadata.json') as mfile: try: metadata = self._get_imds_metadata() mfile.write(json.dumps(metadata, indent=4)) except RuntimeError as err: mfile.write(str(err)) @staticmethod def _get_imds_metadata(): """Retrieve instance metadata from the Azure IMDS endpoint.""" try: req = Request(IMDS_URL, headers={'Metadata': 'true'}) with urlopen(req, timeout=5) as resp: if resp.status != 200: raise RuntimeError( f"IMDS returned HTTP {resp.status}: " + resp.read().decode()) return json.loads(resp.read().decode()) except URLError as err: raise RuntimeError( "Failed to query Azure IMDS: " + str(err)) from err class RedHatAzure(Azure, RedHatPlugin): def setup(self): super().setup() # RHUI repo files vary by RHEL version and offering: # rh-cloud.repo (RHEL 7), rh-cloud-base.repo, rh-cloud-eus.repo, # rh-cloud-ha.repo, rh-cloud-sap-ha.repo, rh-cloud-arm64.repo, etc. rhui_repos = glob.glob('/etc/yum.repos.d/rh-cloud*.repo') if rhui_repos: # RHUI 1/2/3 are retired; Azure Global now uses RHUI 4 # https://learn.microsoft.com/en-us/azure/virtual-machines/ # workloads/redhat/redhat-rhui self.add_cmd_output( 'curl -s -m 5 -vvv https://rhui4-1.microsoft.com' ) # Collect any hardcoded RHUI entries in /etc/hosts self.add_cmd_output( 'grep -i rhui /etc/hosts', suggest_filename='rhui_etc_hosts' ) # Certificate filenames vary by RHEL version and offering: # content.crt, content-base.crt, content-eus.crt, # content-base-ha.crt, content-base-sap-ha.crt, etc. crt_dir = '/etc/pki/rhui/product' for crt_path in glob.glob(f'{crt_dir}/*.crt'): self.add_cmd_output( f'openssl x509 -noout -text -in {crt_path}' ) # vim: set et ts=4 sw=4 :