From 2d99d9492c9da6c8b7a946748aadeb1c74e8cd91 Mon Sep 17 00:00:00 2001 From: Jason Barnett Date: Wed, 9 Aug 2023 15:19:42 -0600 Subject: [PATCH] avoid using dmidecode I didn't see any reason to depend on root privileges for dmidecode when you can just fetch the data directly as an unprivileged user --- .../Scripts/nxOMSAutomationWorker.py | 10 +---- .../Scripts/nxOMSAutomationWorker.py | 10 +---- .../3.x/Scripts/nxOMSAutomationWorker.py | 19 +++------ .../3.x/scripts/onboarding3.py | 11 ++---- .../automationworker/3.x/worker/linuxutil.py | 39 ++++++++----------- .../automationworker/scripts/onboarding2.py | 10 ++--- .../automationworker/worker/linuxutil.py | 34 +++++++--------- 7 files changed, 47 insertions(+), 86 deletions(-) diff --git a/Providers/Scripts/2.4x-2.5x/Scripts/nxOMSAutomationWorker.py b/Providers/Scripts/2.4x-2.5x/Scripts/nxOMSAutomationWorker.py index ec4763e88..44a7cb5dc 100644 --- a/Providers/Scripts/2.4x-2.5x/Scripts/nxOMSAutomationWorker.py +++ b/Providers/Scripts/2.4x-2.5x/Scripts/nxOMSAutomationWorker.py @@ -347,15 +347,9 @@ def get_optional_metadata(): vm_id = unknown is_azure_vm = False try: - proc = subprocess.Popen(["sudo", "-u", AUTOMATION_USER, "python2", OMS_UTIL_FILE_PATH, "--dmidecode"], - stdout=subprocess.PIPE, stderr=subprocess.PIPE) - dmidecode, error = proc.communicate() - if proc.returncode != 0 or not dmidecode: - raise Exception("Unable to invoke omsutil.py --dmidecode: %s" % error) - is_azure_vm = linuxutil.is_azure_vm(dmidecode) - if is_azure_vm: + if linuxutil.is_azure_vm(): asset_tag = linuxutil.get_azure_vm_asset_tag() - vm_id = linuxutil.get_vm_unique_id_from_dmidecode(sys.byteorder, dmidecode) + vm_id = linuxutil.get_vm_unique_id() except Exception, e: log(INFO, "unable to get_optional_metadata: %s" % str(e)) diff --git a/Providers/Scripts/2.6x-2.7x/Scripts/nxOMSAutomationWorker.py b/Providers/Scripts/2.6x-2.7x/Scripts/nxOMSAutomationWorker.py index ec4763e88..44a7cb5dc 100644 --- a/Providers/Scripts/2.6x-2.7x/Scripts/nxOMSAutomationWorker.py +++ b/Providers/Scripts/2.6x-2.7x/Scripts/nxOMSAutomationWorker.py @@ -347,15 +347,9 @@ def get_optional_metadata(): vm_id = unknown is_azure_vm = False try: - proc = subprocess.Popen(["sudo", "-u", AUTOMATION_USER, "python2", OMS_UTIL_FILE_PATH, "--dmidecode"], - stdout=subprocess.PIPE, stderr=subprocess.PIPE) - dmidecode, error = proc.communicate() - if proc.returncode != 0 or not dmidecode: - raise Exception("Unable to invoke omsutil.py --dmidecode: %s" % error) - is_azure_vm = linuxutil.is_azure_vm(dmidecode) - if is_azure_vm: + if linuxutil.is_azure_vm(): asset_tag = linuxutil.get_azure_vm_asset_tag() - vm_id = linuxutil.get_vm_unique_id_from_dmidecode(sys.byteorder, dmidecode) + vm_id = linuxutil.get_vm_unique_id() except Exception, e: log(INFO, "unable to get_optional_metadata: %s" % str(e)) diff --git a/Providers/Scripts/3.x/Scripts/nxOMSAutomationWorker.py b/Providers/Scripts/3.x/Scripts/nxOMSAutomationWorker.py index 801bbfd5f..29393b269 100644 --- a/Providers/Scripts/3.x/Scripts/nxOMSAutomationWorker.py +++ b/Providers/Scripts/3.x/Scripts/nxOMSAutomationWorker.py @@ -124,10 +124,10 @@ def Set_Marshall(ResourceSettings): proxy_conf_path = PROXY_CONF_PATH_LEGACY workspace_id = settings.workspace_id.decode() if isinstance(settings.workspace_id, bytes) else settings.workspace_id - + agent_service_zone = settings.azure_dns_agent_svc_zone azure_dns_agent_svc_zone = agent_service_zone.decode() if isinstance(agent_service_zone, bytes) else agent_service_zone - + args = ["python3", REGISTRATION_FILE_PATH, "--register", "-w", workspace_id, "-a", agent_id, "-c", OMS_CERTIFICATE_PATH, "-k", OMS_CERT_KEY_PATH, "-f", WORKING_DIRECTORY_PATH, "-s", WORKER_STATE_DIR, "-e", azure_dns_agent_svc_zone, "-p", proxy_conf_path, "-g", @@ -364,16 +364,9 @@ def get_optional_metadata(): vm_id = unknown is_azure_vm = False try: - proc = subprocess.Popen(["sudo", "-u", AUTOMATION_USER, "python3", OMS_UTIL_FILE_PATH, "--dmidecode"], - stdout=subprocess.PIPE, stderr=subprocess.PIPE) - dmidecode, error = proc.communicate() - dmidecode = dmidecode.decode("utf-8") - if proc.returncode != 0 or not dmidecode: - raise Exception("Unable to invoke omsutil.py --dmidecode: %s" % error.decode()) - is_azure_vm = linuxutil.is_azure_vm(dmidecode) - if is_azure_vm: + if linuxutil.is_azure_vm(): asset_tag = linuxutil.get_azure_vm_asset_tag() - vm_id = linuxutil.get_vm_unique_id_from_dmidecode(sys.byteorder, dmidecode) + vm_id = linuxutil.get_vm_unique_id() except Exception as e: log(INFO, "unable to get_optional_metadata: %s" % str(e)) @@ -620,7 +613,7 @@ def config_file_to_kv_pair(filename): def start_worker_manager_process(workspace_id): """ Start the worker_manager_process - :param workspace_id: + :param workspace_id: :return: the pid of the worker manager process """ proc = subprocess.Popen(["sudo", "-u", AUTOMATION_USER, "python3", WORKER_MANAGER_START_PATH, OMS_CONF_FILE_PATH, @@ -843,4 +836,4 @@ def log(level, message): try: LG().Log(logging.getLevelName(level), message) except: - pass \ No newline at end of file + pass diff --git a/Providers/nxOMSAutomationWorker/automationworker/3.x/scripts/onboarding3.py b/Providers/nxOMSAutomationWorker/automationworker/3.x/scripts/onboarding3.py index 5557c4577..6be02a636 100644 --- a/Providers/nxOMSAutomationWorker/automationworker/3.x/scripts/onboarding3.py +++ b/Providers/nxOMSAutomationWorker/automationworker/3.x/scripts/onboarding3.py @@ -94,7 +94,7 @@ def generate_hmac(str_to_sign, secret): secret = secret.encode('utf-8') cmd = ['echo -n "' + str(message.decode("utf-8")) + '" | openssl dgst -sha256 -binary -hmac "' + str(secret.decode("utf-8")) + '"'] process, signed_message, error = linuxutil.popen_communicate(cmd, shell=True) - + error = error.decode() if isinstance(error, bytes) else error if process.returncode != 0: raise Exception("Unable to generate signature. " + str(error)) @@ -266,17 +266,15 @@ def register(options): vm_id = unknown is_azure_vm = False try: - dmidecode = invoke_dmidecode() - is_azure_vm = linuxutil.is_azure_vm(dmidecode) - if is_azure_vm: + if linuxutil.is_azure_vm(): asset_tag = linuxutil.get_azure_vm_asset_tag() else: asset_tag = False - vm_id = linuxutil.get_vm_unique_id_from_dmidecode(sys.byteorder, dmidecode) + vm_id = linuxutil.get_vm_unique_id() except Exception as e: print (str(e)) pass - + # generate payload for registration request date = datetime.datetime.utcnow().isoformat() + "0-00:00" payload = {'RunbookWorkerGroup': hybrid_worker_group_name, @@ -425,4 +423,3 @@ def environment_prerequisite_validation(): nxautomation_group_name = "nxautomation" if linuxutil.is_existing_group(omiusers_group_name) is False: raise Exception("Missing group : " + nxautomation_group_name + ".") - diff --git a/Providers/nxOMSAutomationWorker/automationworker/3.x/worker/linuxutil.py b/Providers/nxOMSAutomationWorker/automationworker/3.x/worker/linuxutil.py index 537f308ad..41276d2d3 100644 --- a/Providers/nxOMSAutomationWorker/automationworker/3.x/worker/linuxutil.py +++ b/Providers/nxOMSAutomationWorker/automationworker/3.x/worker/linuxutil.py @@ -90,41 +90,34 @@ def get_azure_vm_asset_tag(): return "7783-7084-3265-9085-8269-3286-77" -def is_azure_vm(dmidecode_output): - """Detects azure vm from dmidecode output. - +def is_azure_vm(): + """Detects azure vm from /sys/devices/virtual/dmi/id/chassis_asset_tag. Note : is an asset tag "7783-7084-3265-9085-8269-3286-77" is present then this is an azure vm. - Returns: bool, true if the host is an azure vm. """ - #print("linux util dmidecode : "+ str(dmidecode_output)) - asset_tags = re.findall(get_azure_vm_asset_tag(), dmidecode_output) - - for tag in asset_tags: - if get_azure_vm_asset_tag() in tag: - return True - - return False + try: + with open('/sys/devices/virtual/dmi/id/chassis_asset_tag', 'r') as file: + return file.read().strip() == get_azure_vm_asset_tag() + except (FileNotFoundError, PermissionError): + print("File not found or permission denied") + return False -def get_vm_unique_id_from_dmidecode(byteorder, dmidecode_output): +def get_vm_unique_id(): """Extract the host UUID from dmidecode output. Returns: string, the host UUID. """ - uuid_prefix = "UUID: " - uuids = re.findall(uuid_prefix + "[A-Z0-9]{8}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{12}", - dmidecode_output.upper()) - if len(uuids) < 1: + try: + with open('/sys/devices/virtual/dmi/id/product_uuid', 'r') as file: + uuid = file.read().strip().lower() + except (FileNotFoundError, PermissionError): raise Exception("No host UUID found.") - # if multiple UUIDs are found take the first one - uuid = uuids[0].split(uuid_prefix)[1].strip() - # azure uuids are big endian - if byteorder == "big": + if sys.byteorder == "big": return uuid uuid_part = uuid.split("-") @@ -139,8 +132,8 @@ def get_vm_unique_id_from_dmidecode(byteorder, dmidecode_output): def convert_to_big_endian(little_endian_value): """Converts the little endian representation of the value into a big endian representation of the value""" """ - Little and big endian are two ways of storing multibyte data-types ( int, float, etc). - In little endian machines, last byte of binary representation of the multibyte data-type is stored first. + Little and big endian are two ways of storing multibyte data-types ( int, float, etc). + In little endian machines, last byte of binary representation of the multibyte data-type is stored first. On the other hand, in big endian machines, first byte of binary representation of the multibyte data-type is stored first. """ codecs_decoded = codecs.decode(little_endian_value, "hex") diff --git a/Providers/nxOMSAutomationWorker/automationworker/scripts/onboarding2.py b/Providers/nxOMSAutomationWorker/automationworker/scripts/onboarding2.py index cb09ff307..090173b14 100644 --- a/Providers/nxOMSAutomationWorker/automationworker/scripts/onboarding2.py +++ b/Providers/nxOMSAutomationWorker/automationworker/scripts/onboarding2.py @@ -246,7 +246,7 @@ def register(options): if os.path.isdir(DIY_STATE_PATH) is False: try: os.makedirs(DIY_STATE_PATH) - except Exception, ex: + except Exception, ex: print("Registration unsuccessful.") print("Cannot create directory for certs/conf. Because of the following exception : " + str(ex)) return @@ -259,13 +259,11 @@ def register(options): vm_id = unknown is_azure_vm = False try: - dmidecode = invoke_dmidecode() - is_azure_vm = linuxutil.is_azure_vm(dmidecode) - if is_azure_vm: + if linuxutil.is_azure_vm(): asset_tag = linuxutil.get_azure_vm_asset_tag() else: asset_tag = False - vm_id = linuxutil.get_vm_unique_id_from_dmidecode(sys.byteorder, dmidecode) + vm_id = linuxutil.get_vm_unique_id() except Exception, e: print str(e) pass @@ -421,5 +419,3 @@ def environment_prerequisite_validation(): nxautomation_group_name = "nxautomation" if linuxutil.is_existing_group(omiusers_group_name) is False: raise Exception("Missing group : " + nxautomation_group_name + ".") - - diff --git a/Providers/nxOMSAutomationWorker/automationworker/worker/linuxutil.py b/Providers/nxOMSAutomationWorker/automationworker/worker/linuxutil.py index 3699cccf5..f36f8e34a 100644 --- a/Providers/nxOMSAutomationWorker/automationworker/worker/linuxutil.py +++ b/Providers/nxOMSAutomationWorker/automationworker/worker/linuxutil.py @@ -87,40 +87,34 @@ def get_azure_vm_asset_tag(): return "7783-7084-3265-9085-8269-3286-77" -def is_azure_vm(dmidecode_output): - """Detects azure vm from dmidecode output. - +def is_azure_vm(): + """Detects azure vm from /sys/devices/virtual/dmi/id/chassis_asset_tag. Note : is an asset tag "7783-7084-3265-9085-8269-3286-77" is present then this is an azure vm. - Returns: bool, true if the host is an azure vm. """ - asset_tags = re.findall(get_azure_vm_asset_tag(), dmidecode_output) - - for tag in asset_tags: - if get_azure_vm_asset_tag() in tag: - return True - - return False + try: + with open('/sys/devices/virtual/dmi/id/chassis_asset_tag', 'r') as file: + return file.read().strip() == get_azure_vm_asset_tag() + except (FileNotFoundError, PermissionError): + print("File not found or permission denied") + return False -def get_vm_unique_id_from_dmidecode(byteorder, dmidecode_output): +def get_vm_unique_id(): """Extract the host UUID from dmidecode output. Returns: string, the host UUID. """ - uuid_prefix = "UUID: " - uuids = re.findall(uuid_prefix + "[A-Z0-9]{8}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{12}", - dmidecode_output.upper()) - if len(uuids) < 1: + try: + with open('/sys/devices/virtual/dmi/id/product_uuid', 'r') as file: + uuid = file.read().strip().lower() + except (FileNotFoundError, PermissionError): raise Exception("No host UUID found.") - # if multiple UUIDs are found take the first one - uuid = uuids[0].split(uuid_prefix)[1].strip() - # azure uuids are big endian - if byteorder == "big": + if sys.byteorder == "big": return uuid uuid_part = uuid.split("-")