Render the CRDs to spec files

Signed-off-by: Mike Tougeron <tougeron@adobe.com>
pull/7440/head
Mike Tougeron 5 years ago
parent 8175c79dd9
commit 804e07300b

@ -62,19 +62,13 @@ func newTemplateCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
client.Replace = true // Skip the name check client.Replace = true // Skip the name check
client.ClientOnly = !validate client.ClientOnly = !validate
client.APIVersions = chartutil.VersionSet(extraAPIs) client.APIVersions = chartutil.VersionSet(extraAPIs)
client.IncludeCRDs = includeCrds
rel, err := runInstall(args, client, valueOpts, out) rel, err := runInstall(args, client, valueOpts, out)
if err != nil { if err != nil {
return err return err
} }
var manifests bytes.Buffer var manifests bytes.Buffer
if includeCrds {
for _, f := range rel.Chart.CRDs() {
fmt.Fprintf(&manifests, "---\n# Source: %s\n%s\n", f.Name, f.Data)
}
}
fmt.Fprintln(&manifests, strings.TrimSpace(rel.Manifest)) fmt.Fprintln(&manifests, strings.TrimSpace(rel.Manifest))
if !client.DisableHooks { if !client.DisableHooks {

@ -83,6 +83,7 @@ type Install struct {
OutputDir string OutputDir string
Atomic bool Atomic bool
SkipCRDs bool SkipCRDs bool
IncludeCRDs bool
SubNotes bool SubNotes bool
// APIVersions allows a manual set of supported API Versions to be passed // APIVersions allows a manual set of supported API Versions to be passed
// (for things like templating). These are ignored if ClientOnly is false // (for things like templating). These are ignored if ClientOnly is false
@ -111,12 +112,12 @@ func NewInstall(cfg *Configuration) *Install {
} }
} }
func (i *Install) installCRDs(crds []*chart.File) error { func (i *Install) installCRDs(crds []chart.CRD) error {
// We do these one file at a time in the order they were read. // We do these one file at a time in the order they were read.
totalItems := []*resource.Info{} totalItems := []*resource.Info{}
for _, obj := range crds { for _, obj := range crds {
// Read in the resources // Read in the resources
res, err := i.cfg.KubeClient.Build(bytes.NewBuffer(obj.Data), false) res, err := i.cfg.KubeClient.Build(bytes.NewBuffer(obj.File.Data), false)
if err != nil { if err != nil {
return errors.Wrapf(err, "failed to install CRD %s", obj.Name) return errors.Wrapf(err, "failed to install CRD %s", obj.Name)
} }
@ -217,7 +218,7 @@ func (i *Install) Run(chrt *chart.Chart, vals map[string]interface{}) (*release.
rel := i.createRelease(chrt, vals) rel := i.createRelease(chrt, vals)
var manifestDoc *bytes.Buffer var manifestDoc *bytes.Buffer
rel.Hooks, manifestDoc, rel.Info.Notes, err = i.cfg.renderResources(chrt, valuesToRender, i.OutputDir, i.SubNotes) rel.Hooks, manifestDoc, rel.Info.Notes, err = i.cfg.renderResources(chrt, valuesToRender, i.OutputDir, i.SubNotes, i.IncludeCRDs)
// Even for errors, attach this if available // Even for errors, attach this if available
if manifestDoc != nil { if manifestDoc != nil {
rel.Manifest = manifestDoc.String() rel.Manifest = manifestDoc.String()
@ -421,7 +422,7 @@ func (i *Install) replaceRelease(rel *release.Release) error {
} }
// renderResources renders the templates in a chart // renderResources renders the templates in a chart
func (c *Configuration) renderResources(ch *chart.Chart, values chartutil.Values, outputDir string, subNotes bool) ([]*release.Hook, *bytes.Buffer, string, error) { func (c *Configuration) renderResources(ch *chart.Chart, values chartutil.Values, outputDir string, subNotes bool, includeCrds bool) ([]*release.Hook, *bytes.Buffer, string, error) {
hs := []*release.Hook{} hs := []*release.Hook{}
b := bytes.NewBuffer(nil) b := bytes.NewBuffer(nil)
@ -494,6 +495,21 @@ func (c *Configuration) renderResources(ch *chart.Chart, values chartutil.Values
// Aggregate all valid manifests into one big doc. // Aggregate all valid manifests into one big doc.
fileWritten := make(map[string]bool) fileWritten := make(map[string]bool)
if includeCrds {
for _, crd := range ch.CRDs() {
if outputDir == "" {
fmt.Fprintf(b, "---\n# Source: %s\n%s\n", crd.Name, string(crd.File.Data[:]))
} else {
err = writeToFile(outputDir, crd.Filename, string(crd.File.Data[:]), fileWritten[crd.Name])
if err != nil {
return hs, b, "", err
}
fileWritten[crd.Name] = true
}
}
}
for _, m := range manifests { for _, m := range manifests {
if outputDir == "" { if outputDir == "" {
fmt.Fprintf(b, "---\n# Source: %s\n%s\n", m.Name, m.Content) fmt.Fprintf(b, "---\n# Source: %s\n%s\n", m.Name, m.Content)

@ -161,7 +161,7 @@ func (u *Upgrade) prepareUpgrade(name string, chart *chart.Chart, vals map[strin
return nil, nil, err return nil, nil, err
} }
hooks, manifestDoc, notesTxt, err := u.cfg.renderResources(chart, valuesToRender, "", u.SubNotes) hooks, manifestDoc, notesTxt, err := u.cfg.renderResources(chart, valuesToRender, "", u.SubNotes, false)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, err
} }

@ -15,7 +15,10 @@ limitations under the License.
package chart package chart
import "strings" import (
"path/filepath"
"strings"
)
// APIVersionV1 is the API version number for version 1. // APIVersionV1 is the API version number for version 1.
const APIVersionV1 = "v1" const APIVersionV1 = "v1"
@ -49,6 +52,15 @@ type Chart struct {
dependencies []*Chart dependencies []*Chart
} }
type CRD struct {
// Name is the File.Name for the crd file
Name string
// Filename is the File obj Name including (sub-)chart.ChartFullPath
Filename string
// File is the File obj for the crd
File *File
}
// SetDependencies replaces the chart dependencies. // SetDependencies replaces the chart dependencies.
func (ch *Chart) SetDependencies(charts ...*Chart) { func (ch *Chart) SetDependencies(charts ...*Chart) {
ch.dependencies = nil ch.dependencies = nil
@ -117,18 +129,19 @@ func (ch *Chart) AppVersion() string {
return ch.Metadata.AppVersion return ch.Metadata.AppVersion
} }
// CRDs returns a list of File objects in the 'crds/' directory of a Helm chart. // CRDs returns a list of CRD objects in the 'crds/' directory of a Helm chart & subcharts
func (ch *Chart) CRDs() []*File { func (ch *Chart) CRDs() []CRD {
files := []*File{} crds := []CRD{}
// Find all resources in the crds/ directory // Find all resources in the crds/ directory
for _, f := range ch.Files { for _, f := range ch.Files {
if strings.HasPrefix(f.Name, "crds/") { if strings.HasPrefix(f.Name, "crds/") {
files = append(files, f) mycrd := CRD{Name: f.Name, Filename: filepath.Join(ch.ChartFullPath(), f.Name), File: f}
crds = append(crds, mycrd)
} }
} }
// Get CRDs from dependencies, too. // Get CRDs from dependencies, too.
for _, dep := range ch.Dependencies() { for _, dep := range ch.Dependencies() {
files = append(files, dep.CRDs()...) crds = append(crds, dep.CRDs()...)
} }
return files return crds
} }

Loading…
Cancel
Save