25
"helm.sh/helm/v3/pkg/chart"
26
"helm.sh/helm/v3/pkg/chartutil"
27
"helm.sh/helm/v3/pkg/engine"
28
"k8s.io/apimachinery/pkg/version"
31
"istio.io/istio/istioctl/pkg/install/k8sversion"
32
"istio.io/istio/manifests"
33
"istio.io/istio/operator/pkg/util"
34
"istio.io/istio/pkg/log"
39
YAMLSeparator = "\n---\n"
42
DefaultProfileString = "default"
46
NotesFileNameSuffix = ".txt"
49
var scope = log.RegisterScope("installer", "installer")
52
type TemplateFilterFunc func(string) bool
55
type TemplateRenderer interface {
60
RenderManifest(values string) (string, error)
62
RenderManifestFiltered(values string, filter TemplateFilterFunc) (string, error)
68
func NewHelmRenderer(operatorDataDir, helmSubdir, componentName, namespace string, version *version.Info) TemplateRenderer {
69
dir := strings.Join([]string{ChartsSubdirName, helmSubdir}, "/")
70
return NewGenericRenderer(manifests.BuiltinOrDir(operatorDataDir), dir, componentName, namespace, version)
75
func ReadProfileYAML(profile, manifestsPath string) (string, error) {
77
var globalValues string
81
case util.IsFilePath(profile):
82
if globalValues, err = readFile(profile); err != nil {
86
if globalValues, err = LoadValues(profile, manifestsPath); err != nil {
87
return "", fmt.Errorf("failed to read profile %v from %v: %v", profile, manifestsPath, err)
91
return globalValues, nil
95
func renderChart(namespace, values string, chrt *chart.Chart, filterFunc TemplateFilterFunc, version *version.Info) (string, error) {
96
options := chartutil.ReleaseOptions{
100
valuesMap := map[string]any{}
101
if err := yaml.Unmarshal([]byte(values), &valuesMap); err != nil {
102
return "", fmt.Errorf("failed to unmarshal values: %v", err)
105
caps := *chartutil.DefaultCapabilities
108
operatorVersion, _ := chartutil.ParseKubeVersion("1." + strconv.Itoa(k8sversion.MinK8SVersion) + ".0")
109
caps.KubeVersion = *operatorVersion
112
caps.KubeVersion = chartutil.KubeVersion{
113
Version: version.GitVersion,
114
Major: version.Major,
115
Minor: version.Minor,
118
vals, err := chartutil.ToRenderValues(chrt, valuesMap, options, &caps)
123
if filterFunc != nil {
124
filteredTemplates := []*chart.File{}
125
for _, t := range chrt.Templates {
127
if filterFunc(t.Name) || strings.HasSuffix(t.Name, ".tpl") || t.Name == "templates/zzz_profile.yaml" {
128
filteredTemplates = append(filteredTemplates, t)
131
chrt.Templates = filteredTemplates
134
files, err := engine.Render(chrt, vals)
135
crdFiles := chrt.CRDObjects()
139
if chrt.Metadata.Name == "base" {
140
base, _ := valuesMap["base"].(map[string]any)
141
if enableIstioConfigCRDs, ok := base["enableIstioConfigCRDs"].(bool); ok && !enableIstioConfigCRDs {
142
crdFiles = []chart.CRD{}
147
keys := make([]string, 0, len(files))
148
for k := range files {
149
if strings.HasSuffix(k, NotesFileNameSuffix) {
152
keys = append(keys, k)
156
var sb strings.Builder
157
for i := 0; i < len(keys); i++ {
160
f = strings.TrimSpace(f) + "\n"
161
if !strings.HasSuffix(f, YAMLSeparator) {
164
_, err := sb.WriteString(f)
171
sort.Slice(crdFiles, func(i, j int) bool { return crdFiles[i].Name < crdFiles[j].Name })
172
for _, crdFile := range crdFiles {
173
f := string(crdFile.File.Data)
175
f = strings.TrimSpace(f) + "\n"
176
if !strings.HasSuffix(f, YAMLSeparator) {
179
_, err := sb.WriteString(f)
185
return sb.String(), nil
189
func GenerateHubTagOverlay(hub, tag string) (string, error) {
190
hubTagYAMLTemplate := `
202
return util.RenderTemplate(hubTagYAMLTemplate, ts)
206
func DefaultFilenameForProfile(profile string) string {
208
case util.IsFilePath(profile):
209
return filepath.Join(filepath.Dir(profile), DefaultProfileFilename)
211
return DefaultProfileString
216
func IsDefaultProfile(profile string) bool {
217
return profile == "" || profile == DefaultProfileString || filepath.Base(profile) == DefaultProfileFilename
220
func readFile(path string) (string, error) {
221
b, err := os.ReadFile(path)
222
return string(b), err
227
func GetProfileYAML(installPackagePath, profileOrPath string) (string, error) {
228
if profileOrPath == "" {
229
profileOrPath = "default"
231
profiles, err := readProfiles(installPackagePath)
233
return "", fmt.Errorf("failed to read profiles: %v", err)
236
if profiles[profileOrPath] && installPackagePath != "" {
237
profileOrPath = filepath.Join(installPackagePath, "profiles", profileOrPath+".yaml")
240
baseCRYAML, err := ReadProfileYAML(profileOrPath, installPackagePath)
245
if !IsDefaultProfile(profileOrPath) {
247
dfn := DefaultFilenameForProfile(profileOrPath)
248
defaultYAML, err := ReadProfileYAML(dfn, installPackagePath)
252
baseCRYAML, err = util.OverlayIOP(defaultYAML, baseCRYAML)
258
return baseCRYAML, nil