pulumi-kubernetes
pulumi-kubernetes copied to clipboard
Helm chart v4: no more getResource & how to use chart.resources
Hi,
When transitioning from Helm chart v3 to helm chart v4, we loose access to getResource.
The docs surrounding the resources output of helm chart v4 are very bare: resources any[] Resources created by the Chart..
From https://github.com/pulumi/pulumi-kubernetes/issues/3110#issuecomment-2393940142:
Wanted to wonder if there's any guidelines on how to manage outputs better with the v4 Chart? The v3 chart had
getResourcetyped API which was very helpful.
From the docs it's not very clear how I'm supposed to do it. I switched some deployments from the v3 to the v4 chart and I end up with this sort of diff:
- const clusterCrd = operatorChart.getResource("apiextensions.k8s.io/v1/CustomResourceDefinition", "rabbitmqclusters.rabbitmq.com").apply(c => notNull(c));
+ const clusterCrd = operatorChart.resources.apply(resources => {
+ for (const r of resources) {
+ if (r.__pulumiType === "kubernetes:apiextensions.k8s.io/v1:CustomResourceDefinition" && r.__name.endsWith("rabbitmqclusters.rabbitmq.com")) {
+ return r;
+ }
+ }
+ throw new Error("Could not find rabbitmq operator CRD");
+ });
I previously posted a message on slack: https://pulumi-community.slack.com/archives/CRFURDVQB/p1728239416448769
@awoimbee Apologies that you're having difficulties getting a resource with Chart v4. This is still an area that we're improving the UX on. For now, the following snippet might be helpful in replicating a getResource type functionality.
import * as k8s from "@pulumi/kubernetes"
// create a mapping table from `apiVersion/Kind/Namespace/Name` to kubernetes resource
const lookupTable = operatorChart.resources.apply(resources => {
return resources.reduce((table, r) => {
const ident = pulumi.interpolate`${r.apiVersion}/${r.kind}/${r.metadata.namespace}/${r.metadata.name}`;
return pulumi.all([table, ident]).apply(([tbl, id]) => {
tbl[id] = (r as pulumi.Resource);
return tbl;
});
}, {});
})
// now we can look up the desired resource by ident
const svc = lookupTable.apply(table => {
return table["apiextensions.k8s.io/v1/CustomResourceDefinition/rabbitmqclusters.rabbitmq.com"]
}) as unknown as k8s.apiextensions.v1.CustomResourceDefinition;
We're considering having better support with a utility function similar to getResource and this is on our backlog.
Thanks for the idea, I ended up with this generic solution:
export function getResource<T extends pulumi.Resource=pulumi.Resource> (
chart: k8s.helm.v4.Chart,
match: pulumi.Input<string>
): pulumi.Output<T> {
const resources = chart.resources.apply(
resources => pulumi.all(
resources.map(
r => {
const namespace = output(r.metadata?.namespace).apply(n => n || "");
return pulumi.all([
r as pulumi.Resource,
pulumi.interpolate`${r.apiVersion}:${r.kind}:${namespace}:${r.metadata?.name}`
]);
}
)
)
);
return pulumi.all([resources, match]).apply(([resources, match]) => {
const matchingResources = resources.filter(([_, name]) => name === match);
const matchingResourceNames = matchingResources.map(([_, n]) => n);
assert.equal(matchingResources.length, 1, `Exactly 1 resource should match '${match}', matched: '${matchingResourceNames}'`);
return matchingResources[0][0] as T;
});
}
The full code is here: https://github.com/pulumi/pulumi-kubernetes/issues/3110#issuecomment-2414011466
Could we at least add something to the docs that this is a known limitation and how to get around it?
Can this be done in python? Unfortunately my python / ts isn't sufficient to do it on my own.
A related PR: https://github.com/pulumi/pulumi-kubernetes/pull/2918
yeah re-implimenting this in go is a bit of a pain in the ass, would love to see it come back though
Sounds like the main thing we need to do to close this is to internalize the getResources workaround in the second comment.
Sounds like the main thing we need to do to close this is to internalize the getResources workaround in the second comment.
Please! I've defaulted to rebuilding helm chats myself to have access to resource names.