-
Notifications
You must be signed in to change notification settings - Fork 10
/
config.go
130 lines (104 loc) · 3.61 KB
/
config.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
package main
import (
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"path/filepath"
"gopkg.in/yaml.v2"
)
// ConfigFilename is for reading bucket info
const jsonConfigFilename = "gmig.json"
const YAMLConfigFilename = "gmig.yaml"
const ymlConfigFilename = "gmig.yml"
// Config holds gmig program config
type Config struct {
// Project is a GCP project name.
Project string `json:"project" yaml:"project"`
// Region is a GCP region. Optional, use the default one if absent.
Region string `json:"region,omitempty" yaml:"region,omitempty"`
// Region is a GCP zone. Optional, use the default one if absent.
Zone string `json:"zone,omitempty" yaml:"zone,omitempty"`
// Bucket is the name of the Google Storage Bucket.
Bucket string `json:"bucket" yaml:"bucket"`
//LastMigrationObjectName is the name of the bucket object and the local (temporary) file.
LastMigrationObjectName string `json:"state" yaml:"state"`
// EnvironmentVars hold additional environment values
// that can be accessed by each command line in the Do & Undo section.
// Note that PROJECT,REGION and ZONE are already available.
EnvironmentVars map[string]string `json:"env,omitempty" yaml:"env,omitempty"`
// verbose if true then produce more logging.
verbose bool
// source filename
filename string
}
func loadAndUnmarshalConfig(location string, unmarshaller func(in []byte, out interface{}) (err error)) (*Config, error) {
data, err := ioutil.ReadFile(location)
if err != nil {
return nil, err
}
c := &Config{
filename: location,
}
if err := unmarshaller(data, &c); err != nil {
return nil, err
}
if err := c.Validate(); err != nil {
return nil, err
}
return c, nil
}
func loadYAMLConfig(location string) (*Config, error) {
return loadAndUnmarshalConfig(location, yaml.Unmarshal)
}
func loadJSONConfig(location string) (*Config, error) {
return loadAndUnmarshalConfig(location, json.Unmarshal)
}
// TryToLoadConfig reads configuration from path first looking for gmig.yaml,
// if not exists fallback to gmig.yml and gmig.json then validates it.
func TryToLoadConfig(pathToConfig string) (*Config, error) {
yamlLocation := filepath.Join(pathToConfig, YAMLConfigFilename)
ymlLocation := filepath.Join(pathToConfig, ymlConfigFilename)
jsonLocation := filepath.Join(pathToConfig, jsonConfigFilename)
if checkExists(yamlLocation) == nil {
return loadYAMLConfig(yamlLocation)
} else if checkExists(ymlLocation) == nil {
return loadYAMLConfig(ymlLocation)
} else if checkExists(jsonLocation) == nil {
config, err := loadJSONConfig(jsonLocation)
printWarning("JSON configuration (gmig.json) is deprecated, your configuration (gmig.yaml)")
return config, err
}
return nil, errors.New("can not find any configuration")
}
// ToJSON returns the JSON representation.
func (c Config) ToJSON() string {
data, _ := json.MarshalIndent(c, "", "\t")
return string(data)
}
// ToYAML returns the YAML representation.
func (c Config) ToYAML() string {
data, _ := yaml.Marshal(c)
return string(data)
}
// Validate checks required fields in the configuration.
func (c Config) Validate() error {
if len(c.Project) == 0 {
return errors.New("missing project in configuration")
}
if len(c.Bucket) == 0 {
return errors.New("missing bucket in configuration")
}
if len(c.LastMigrationObjectName) == 0 {
return errors.New("missing state name in configuration")
}
return nil
}
func (c Config) shellEnv() (envs []string) {
envs = append(envs, "PROJECT="+c.Project, "REGION="+c.Region, "ZONE="+c.Zone)
// now (override) with any custom values ; do not check values
for k, v := range c.EnvironmentVars {
envs = append(envs, fmt.Sprintf("%s=%s", k, v))
}
return
}