pulumi-kubernetes icon indicating copy to clipboard operation
pulumi-kubernetes copied to clipboard

Helm chart v4: no more getResource & how to use chart.resources

Open awoimbee opened this issue 1 year ago • 2 comments

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 getResource typed 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 avatar Oct 09 '24 15:10 awoimbee

@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.

rquitales avatar Oct 11 '24 23:10 rquitales

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

awoimbee avatar Oct 15 '24 14:10 awoimbee

Could we at least add something to the docs that this is a known limitation and how to get around it?

jkodroff avatar Nov 18 '24 16:11 jkodroff

Can this be done in python? Unfortunately my python / ts isn't sufficient to do it on my own.

landorg avatar Jan 30 '25 12:01 landorg

A related PR: https://github.com/pulumi/pulumi-kubernetes/pull/2918

EronWright avatar Apr 21 '25 19:04 EronWright

yeah re-implimenting this in go is a bit of a pain in the ass, would love to see it come back though

Lite5h4dow avatar Jul 21 '25 18:07 Lite5h4dow

Sounds like the main thing we need to do to close this is to internalize the getResources workaround in the second comment.

mjeffryes avatar Sep 22 '25 18:09 mjeffryes

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.

Lite5h4dow avatar Sep 22 '25 18:09 Lite5h4dow