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

Embed Helm chart templates in CLI #757

Merged
merged 10 commits into from
Oct 7, 2021
Merged

Embed Helm chart templates in CLI #757

merged 10 commits into from
Oct 7, 2021

Conversation

ndhanushkodi
Copy link
Contributor

Changes proposed in this PR:

  • Make the helm charts directory a go module where the helm chart files are embedded into an exported variable
  • Import the variable into the CLI to embed it at compilation time. The replace directive makes it so that you don't need to bump the dependency on changes to the charts files.
  • New functions to read those local templates and load the install from there

How I've tested this PR:

How I expect reviewers to test this PR:

  • review

Checklist:

  • Tests added
  • CHANGELOG entry added

    HashiCorp engineers only, community PRs should not add a changelog entry.
    Entries should use present tense (e.g. Add support for...)

.circleci/config.yml Outdated Show resolved Hide resolved
@ndhanushkodi ndhanushkodi requested review from a team, lkysow and t-eckert and removed request for a team October 4, 2021 16:50
charts/go.mod Show resolved Hide resolved
charts/embed_chart.go Outdated Show resolved Hide resolved
cli/cmd/common/utils.go Outdated Show resolved Hide resolved
cli/cmd/common/utils.go Outdated Show resolved Hide resolved
Name: valuesFileName,
Data: bytes,
},
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could wrap this behavior in a separate function to reduce code duplication.

func readChart(chartDirName, fileName) (*chartFile, error) {
        bytes, err = chart.ReadFile(fmt.Sprintf("%s/%s", chartDirName, fileName))
	if err != nil {
		return nil, err
	}
	return &loader.BufferedFile{
		Name: fileName,
		Data: bytes,
	}
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took a stab at a fun refactor using Thomas's suggestion and using filepath.Rel to do the removal of charts/:

func ReadChartFiles(chart embed.FS, chartDirName string) ([]*loader.BufferedFile, error) {
	var chartFiles []*loader.BufferedFile

	// Load Chart.yaml and values.yaml first.
	for _, f := range []string{chartFileName, valuesFileName} {
		buffered, err := readFile(chart, filepath.Join(chartDirName, f), chartDirName)
		if err != nil {
			return nil, err
		}
		chartFiles = append(chartFiles, buffered)
	}

	// Now load everything under templates/.
	dirs, err := chart.ReadDir(filepath.Join(chartDirName, templatesDirName))
	if err != nil {
		return nil, err
	}
	for _, dir := range dirs {
		if dir.IsDir() {
			// We only need to package up files.
			continue
		}

		buffered, err := readFile(chart, filepath.Join(chartDirName, templatesDirName, dir.Name()), chartDirName)
		if err != nil {
			return nil, err
		}
		chartFiles = append(chartFiles, buffered)
	}

	return chartFiles, nil
}

func readFile(chart embed.FS, f string, basePath string) (*loader.BufferedFile, error) {
	bytes, err := chart.ReadFile(f)
	if err != nil {
		return nil, err
	}
	rel, err := filepath.Rel(basePath, f)
	if err != nil {
		return nil, err
	}
	return &loader.BufferedFile{
		Name: rel,
		Data: bytes,
	}, nil
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could definitely be cleaned up but might be a nice change.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great suggestion @t-eckert and thanks for giving it a shot Luke, it pretty much looks good to me that way. I ended up only changing a few variable names from what it looks like here

Copy link
Contributor

@t-eckert t-eckert left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks great! I had some stylistic nits, but nothing major. You are doing great with this!

Copy link
Member

@lkysow lkysow left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work!

For future selves: Nitya and I discussed instead of doing this, pinning the chart version that helm downloads using version/version.go. This would reduce the complexity here but this work has the nice effect that there are no external calls to Helm/repositories and that everything is packaged up in the compiled binary so based on that we decided to continue with this approach.

charts/embed_chart.go Show resolved Hide resolved
cli/cmd/common/utils.go Outdated Show resolved Hide resolved
cli/cmd/common/utils.go Outdated Show resolved Hide resolved
Name: valuesFileName,
Data: bytes,
},
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took a stab at a fun refactor using Thomas's suggestion and using filepath.Rel to do the removal of charts/:

func ReadChartFiles(chart embed.FS, chartDirName string) ([]*loader.BufferedFile, error) {
	var chartFiles []*loader.BufferedFile

	// Load Chart.yaml and values.yaml first.
	for _, f := range []string{chartFileName, valuesFileName} {
		buffered, err := readFile(chart, filepath.Join(chartDirName, f), chartDirName)
		if err != nil {
			return nil, err
		}
		chartFiles = append(chartFiles, buffered)
	}

	// Now load everything under templates/.
	dirs, err := chart.ReadDir(filepath.Join(chartDirName, templatesDirName))
	if err != nil {
		return nil, err
	}
	for _, dir := range dirs {
		if dir.IsDir() {
			// We only need to package up files.
			continue
		}

		buffered, err := readFile(chart, filepath.Join(chartDirName, templatesDirName, dir.Name()), chartDirName)
		if err != nil {
			return nil, err
		}
		chartFiles = append(chartFiles, buffered)
	}

	return chartFiles, nil
}

func readFile(chart embed.FS, f string, basePath string) (*loader.BufferedFile, error) {
	bytes, err := chart.ReadFile(f)
	if err != nil {
		return nil, err
	}
	rel, err := filepath.Rel(basePath, f)
	if err != nil {
		return nil, err
	}
	return &loader.BufferedFile{
		Name: rel,
		Data: bytes,
	}, nil
}

Name: valuesFileName,
Data: bytes,
},
)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could definitely be cleaned up but might be a nice change.

lawliet89 pushed a commit to lawliet89/consul-k8s that referenced this pull request Oct 6, 2021
This will help debug errors in connections between static-client and
static-server after federation has been set up. This will provide
information about whether DC1 (static-client) is aware of the
static-server deployment in DC2.
Copy link
Member

@lkysow lkysow left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎉 super cool!

@ndhanushkodi ndhanushkodi merged commit eb86243 into main Oct 7, 2021
@ndhanushkodi ndhanushkodi deleted the install-local branch October 7, 2021 23:07
sadjamz pushed a commit that referenced this pull request Oct 18, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants