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 };
}