async function getAzureServiceResourceTypes()

in src/tree/azureResourceNodeContributor.ts [67:142]


async function getAzureServiceResourceTypes(kubectl: k8s.KubectlV1): Promise<Errorable<CustomResource[]>> {
    // Some kubectl versions discard everything after a null/missing value within a jsonpath `range`,
    // meaning trailing newlines get omitted from the output and we can't split lines correctly.
    // For this reason, we make the newline the *first* component of the range, and ensure the value
    // which might be null (shortNames[0] in this case) is right at the end.
    // This means we end up with a blank line at the start of the output, but it's otherwise consistent.
    const command = `get crd -o jsonpath="{range .items[*]}{\\"\\n\\"}{.metadata.name}{\\" \\"}{.spec.names.kind}{\\" \\"}{.spec.names.singular}{\\" \\"}{.spec.names.plural}{\\" \\"}{.spec.group}{\\" \\"}{.spec.names.shortNames[0]}{end}"`;
    const crdShellResult = await kubectl.invokeCommand(command);
    if (crdShellResult === undefined) {
        return { succeeded: false, error: `Failed to run kubectl command: ${command}` };
    }

    if (crdShellResult.code !== 0) {
        return {
            succeeded: false,
            error: `Kubectl returned error ${crdShellResult.code} for ${command}\nError: ${crdShellResult.stderr}`,
        };
    }

    const lines = crdShellResult.stdout.split("\n").filter((l) => l.length > 0);

    const customResources = lines.map((line) => {
        const parts = line.split(" ");
        const metadataName = parts[0];
        const kind = parts[1];
        const singularName = parts[2];
        const pluralName = parts[3];
        const groupURL = parts[4];
        const shortName = parts[5];
        const abbreviation = shortName || metadataName;
        return {
            name: metadataName,
            displayName: singularName,
            pluralDisplayName: pluralName,
            manifestKind: kind,
            group: groupURL,
            abbreviation,
        };
    });

    const approvedGroups: Set<string> = new Set([
        "servicebus.azure.com",
        "insights.azure.com",
        "compute.azure.com",
        "cdn.azure.com",
        "dbforpostgresql.azure.com",
        "keyvault.azure.com",
        "eventgrid.azure.com",
        "cache.azure.com",
        "containerinstance.azure.com",
        "eventhub.azure.com",
        "sql.azure.com",
        "network.azure.com",
        "operationalinsights.azure.com",
        "resources.azure.com",
        "managedidentity.azure.com",
        "storage.azure.com",
        "machinelearningservices.azure.com",
        "signalrservice.azure.com",
        "batch.azure.com",
        "dbformysql.azure.com",
        "subscription.azure.com",
        "appconfiguration.azure.com",
        "containerservice.azure.com",
        "dbformariadb.azure.com",
        "web.azure.com",
        "authorization.azure.com",
        "synapse.azure.com",
        "containerregistry.azure.com",
        "documentdb.azure.com",
    ]);

    // Filter the custom resources to only include Azure resources
    const azureResources = customResources.filter((r) => approvedGroups.has(r.group));
    return { succeeded: true, result: azureResources };
}