-
Notifications
You must be signed in to change notification settings - Fork 0
/
config.go
148 lines (123 loc) · 3.37 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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
package config
import (
"flag"
"fmt"
"net/url"
"os"
"os/user"
"path/filepath"
"strings"
"gopkg.in/yaml.v3"
)
type ConfigTemplateOverwrite struct {
Key string `yaml:"key"`
Value string `yaml:"value"`
Template string `yaml:"template"`
}
type ConfigNameOverwrite struct {
Regex string `yaml:"regex"`
Value string `yaml:"value"`
}
type ConfigSessionPath struct {
Template string `yaml:"template"`
Overwrites []ConfigTemplateOverwrite `yaml:"overwrites"`
}
type Config struct {
configPath string
NetboxUrl string `yaml:"netbox_url"`
NetboxToken string `yaml:"netbox_token"`
RootPath string `yaml:"root_path"`
NameOverwrites []ConfigNameOverwrite `yaml:"name_overwrites"`
SessionPath ConfigSessionPath `yaml:"session_path"`
EnablePeriodicSync bool `yaml:"periodic_sync_enable"`
PeriodicSyncInterval *int `yaml:"periodic_sync_interval"`
DefaultCredential *string `yaml:"default_credential"`
}
func NewConfig(configPath string) (*Config, error) {
// Create config structure
config := &Config{}
// Open config file
file, err := os.Open(configPath)
if err != nil {
return nil, err
}
defer file.Close()
// Init new YAML decode
d := yaml.NewDecoder(file)
// Start YAML decoding from file
if err := d.Decode(&config); err != nil {
return nil, err
}
if config.PeriodicSyncInterval == nil {
defaultTime := 60
config.PeriodicSyncInterval = &defaultTime
}
// validate the netbox url, and allows us to strip http/https etc
url, err := parseRawURL(config.NetboxUrl)
if err != nil {
return nil, err
}
config.NetboxUrl = url.Host
config.configPath = configPath
return config, nil
}
func (c *Config) Save() error {
data, err := yaml.Marshal(c)
if err != nil {
return err
}
err = os.WriteFile(c.configPath, data, 0)
if err != nil {
return err
}
return nil
}
// ValidateConfigPath just makes sure, that the path provided is a file,
// that can be read
func ValidateConfigPath(path string) error {
s, err := os.Stat(path)
if err != nil {
return err
}
if s.IsDir() {
return fmt.Errorf("'%s' is a directory, not a normal file", path)
}
return nil
}
func ParseFlags() (string, error) {
// String that contains the configured configuration path
var configPath string
// Set up a CLI flag called "-config" to allow users
// to supply the configuration file
flag.StringVar(&configPath, "config", "~/.securecrt-inventory.yaml", "path to config file")
// handle the users home dir
usr, _ := user.Current()
dir := usr.HomeDir
if configPath == "~" {
// In case of "~", which won't be caught by the "else if"
configPath = dir
} else if strings.HasPrefix(configPath, "~/") {
// Use strings.HasPrefix so we don't match paths like
// "/something/~/something/"
configPath = filepath.Join(dir, configPath[2:])
}
// Actually parse the flags
flag.Parse()
// Validate the path first
if err := ValidateConfigPath(configPath); err != nil {
return "", err
}
// Return the configuration path
return configPath, nil
}
func parseRawURL(rawurl string) (u *url.URL, err error) {
u, err = url.ParseRequestURI(rawurl)
if err != nil || u.Host == "" {
u, repErr := url.ParseRequestURI("https://" + rawurl)
if repErr != nil {
return nil, err
}
return u, nil
}
return u, nil
}