github.com/sleungcy-sap/cli@v7.1.0+incompatible/util/manifest/manifest.go (about) 1 package manifest 2 3 import ( 4 "io/ioutil" 5 "path/filepath" 6 7 "github.com/cloudfoundry/bosh-cli/director/template" 8 yaml "gopkg.in/yaml.v2" 9 ) 10 11 type Manifest struct { 12 Applications []Application `yaml:"applications"` 13 } 14 15 func (manifest *Manifest) UnmarshalYAML(unmarshal func(interface{}) error) error { 16 var raw rawManifest 17 err := unmarshal(&raw) 18 if err != nil { 19 return err 20 } 21 22 if raw.containsInheritanceField() { 23 return InheritanceFieldError{} 24 } 25 26 if globals := raw.containsGlobalFields(); len(globals) > 0 { 27 return GlobalFieldsError{Fields: globals} 28 } 29 30 manifest.Applications = raw.Applications 31 return nil 32 } 33 34 // ReadAndInterpolateManifest reads the manifest at the provided paths, 35 // interpolates variables if a vars file is provided, and returns a fully 36 // merged set of applications. 37 func ReadAndInterpolateManifest(pathToManifest string, pathsToVarsFiles []string, vars []template.VarKV) ([]Application, error) { 38 rawManifest, err := ReadAndInterpolateRawManifest(pathToManifest, pathsToVarsFiles, vars) 39 if err != nil { 40 return nil, err 41 } 42 43 var manifest Manifest 44 err = yaml.Unmarshal(rawManifest, &manifest) 45 if err != nil { 46 return nil, err 47 } 48 49 for i, app := range manifest.Applications { 50 if app.Path != "" && !filepath.IsAbs(app.Path) { 51 manifest.Applications[i].Path = filepath.Join(filepath.Dir(pathToManifest), app.Path) 52 } 53 } 54 55 return manifest.Applications, err 56 } 57 58 // ReadAndInterpolateRawManifest reads the manifest at the provided paths, 59 // interpolates variables if a vars file is provided, and returns the 60 // Unmarshalled result. 61 func ReadAndInterpolateRawManifest(pathToManifest string, pathsToVarsFiles []string, vars []template.VarKV) ([]byte, error) { 62 rawManifest, err := ioutil.ReadFile(pathToManifest) 63 if err != nil { 64 return nil, err 65 } 66 67 tpl := template.NewTemplate(rawManifest) 68 fileVars := template.StaticVariables{} 69 70 for _, path := range pathsToVarsFiles { 71 rawVarsFile, ioerr := ioutil.ReadFile(path) 72 if ioerr != nil { 73 return nil, ioerr 74 } 75 76 var sv template.StaticVariables 77 78 err = yaml.Unmarshal(rawVarsFile, &sv) 79 if err != nil { 80 return nil, InvalidYAMLError{Err: err} 81 } 82 83 for k, v := range sv { 84 fileVars[k] = v 85 } 86 } 87 88 for _, kv := range vars { 89 fileVars[kv.Name] = kv.Value 90 } 91 92 rawManifest, err = tpl.Evaluate(fileVars, nil, template.EvaluateOpts{ExpectAllKeys: true}) 93 if err != nil { 94 return nil, InterpolationError{Err: err} 95 } 96 return rawManifest, nil 97 } 98 99 // WriteApplicationManifest writes the provided application to the given 100 // filepath. If the filepath does not exist, it will create it. 101 func WriteApplicationManifest(application Application, filePath string) error { 102 manifest := Manifest{Applications: []Application{application}} 103 manifestBytes, err := yaml.Marshal(manifest) 104 if err != nil { 105 return ManifestCreationError{Err: err} 106 } 107 108 err = ioutil.WriteFile(filePath, manifestBytes, 0644) 109 if err != nil { 110 return ManifestCreationError{Err: err} 111 } 112 113 return nil 114 }