github.com/ouraigua/jenkins-library@v0.0.0-20231028010029-fbeaf2f3aa9b/pkg/piperenv/templating.go (about) 1 package piperenv 2 3 import ( 4 "bytes" 5 "fmt" 6 "strings" 7 "text/template" 8 ) 9 10 const DEFAULT_START_DELIMITER = "{{" 11 const DEFAULT_END_DELIMITER = "}}" 12 13 // ParseTemplate allows to parse a template which contains references to the CPE 14 // Utility functions make it simple to access specific parts of the CPE 15 func (c *CPEMap) ParseTemplate(cpeTemplate string) (*bytes.Buffer, error) { 16 return c.ParseTemplateWithDelimiter(cpeTemplate, DEFAULT_START_DELIMITER, DEFAULT_END_DELIMITER) 17 } 18 19 func (c *CPEMap) ParseTemplateWithDelimiter(cpeTemplate string, startDelimiter string, endDelimiter string) (*bytes.Buffer, error) { 20 funcMap := template.FuncMap{ 21 "cpe": c.cpe, 22 "cpecustom": c.custom, 23 "git": c.git, 24 "imageDigest": c.imageDigest, 25 "imageTag": c.imageTag, 26 27 // ToDo: add template function for artifacts 28 // This requires alignment on artifact handling before, though 29 } 30 31 tmpl, err := template.New("cpetemplate").Delims(startDelimiter, endDelimiter).Funcs(funcMap).Parse(cpeTemplate) 32 if err != nil { 33 return nil, fmt.Errorf("failed to parse cpe template '%v': %w", cpeTemplate, err) 34 } 35 36 tmplParams := struct { 37 CPE map[string]interface{} 38 }{ 39 CPE: map[string]interface{}(*c), 40 } 41 42 var generated bytes.Buffer 43 err = tmpl.Execute(&generated, tmplParams) 44 if err != nil { 45 return nil, fmt.Errorf("failed to execute cpe template '%v': %w", cpeTemplate, err) 46 } 47 48 return &generated, nil 49 } 50 51 func (c *CPEMap) cpe(element string) string { 52 // ToDo: perform validity checks to allow only selected fields for now? 53 // This would allow a stable contract and could perform conversions in case a contract changes. 54 55 return fmt.Sprint(map[string]interface{}(*c)[element]) 56 } 57 58 func (c *CPEMap) custom(element string) string { 59 return fmt.Sprint(map[string]interface{}(*c)[fmt.Sprintf("custom/%v", element)]) 60 } 61 62 func (c *CPEMap) git(element string) string { 63 var el string 64 if element == "organization" || element == "repository" { 65 el = fmt.Sprint(map[string]interface{}(*c)[fmt.Sprintf("github/%v", element)]) 66 } else { 67 el = fmt.Sprint(map[string]interface{}(*c)[fmt.Sprintf("git/%v", element)]) 68 } 69 return el 70 } 71 72 func (c *CPEMap) imageDigest(imageName string) string { 73 digests, _ := map[string]interface{}(*c)["container/imageDigests"].([]interface{}) 74 imageNames, _ := map[string]interface{}(*c)["container/imageNames"].([]interface{}) 75 if len(digests) > 0 && len(digests) == len(imageNames) { 76 for i, image := range imageNames { 77 if fmt.Sprint(image) == imageName { 78 return fmt.Sprint(digests[i]) 79 } 80 } 81 } 82 return "" 83 } 84 85 func (c *CPEMap) imageTag(imageName string) string { 86 nameTags, _ := map[string]interface{}(*c)["container/imageNameTags"].([]interface{}) 87 for _, nameTag := range nameTags { 88 nt := strings.Split(fmt.Sprint(nameTag), ":") 89 if nt[0] == imageName { 90 return nt[1] 91 } 92 } 93 return "" 94 }