forked from cloudfoundry/bosh-cli
-
Notifications
You must be signed in to change notification settings - Fork 0
/
vars_fs_store.go
132 lines (100 loc) · 2.68 KB
/
vars_fs_store.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package cmd
import (
bosherr "github.com/cloudfoundry/bosh-utils/errors"
boshsys "github.com/cloudfoundry/bosh-utils/system"
cfgtypes "github.com/cloudfoundry/config-server/types"
"gopkg.in/yaml.v2"
boshtpl "github.com/cloudfoundry/bosh-cli/director/template"
)
type VarsFSStore struct {
FS boshsys.FileSystem
ValueGeneratorFactory cfgtypes.ValueGeneratorFactory
path string
}
var _ boshtpl.Variables = VarsFSStore{}
func (s VarsFSStore) IsSet() bool { return len(s.path) > 0 }
func (s VarsFSStore) Get(varDef boshtpl.VariableDefinition) (interface{}, bool, error) {
vars, err := s.load()
if err != nil {
return nil, false, err
}
val, found := vars[varDef.Name]
if found {
return val, true, nil
}
if len(varDef.Type) == 0 {
return nil, false, nil
}
val, err = s.generateAndSet(varDef)
if err != nil {
return nil, false, bosherr.WrapErrorf(err, "Generating variable '%s'", varDef.Name)
}
return val, true, nil
}
func (s VarsFSStore) List() ([]boshtpl.VariableDefinition, error) {
vars, err := s.load()
if err != nil {
return nil, err
}
return vars.List()
}
func (s VarsFSStore) generateAndSet(varDef boshtpl.VariableDefinition) (interface{}, error) {
generator, err := s.ValueGeneratorFactory.GetGenerator(varDef.Type)
if err != nil {
return nil, err
}
val, err := generator.Generate(varDef.Options)
if err != nil {
return nil, err
}
err = s.set(varDef.Name, val)
if err != nil {
return nil, err
}
return val, nil
}
func (s VarsFSStore) set(key string, val interface{}) error {
vars, err := s.load()
if err != nil {
return err
}
vars[key] = val
return s.save(vars)
}
func (s VarsFSStore) load() (boshtpl.StaticVariables, error) {
vars := boshtpl.StaticVariables{}
if s.FS.FileExists(s.path) {
bytes, err := s.FS.ReadFile(s.path)
if err != nil {
return vars, err
}
err = yaml.Unmarshal(bytes, &vars)
if err != nil {
return vars, bosherr.WrapErrorf(err, "Deserializing variables file store '%s'", s.path)
}
}
return vars, nil
}
func (s VarsFSStore) save(vars boshtpl.StaticVariables) error {
bytes, err := yaml.Marshal(vars)
if err != nil {
return bosherr.WrapErrorf(err, "Serializing variables")
}
err = s.FS.WriteFile(s.path, bytes)
if err != nil {
return bosherr.WrapErrorf(err, "Writing variables to file store '%s'", s.path)
}
return nil
}
func (s *VarsFSStore) UnmarshalFlag(data string) error {
if len(data) == 0 {
return bosherr.Errorf("Expected file path to be non-empty")
}
absPath, err := s.FS.ExpandPath(data)
if err != nil {
return bosherr.WrapErrorf(err, "Getting absolute path '%s'", data)
}
(*s).path = absPath
(*s).ValueGeneratorFactory = cfgtypes.NewValueGeneratorConcrete(nil)
return nil
}