github.com/ablease/cli@v6.37.1-0.20180613014814-3adbb7d7fb19+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 retunrs a fully
    36  // merged set of applications.
    37  func ReadAndInterpolateManifest(pathToManifest string, pathsToVarsFiles []string, vars []template.VarKV) ([]Application, error) {
    38  	rawManifest, err := ioutil.ReadFile(pathToManifest)
    39  	if err != nil {
    40  		return nil, err
    41  	}
    42  
    43  	tpl := template.NewTemplate(rawManifest)
    44  	fileVars := template.StaticVariables{}
    45  
    46  	for _, path := range pathsToVarsFiles {
    47  		rawVarsFile, ioerr := ioutil.ReadFile(path)
    48  		if ioerr != nil {
    49  			return nil, ioerr
    50  		}
    51  
    52  		var sv template.StaticVariables
    53  
    54  		err = yaml.Unmarshal(rawVarsFile, &sv)
    55  		if err != nil {
    56  			return nil, InvalidYAMLError{Err: err}
    57  		}
    58  
    59  		for k, v := range sv {
    60  			fileVars[k] = v
    61  		}
    62  	}
    63  
    64  	for _, kv := range vars {
    65  		fileVars[kv.Name] = kv.Value
    66  	}
    67  
    68  	rawManifest, err = tpl.Evaluate(fileVars, nil, template.EvaluateOpts{ExpectAllKeys: true})
    69  	if err != nil {
    70  		return nil, InterpolationError{Err: err}
    71  	}
    72  
    73  	var manifest Manifest
    74  
    75  	err = yaml.Unmarshal(rawManifest, &manifest)
    76  	if err != nil {
    77  		return nil, err
    78  	}
    79  
    80  	for i, app := range manifest.Applications {
    81  		if app.Path != "" && !filepath.IsAbs(app.Path) {
    82  			manifest.Applications[i].Path = filepath.Join(filepath.Dir(pathToManifest), app.Path)
    83  		}
    84  	}
    85  
    86  	return manifest.Applications, err
    87  }
    88  
    89  // WriteApplicationManifest writes the provided application to the given
    90  // filepath. If the filepath does not exist, it will create it.
    91  func WriteApplicationManifest(application Application, filePath string) error {
    92  	manifest := Manifest{Applications: []Application{application}}
    93  	manifestBytes, err := yaml.Marshal(manifest)
    94  	if err != nil {
    95  		return ManifestCreationError{Err: err}
    96  	}
    97  
    98  	err = ioutil.WriteFile(filePath, manifestBytes, 0644)
    99  	if err != nil {
   100  		return ManifestCreationError{Err: err}
   101  	}
   102  
   103  	return nil
   104  }