github.com/stefanmcshane/helm@v0.0.0-20221213002717-88a4a2c6e77d/pkg/chart/chart.go (about) 1 /* 2 Copyright The Helm Authors. 3 Licensed under the Apache License, Version 2.0 (the "License"); 4 you may not use this file except in compliance with the License. 5 You may obtain a copy of the License at 6 7 http://www.apache.org/licenses/LICENSE-2.0 8 9 Unless required by applicable law or agreed to in writing, software 10 distributed under the License is distributed on an "AS IS" BASIS, 11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 See the License for the specific language governing permissions and 13 limitations under the License. 14 */ 15 16 package chart 17 18 import ( 19 "path/filepath" 20 "regexp" 21 "strings" 22 ) 23 24 // APIVersionV1 is the API version number for version 1. 25 const APIVersionV1 = "v1" 26 27 // APIVersionV2 is the API version number for version 2. 28 const APIVersionV2 = "v2" 29 30 // aliasNameFormat defines the characters that are legal in an alias name. 31 var aliasNameFormat = regexp.MustCompile("^[a-zA-Z0-9_-]+$") 32 33 // Chart is a helm package that contains metadata, a default config, zero or more 34 // optionally parameterizable templates, and zero or more charts (dependencies). 35 type Chart struct { 36 // Raw contains the raw contents of the files originally contained in the chart archive. 37 // 38 // This should not be used except in special cases like `helm show values`, 39 // where we want to display the raw values, comments and all. 40 Raw []*File `json:"-"` 41 // Metadata is the contents of the Chartfile. 42 Metadata *Metadata `json:"metadata"` 43 // Lock is the contents of Chart.lock. 44 Lock *Lock `json:"lock"` 45 // Templates for this chart. 46 Templates []*File `json:"templates"` 47 // Values are default config for this chart. 48 Values map[string]interface{} `json:"values"` 49 // Schema is an optional JSON schema for imposing structure on Values 50 Schema []byte `json:"schema"` 51 // Files are miscellaneous files in a chart archive, 52 // e.g. README, LICENSE, etc. 53 Files []*File `json:"files"` 54 55 parent *Chart 56 dependencies []*Chart 57 } 58 59 type CRD struct { 60 // Name is the File.Name for the crd file 61 Name string 62 // Filename is the File obj Name including (sub-)chart.ChartFullPath 63 Filename string 64 // File is the File obj for the crd 65 File *File 66 } 67 68 // SetDependencies replaces the chart dependencies. 69 func (ch *Chart) SetDependencies(charts ...*Chart) { 70 ch.dependencies = nil 71 ch.AddDependency(charts...) 72 } 73 74 // Name returns the name of the chart. 75 func (ch *Chart) Name() string { 76 if ch.Metadata == nil { 77 return "" 78 } 79 return ch.Metadata.Name 80 } 81 82 // AddDependency determines if the chart is a subchart. 83 func (ch *Chart) AddDependency(charts ...*Chart) { 84 for i, x := range charts { 85 charts[i].parent = ch 86 ch.dependencies = append(ch.dependencies, x) 87 } 88 } 89 90 // Root finds the root chart. 91 func (ch *Chart) Root() *Chart { 92 if ch.IsRoot() { 93 return ch 94 } 95 return ch.Parent().Root() 96 } 97 98 // Dependencies are the charts that this chart depends on. 99 func (ch *Chart) Dependencies() []*Chart { return ch.dependencies } 100 101 // IsRoot determines if the chart is the root chart. 102 func (ch *Chart) IsRoot() bool { return ch.parent == nil } 103 104 // Parent returns a subchart's parent chart. 105 func (ch *Chart) Parent() *Chart { return ch.parent } 106 107 // ChartPath returns the full path to this chart in dot notation. 108 func (ch *Chart) ChartPath() string { 109 if !ch.IsRoot() { 110 return ch.Parent().ChartPath() + "." + ch.Name() 111 } 112 return ch.Name() 113 } 114 115 // ChartFullPath returns the full path to this chart. 116 func (ch *Chart) ChartFullPath() string { 117 if !ch.IsRoot() { 118 return ch.Parent().ChartFullPath() + "/charts/" + ch.Name() 119 } 120 return ch.Name() 121 } 122 123 // Validate validates the metadata. 124 func (ch *Chart) Validate() error { 125 return ch.Metadata.Validate() 126 } 127 128 // AppVersion returns the appversion of the chart. 129 func (ch *Chart) AppVersion() string { 130 if ch.Metadata == nil { 131 return "" 132 } 133 return ch.Metadata.AppVersion 134 } 135 136 // CRDs returns a list of File objects in the 'crds/' directory of a Helm chart. 137 // Deprecated: use CRDObjects() 138 func (ch *Chart) CRDs() []*File { 139 files := []*File{} 140 // Find all resources in the crds/ directory 141 for _, f := range ch.Files { 142 if strings.HasPrefix(f.Name, "crds/") && hasManifestExtension(f.Name) { 143 files = append(files, f) 144 } 145 } 146 // Get CRDs from dependencies, too. 147 for _, dep := range ch.Dependencies() { 148 files = append(files, dep.CRDs()...) 149 } 150 return files 151 } 152 153 // CRDObjects returns a list of CRD objects in the 'crds/' directory of a Helm chart & subcharts 154 func (ch *Chart) CRDObjects() []CRD { 155 crds := []CRD{} 156 // Find all resources in the crds/ directory 157 for _, f := range ch.Files { 158 if strings.HasPrefix(f.Name, "crds/") && hasManifestExtension(f.Name) { 159 mycrd := CRD{Name: f.Name, Filename: filepath.Join(ch.ChartFullPath(), f.Name), File: f} 160 crds = append(crds, mycrd) 161 } 162 } 163 // Get CRDs from dependencies, too. 164 for _, dep := range ch.Dependencies() { 165 crds = append(crds, dep.CRDObjects()...) 166 } 167 return crds 168 } 169 170 func hasManifestExtension(fname string) bool { 171 ext := filepath.Ext(fname) 172 return strings.EqualFold(ext, ".yaml") || strings.EqualFold(ext, ".yml") || strings.EqualFold(ext, ".json") 173 }