Skip to content

Commit

Permalink
Allow more flexible chart references
Browse files Browse the repository at this point in the history
Allows the `chart` input argument to be used in more of the same ways allowed as argument to `helm install`.  Makes `repo` optional to allow chart to be provided in forms that require fully qualified references.  Actually expose the `fetchOpts` argument so that `--repo` (and other customerizations to fetch) can be passed.  Adds some additional test coverage.

All of the following now work:

// #1
repo: "stable",
chart: "nginx-lego",
version: "0.3.1",

// #2
repo: "stable",
chart: "nginx-lego",

// #3
chart: "stable/nginx-lego",

// #4
chart: "stable/nginx-lego",
version: "0.3.1"

// #5
chart: "nginx-lego",
version: "0.3.1",
fetchOpts: {
  repo: "https://kubernetes-charts.storage.googleapis.com"
},

// #6
chart: "nginx-lego",
fetchOpts: {
  repo: "https://kubernetes-charts.storage.googleapis.com"
},

// #7
chart: "https://kubernetes-charts.storage.googleapis.com/nginx-lego-0.3.1.tgz",

Fixes #229.
Fixes #257.
  • Loading branch information
Luke Hoban committed Nov 18, 2018
1 parent 0a9bf36 commit 3088a11
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 13 deletions.
20 changes: 20 additions & 0 deletions examples/helm/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,23 @@ const nginx = new k8s.helm.v2.Chart("simple-nginx", {
// Export the (cluster-private) IP address of the Guestbook frontend.
export const frontendClusterIp = nginx.getResourceProperty("v1/Service", "simple-nginx-nginx-lego", "spec")
.apply(spec => spec.clusterIP);

// Test a variety of other inputs on a chart that creates no resources.
const empty1 = new k8s.helm.v2.Chart("empty1", {
chart: "https://kubernetes-charts-incubator.storage.googleapis.com/raw-0.1.0.tgz",
});

const empty2 = new k8s.helm.v2.Chart("empty2", {
chart: "raw",
version: "0.1.0",
fetchOpts: {
repo: "https://kubernetes-charts-incubator.storage.googleapis.com/",
},
});

const empty3 = new k8s.helm.v2.Chart("empty3", {
chart: "raw",
fetchOpts: {
repo: "https://kubernetes-charts-incubator.storage.googleapis.com/",
},
});
41 changes: 35 additions & 6 deletions pkg/gen/nodejs-templates/helm.ts.mustache
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,51 @@ import * as nodepath from "path";

export namespace v2 {
interface BaseChartOpts {
/**
* The optional namespace to install chart resources into.
*/
namespace?: pulumi.Input<string>;
/**
* Overrides for chart values.
*/
values?: pulumi.Inputs;
/**
* Optional array of transformations to apply to resources that will be created by this chart prior to
* creation. Allows customization of the chart behaviour without directly modifying the chart itself.
*/
transformations?: ((o: any) => void)[];
}

export interface ChartOpts extends BaseChartOpts {
repo: pulumi.Input<string>;
/**
* The repository containing the desired chart. If not provided, [chart] must be a fully qualified chart URL
* or repo/chartname.
*/
repo?: pulumi.Input<string>;
/**
* The chart to deploy. If [repo] is provided, this chart name is looked up in the given repository. Else
* this chart name must be a fully qualified chart URL or `repo/chartname`.
*/
chart: pulumi.Input<string>;
/**
* The version of the chart to deploy. If not provided, the latest version will be deployed.
*/
version?: pulumi.Input<string>;
/**
* Additional options to customize the fetching of the Helm chart.
*/
fetchOpts?: pulumi.Input<FetchOpts>;
}

function isChartOpts(o: any): o is ChartOpts {
return "repo" in o && "chart" in o && "version" in o;
return "chart" in o;
}

export interface LocalChartOpts extends BaseChartOpts {
// path of the Chart directory, which contains the `Chart.yaml` file.
/**
* The path to the chart directory which contains the `Chart.yaml` file.
*/
path: string;
}

Expand Down Expand Up @@ -83,13 +109,16 @@ export namespace v2 {
let defaultValues: string;
if (isChartOpts(cfg)) {
// Fetch chart.
fetch(`${cfg.repo}/${cfg.chart}`, {
const chartToFetch = cfg.repo ? `${cfg.repo}/${cfg.chart}` : cfg.chart;
const fetchOpts = Object.assign({}, cfg.fetchOpts, {
destination: chartDir.name,
version: cfg.version
});
chart = path.quotePath(nodepath.join(chartDir.name, cfg.chart));
fetch(chartToFetch, fetchOpts);
const fetchedChartName = fs.readdirSync(chartDir.name)[0];
chart = path.quotePath(nodepath.join(chartDir.name, fetchedChartName));
defaultValues = path.quotePath(
nodepath.join(chartDir.name, cfg.chart, "values.yaml")
nodepath.join(chartDir.name, fetchedChartName, "values.yaml")
);
} else {
chart = path.quotePath(cfg.path);
Expand Down
46 changes: 39 additions & 7 deletions sdk/nodejs/helm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,51 @@ import * as nodepath from "path";

export namespace v2 {
interface BaseChartOpts {
/**
* The optional namespace to install chart resources into.
*/
namespace?: pulumi.Input<string>;
/**
* Overrides for chart values.
*/
values?: pulumi.Inputs;
/**
* Optional array of transformations to apply to resources that will be created by this chart prior to
* creation. Allows customization of the chart behaviour without directly modifying the chart itself.
*/
transformations?: ((o: any) => void)[];
}

export interface ChartOpts extends BaseChartOpts {
repo: pulumi.Input<string>;
/**
* The repository containing the desired chart. If not provided, [chart] must be a fully qualified chart URL
* or repo/chartname.
*/
repo?: pulumi.Input<string>;
/**
* The chart to deploy. If [repo] is provided, this chart name is looked up in the given repository. Else
* this chart name must be a fully qualified chart URL or `repo/chartname`.
*/
chart: pulumi.Input<string>;
/**
* The version of the chart to deploy. If not provided, the latest version will be deployed.
*/
version?: pulumi.Input<string>;

/**
* Additional options to customize the fetching of the Helm chart.
*/
fetchOpts?: pulumi.Input<FetchOpts>;
}

function isChartOpts(o: any): o is ChartOpts {
return "repo" in o && "chart" in o && "version" in o;
return "chart" in o;
}

export interface LocalChartOpts extends BaseChartOpts {
// path of the Chart directory, which contains the `Chart.yaml` file.
/**
* The path to the chart directory which contains the `Chart.yaml` file.
*/
path: string;
}

Expand Down Expand Up @@ -82,14 +108,20 @@ export namespace v2 {
let chart: string;
let defaultValues: string;
if (isChartOpts(cfg)) {
// Fetch chart.
fetch(`${cfg.repo}/${cfg.chart}`, {
const chartToFetch = cfg.repo ? `${cfg.repo}/${cfg.chart}` : cfg.chart;
const fetchOpts = Object.assign({}, cfg.fetchOpts, {
destination: chartDir.name,
version: cfg.version
});
chart = path.quotePath(nodepath.join(chartDir.name, cfg.chart));
// Fetch chart.
fetch(chartToFetch, fetchOpts);
// The fetched chart will be in a folder inside chartDir named after the chart. Instead of
// computing the chart name from the inputs (and duplicating Helm logic), just grab the single
// nested folder.
const fetchedChartName = fs.readdirSync(chartDir.name)[0];
chart = path.quotePath(nodepath.join(chartDir.name, fetchedChartName));
defaultValues = path.quotePath(
nodepath.join(chartDir.name, cfg.chart, "values.yaml")
nodepath.join(chartDir.name, fetchedChartName, "values.yaml")
);
} else {
chart = path.quotePath(cfg.path);
Expand Down

0 comments on commit 3088a11

Please sign in to comment.