Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix: Determine Virtual Machine UUID (VMware) #18921

Closed

Conversation

eduardomozart
Copy link
Contributor

@eduardomozart eduardomozart commented Feb 5, 2025

Checklist before requesting a review

Please delete options that are not relevant.

  • I have read the CONTRIBUTING document.
  • I have performed a self-review of my code.
  • I have added tests that prove my fix is effective or that my feature works.
  • This change requires a documentation update.

Description

  • It fixes # (issue number, if applicable)
  • Here is a brief description of what this PR does

There's a known bug on VMware UUID retrieve (as seen in glpi-project/glpi-agent#839 (comment)) when "Create components for virtual machines" is enabled. This PR makes sure that if multiple Computers with same UUID is found, retrieve only the only gathered by ESX remote task.

Screenshots (if appropriate):

Here's the screenshot of "Virtualization" tab of an ESX host WITHOUT this PR applied:

Image

Inventory file of the ESX host:

server02-with-glpi-agent.json
esxi01.json
server02-agentless-esx-inventory.json

@eduardomozart
Copy link
Contributor Author

Hello @cedric-anne, I've updated this PR, please take a look. Thank you.

@stonebuzz
Copy link
Contributor

I do not reproduce with related inventory file

image

can you check whether you have the corresponding PC both in the recycle bin and in GLPI?

Copy link
Member

@cedric-anne cedric-anne left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems correct to me.

However, dealing with lack of uniqueness of UUIDs is pretty weird. IMHO, the uuid field should have a unique key, but it is ou of the scope of the current PR.

@eduardomozart
Copy link
Contributor Author

Hello @stonebuzz, I've updated the main thread to include all the inventory files needed to reproduce this issue. Please make sure to check "Create computer for virtual machines" chebox in Administration > Inventory and import the *.json files into the order of this PR. Please make sure that those assets do not exists on your DB (exclude the Computer assets and all related devices first).
image

@stonebuzz
Copy link
Contributor

I have reproduced the issue, but I believe the problem does not lie here; rather, it is within the reconciliation engine, specifically in the rules that utilize the UUID.

Currently, in the processing of virtual machines, GLPI attempts to locate the corresponding PC (whether created via ESX, an agent, etc.) using its UUID. We have a dedicated function to handle special cases, particularly issues related to dmidecode versions earlier than 2.10.

This function, located in ComputervirtualMachine.php, is as follows:

public static function getUUIDRestrictCriteria($uuid)
{
    // More information about UUIDs can be found on Wikipedia:
    // https://en.wikipedia.org/wiki/Universally_unique_identifier
    // Some UUIDs are not compliant, requiring preprocessing.
    // A valid UUID looks like: 550e8400-e29b-41d4-a716-446655440000

    // Case 1: Some UUIDs may appear as:
    // 56 4d 77 d0 6b ef 3d da-4d 67 5c 80 a9 52 e2 c9
    $pattern  = "/([\w]{2})\ ([\w]{2})\ ([\w]{2})\ ([\w]{2})\ ";
    $pattern .= "([\w]{2})\ ([\w]{2})\ ([\w]{2})\ ([\w]{2})-";
    $pattern .= "([\w]{2})\ ([\w]{2})\ ([\w]{2})\ ([\w]{2})\ ";
    $pattern .= "([\w]{2})\ ([\w]{2})\ ([\w]{2})\ ([\w]{2})/";

    if (preg_match($pattern, $uuid)) {
        $uuid = preg_replace($pattern, "$1$2$3$4-$5$6-$7$8-$9$10-$11$12$13$14$15$16", $uuid);
    }

    // Case 2: This correction is required due to a known bug in dmidecode < 2.10.
    // On Unix, the first block of the UUID is flipped, while on Windows, the first three blocks are flipped.
    $in = [strtolower($uuid)];
    $regexes = [
        "/([\w]{2})([\w]{2})([\w]{2})([\w]{2})(.*)/"                                        => "$4$3$2$1$5",
        "/([\w]{2})([\w]{2})([\w]{2})([\w]{2})-([\w]{2})([\w]{2})-([\w]{2})([\w]{2})(.*)/"  => "$4$3$2$1-$6$5-$8$7$9"
    ];
    
    foreach ($regexes as $pattern => $replace) {
        $reverse_uuid = preg_replace($pattern, $replace, $uuid);
        if ($reverse_uuid) {
            $in[] = strtolower($reverse_uuid);
        }
    }

    return Sanitizer::sanitize($in);
}

This method, used by the native inventory during virtual machine processing, should also be integrated into the reconciliation rules.

Currently, with the provided files, GLPI incorrectly creates a new PC for both server02-with-glpi-agent.json and server02-agentless-esx-inventory.json, whereas it should recognize them as the same machine. The serial + UUID rule should be able to correctly match the existing PC, but it does not use the method that processes and normalizes UUIDs.

See this-> #18929

@eduardomozart
Copy link
Contributor Author

Closed as of #18929.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants