diff --git a/internal/pkg/rancher/client/app_client.go b/internal/pkg/rancher/client/app_client.go index 58b905f..aa88a7a 100644 --- a/internal/pkg/rancher/client/app_client.go +++ b/internal/pkg/rancher/client/app_client.go @@ -17,6 +17,7 @@ package client import ( "fmt" "reflect" + "strings" projectModel "github.com/bitgrip/cattlectl/internal/pkg/rancher/project/model" "github.com/rancher/norman/types" @@ -148,7 +149,7 @@ func (client *appClient) Upgrade() error { ExternalID: externalID, } if client.app.ValuesYaml != "" { - if installedApp.ValuesYaml == client.app.ValuesYaml { + if strings.TrimSpace(installedApp.ValuesYaml) == strings.TrimSpace(client.app.ValuesYaml) { client.logger.Debug("Skip upgrade app - no changes") return nil } diff --git a/internal/pkg/template/template.go b/internal/pkg/template/template.go index f206728..2ad4ff5 100644 --- a/internal/pkg/template/template.go +++ b/internal/pkg/template/template.go @@ -41,9 +41,11 @@ func BuildTemplate(templateData []byte, values map[string]interface{}, baseDir s } descriptorTemplate := template.New("data-template") descriptorTemplate.Funcs(template.FuncMap{ - "read": readFunc(absBaseDir), - "indent": indent, - "toYaml": toYaml, + "read": readFunc(absBaseDir), + "readWithTemplate": readTemplateFunc(baseDir, values), + "indent": indent, + "trim": trim, + "toYaml": toYaml, }) if truncated { descriptorTemplate.Funcs(template.FuncMap{ @@ -84,6 +86,41 @@ func readFunc(baseDir string) func(fileName string) []byte { } } +func readTemplateFunc(baseDir string, values map[string]interface{}) func(fileName string) string { + return func(fileName string) string { + + var absFileName string + if filepath.IsAbs(fileName) { + absFileName = fileName + } else { + absFileName = filepath.Clean(fmt.Sprintf("%s/%s", baseDir, fileName)) + } + + fileContent, err := ioutil.ReadFile(absFileName) + if err != nil { + log.Fatal(err) + } + + descriptorTemplate := template.New(absFileName) + descriptorTemplate.Funcs(template.FuncMap{ + "read": readFunc(filepath.Dir(absFileName)), + "indent": indent, + "toYaml": toYaml, + "base64": toBase64, + }) + descriptorTemplate, err = descriptorTemplate.Parse(string(fileContent)) + if err != nil { + log.Fatal(err) + } + descriptorTemplate = descriptorTemplate.Option("missingkey=error") + var templateBuffer bytes.Buffer + if err := descriptorTemplate.Execute(&templateBuffer, values); err != nil { + log.Fatal(err) + } + return string(templateBuffer.Bytes()) + } +} + func toBase64(data interface{}) string { var encoded string if bytes, isBytes := data.([]byte); isBytes { @@ -113,6 +150,16 @@ func indent(indents int, data interface{}) string { return prefix + result } +func trim(data interface{}) string { + var toTrim string + if bytes, isBytes := data.([]byte); isBytes { + toTrim = string(bytes) + } else { + toTrim = fmt.Sprint(data) + } + return strings.TrimSpace(toTrim) +} + func toYaml(data interface{}) (string, error) { marshalledYaml, err := yaml.Marshal(data) if err != nil { diff --git a/internal/pkg/template/testdata/read-template/input.txt b/internal/pkg/template/testdata/read-template/input.txt new file mode 100644 index 0000000..d03858d --- /dev/null +++ b/internal/pkg/template/testdata/read-template/input.txt @@ -0,0 +1 @@ + {{readWithTemplate "template.txt" | trim }} diff --git a/internal/pkg/template/testdata/read-template/read-file1.txt b/internal/pkg/template/testdata/read-template/read-file1.txt new file mode 100644 index 0000000..83db48f --- /dev/null +++ b/internal/pkg/template/testdata/read-template/read-file1.txt @@ -0,0 +1,3 @@ +line1 +line2 +line3 diff --git a/internal/pkg/template/testdata/read-template/read-template-false.golden b/internal/pkg/template/testdata/read-template/read-template-false.golden new file mode 100644 index 0000000..c403458 --- /dev/null +++ b/internal/pkg/template/testdata/read-template/read-template-false.golden @@ -0,0 +1,7 @@ + line1 + line2 + line3 + + line1 + line2 + line3 diff --git a/internal/pkg/template/testdata/read-template/read-template-true.golden b/internal/pkg/template/testdata/read-template/read-template-true.golden new file mode 100644 index 0000000..c403458 --- /dev/null +++ b/internal/pkg/template/testdata/read-template/read-template-true.golden @@ -0,0 +1,7 @@ + line1 + line2 + line3 + + line1 + line2 + line3 diff --git a/internal/pkg/template/testdata/read-template/template.txt b/internal/pkg/template/testdata/read-template/template.txt new file mode 100644 index 0000000..ced0830 --- /dev/null +++ b/internal/pkg/template/testdata/read-template/template.txt @@ -0,0 +1,3 @@ +{{read .file_name1 | indent 4 }} + +{{read .file_name1 | indent 5 }} diff --git a/sample/project-with-app-with-values-yaml/app-values.yaml b/sample/project-with-app-with-values-yaml/app-values.yaml new file mode 100644 index 0000000..3c3837d --- /dev/null +++ b/sample/project-with-app-with-values-yaml/app-values.yaml @@ -0,0 +1,15 @@ +--- +wordpressUsername: "{{ .wordpress.username }}" +wordpressPassword: "{{ .wordpress.password }}" +wordpressEmail: "{{ .wordpress.email }}" +mariadb: + master: + persistence: + enabled: false +persistence: + enabled: false +ingress: + enabled: true + hosts: + - name: xip.io +serviceType: ClusterIP \ No newline at end of file diff --git a/sample/project-with-app-with-values-yaml/project.yaml b/sample/project-with-app-with-values-yaml/project.yaml new file mode 100644 index 0000000..e4e34e7 --- /dev/null +++ b/sample/project-with-app-with-values-yaml/project.yaml @@ -0,0 +1,15 @@ +--- +api_version: v1.0 +kind: Project +metadata: + name: "{{ .project_name }}" +namespaces: + - name: "{{ .project_name }}-web" +apps: +- name: blog-wordpress-from-values-yaml + catalog: library + chart: wordpress + version: "2.1.10" + namespace: "{{ .project_name }}-web" + values_yaml: | + {{readWithTemplate "app-values.yaml" | indent 2 | trim}} diff --git a/sample/project-with-app-with-values-yaml/values1.yaml b/sample/project-with-app-with-values-yaml/values1.yaml new file mode 100644 index 0000000..9467bba --- /dev/null +++ b/sample/project-with-app-with-values-yaml/values1.yaml @@ -0,0 +1,5 @@ +project_name: test-project +wordpress: + username: 'my-wordpress-user' + password: 'a-simple-password-to-be-changed' + email: 'info@my-wordpress-blog' diff --git a/sample/project-with-app-with-values-yaml/values2.yaml b/sample/project-with-app-with-values-yaml/values2.yaml new file mode 100644 index 0000000..bad8f8e --- /dev/null +++ b/sample/project-with-app-with-values-yaml/values2.yaml @@ -0,0 +1,5 @@ +project_name: test-project +wordpress: + username: 'my-wordpress-user' + password: 'a-simple-password-to-be-changed-changed' + email: 'info@my-wordpress-blog' \ No newline at end of file diff --git a/sample/project-with-app/project.yaml b/sample/project-with-app/project.yaml index 98363fe..06fcace 100644 --- a/sample/project-with-app/project.yaml +++ b/sample/project-with-app/project.yaml @@ -2,21 +2,21 @@ api_version: v1.0 kind: Project metadata: - name: {{ .project_name }} + name: "{{ .project_name }}" namespaces: - - name: {{ .project_name }}-web + - name: "{{ .project_name }}-web" apps: - name: blog-wordpress catalog: library chart: wordpress version: "2.1.10" - namespace: {{ .project_name }}-web + namespace: "{{ .project_name }}-web" answers: - wordpressUsername: {{ .wordpress.username }} - wordpressPassword: {{ .wordpress.password }} - wordpressEmail: {{ .wordpress.email }} - mariadb.master.persistence.enabled: 'false' - persistence.enabled: 'false' + wordpressUsername: "{{ .wordpress.username }}" + wordpressPassword: "{{ .wordpress.password }}" + wordpressEmail: "{{ .wordpress.email }}" + mariadb.master.persistence.enabled: "false" + persistence.enabled: "false" ingress.enabled: true 'ingress.hosts[0].name': xip.io serviceType: ClusterIP