~tsileo/blobstash

ref: b178995e346d blobstash/pkg/config/config.go -rw-r--r-- 5.6 KiB
b178995eThomas Sileo vendor: update deps 2 years ago
                                                                                
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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
package config // import "a4.io/blobstash/pkg/config"

import (
	"fmt"
	"io/ioutil"
	"os"
	"path/filepath"

	"github.com/inconshreveable/log15"
	"gopkg.in/yaml.v2"

	"a4.io/blobstash/pkg/config/pathutil"
)

var (
	DefaultListen  = ":8051"
	LetsEncryptDir = "letsencrypt"
)

// AppConfig holds an app configuration items
type AppConfig struct {
	Name              string `yaml:"name"`
	Path              string `yaml:"path"` // App path, optional?
	Entrypoint        string `yaml:"entrypoint"`
	Domain            string `yaml:"domain"`
	Username          string `yaml:"username"`
	Password          string `yaml:"password"`
	IndieAuthEndpoint string `yaml:"indieauth_endpoint"`
	Proxy             string `yaml:"proxy"`
	Remote            string `yaml:"remote"`
	Scheduled         string `yaml:"scheduled"`

	Config map[string]interface{} `yaml:"config"`
}

type S3Repl struct {
	Bucket    string `yaml:"bucket"`
	Region    string `yaml:"region"`
	KeyFile   string `yaml:"key_file"`
	Endpoint  string `yaml:"endpoint"`
	AccessKey string `yaml:"access_key_id"`
	SecretKey string `yaml:"secret_access_key"`
}

type Replication struct {
	EnableOplog bool `yaml:"enable_oplog"`
}

type ReplicateFrom struct {
	URL    string `yaml:"url"`
	APIKey string `yaml:"api_key"`
}

func (s3 *S3Repl) Key() (*[32]byte, error) {
	if s3.KeyFile == "" {
		return nil, nil
	}
	var out [32]byte
	data, err := ioutil.ReadFile(s3.KeyFile)
	if err != nil {
		return nil, err
	}
	copy(out[:], data)
	return &out, nil
}

type BasicAuth struct {
	ID       string   `yaml:"id"`
	Roles    []string `yaml:"roles"`
	Username string   `yaml:"username"`
	Password string   `yaml:"password"`
}

type Role struct {
	Name     string                 `yaml:"name"`
	Template string                 `yaml:"template"`
	Perms    []*Perm                `yaml:"permissions"`
	Args     map[string]interface{} `yaml:"args"`

	// Only set pragmatically for "managed role"
	Managed      bool     `yaml:"-"`
	ArgsRequired []string `yaml:"-"`
}

type Perm struct {
	Action   string `yaml:"action"`
	Resource string `yaml:"resource"`
}

// Config holds the configuration items
type Config struct {
	init     bool
	Listen   string `yaml:"listen"`
	LogLevel string `yaml:"log_level"`
	// TLS     bool     `yaml:"tls"`
	AutoTLS bool     `yaml:"tls_auto"`
	Domains []string `yaml:"tls_domains"`

	Roles []*Role `yaml:"roles"`
	Auth  []*BasicAuth

	ExpvarListen string `yaml:"expvar_server_listen"`

	ExtraApacheCombinedLogs string `yaml:"extra_apache_combined_logs"`

	SharingKey string  `yaml:"sharing_key"`
	DataDir    string  `yaml:"data_dir"`
	S3Repl     *S3Repl `yaml:"s3_replication"`

	Apps          []*AppConfig    `yaml:"apps"`
	Docstore      *DocstoreConfig `yaml:"docstore"`
	Replication   *Replication    `yaml:"replication"`
	ReplicateFrom *ReplicateFrom  `yaml:"replicate_from"`

	SecretKey string `yaml:"secret_key"`

	// Items defined with the CLI flags
	CheckMode                  bool `yaml:"-"`
	ScanMode                   bool `yaml:"-"`
	S3ScanMode                 bool `yaml:"-"`
	S3RestoreMode              bool `yaml:"-"`
	DocstoreIndexesReindexMode bool `yaml:"-"`
}

func (c *Config) LogLvl() log15.Lvl {
	if c.LogLevel == "" {
		c.LogLevel = "info"
	}
	lvl, err := log15.LvlFromString(c.LogLevel)
	if err != nil {
		panic(err)
	}
	return lvl
}

type DocstoreSortIndex struct {
	Field string `yaml:"field"`
}

type DocstoreConfig struct {
	SortIndexes map[string]map[string]*DocstoreSortIndex `yaml:"sort_indexes"`
}

// New initialize a config object by loading the YAML path at the given path
func New(path string) (*Config, error) {
	data, err := ioutil.ReadFile(path)
	if err != nil {
		return nil, err
	}
	conf := &Config{}
	if err := yaml.Unmarshal([]byte(data), &conf); err != nil {
		return nil, err
	}
	return conf, nil
}

// VarDir returns the directory where the index will be stored
func (c *Config) ConfigDir() string {
	// TODO(tsileo): allow override?
	return pathutil.ConfigDir()
}

// VarDir returns the directory where the index will be stored
func (c *Config) VarDir() string {
	if c.DataDir != "" {
		return c.DataDir
	}
	return pathutil.VarDir()
}

// VarDir returns the directory where the index will be stored
func (c *Config) StashDir() string {
	return filepath.Join(c.VarDir(), "stash")
}

// VarDir returns the directory where the video metadata and transcoded webm
func (c *Config) VidDir() string {
	return filepath.Join(c.VarDir(), "videos")
}

// Init initialize the config.
//
// It will try to create all the needed directory.
func (c *Config) Init() error {
	if c.init {
		return nil
	}
	if _, err := os.Stat(c.VarDir()); os.IsNotExist(err) {
		if err := os.MkdirAll(c.VarDir(), 0700); err != nil {
			return err
		}
	}
	if _, err := os.Stat(c.VidDir()); os.IsNotExist(err) {
		if err := os.MkdirAll(c.VidDir(), 0700); err != nil {
			return err
		}
	}
	if _, err := os.Stat(c.StashDir()); os.IsNotExist(err) {
		if err := os.MkdirAll(c.VarDir(), 0700); err != nil {
			return err
		}
	}
	if _, err := os.Stat(c.ConfigDir()); os.IsNotExist(err) {
		if err := os.MkdirAll(c.ConfigDir(), 0700); err != nil {
			return err
		}
	}
	if _, err := os.Stat(filepath.Join(c.ConfigDir(), LetsEncryptDir)); os.IsNotExist(err) {
		if err := os.MkdirAll(filepath.Join(c.ConfigDir(), LetsEncryptDir), 0700); err != nil {
			return err
		}
	}
	if c.SharingKey == "" {
		return fmt.Errorf("missing `sharing_key` config item")
	}
	if c.S3Repl != nil {
		// Set default region
		if c.S3Repl.Region == "" {
			c.S3Repl.Region = "us-east-1"
		}
	}
	c.init = true
	return nil
}

// Sync url config parsing
//u, err := url.Parse("http://:123@127.0.0.1:8053")
//	if err != nil {
//		log.Fatal(err)
//	}
//	u.User = nil
//	//apiKey, _ := u.User.Password()
//	fmt.Printf("%+v", u)