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

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

Open
awoimbee opened this issue Oct 9, 2024 · 3 comments
Open

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

awoimbee opened this issue Oct 9, 2024 · 3 comments
Labels
area/helm impact/usability Something that impacts users' ability to use the product easily and intuitively kind/enhancement Improvements or new features

Comments

@awoimbee
Copy link

awoimbee commented Oct 9, 2024

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 #3110 (comment):

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 awoimbee added kind/enhancement Improvements or new features needs-triage Needs attention from the triage team labels Oct 9, 2024
@rquitales
Copy link
Member

@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 rquitales added impact/usability Something that impacts users' ability to use the product easily and intuitively and removed needs-triage Needs attention from the triage team labels Oct 11, 2024
@awoimbee
Copy link
Author

awoimbee commented Oct 15, 2024

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: #3110 (comment)

@jkodroff
Copy link
Member

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/helm impact/usability Something that impacts users' ability to use the product easily and intuitively kind/enhancement Improvements or new features
Projects
None yet
Development

No branches or pull requests

4 participants