forked from Cloud-Foundations/Dominator
/
generators.go
107 lines (96 loc) · 2.89 KB
/
generators.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
package main
import (
"bufio"
"errors"
"io"
"net/http"
"os"
"strings"
"github.com/Cloud-Foundations/Dominator/lib/log"
"github.com/Cloud-Foundations/Dominator/lib/mdb"
)
type makeGeneratorFunc func([]string, log.DebugLogger) (generator, error)
type sourceDriverFunc func(reader io.Reader, datacentre string,
logger log.Logger) (*mdb.Mdb, error)
// The generator interface generates an mdb from some source.
type generator interface {
Generate(datacentre string, logger log.DebugLogger) (*mdb.Mdb, error)
}
// The eventGenerator interface generates an mdb from a source which has update
// events.
type eventGenerator interface {
generator
RegisterEventChannel(events chan<- struct{})
}
func setupGenerators(reader io.Reader, drivers []driver,
logger log.DebugLogger) ([]generator, error) {
var generators []generator
scanner := bufio.NewScanner(reader)
for scanner.Scan() {
fields := strings.Fields(scanner.Text())
if len(fields) < 1 || len(fields[0]) < 1 || fields[0][0] == '#' {
continue
}
driverName := fields[0]
args := fields[1:]
var drv *driver
for _, d := range drivers {
if d.name == driverName {
drv = &d
break
}
}
if drv == nil {
return nil, errors.New("unknown driver: " + driverName)
}
if len(args) < drv.minArgs {
return nil, errors.New("insufficient arguments for: " + driverName)
}
if drv.maxArgs >= 0 && len(args) > drv.maxArgs {
return nil, errors.New("too mant arguments for: " + driverName)
}
gen, err := drv.setupFunc(args, logger)
if err != nil {
return nil, err
}
generators = append(generators, gen)
}
if err := scanner.Err(); err != nil {
return nil, err
}
return generators, nil
}
// sourceGenerator implements the generator interface and generates an *mdb.Mdb
// from either a flat file or a URL.
type sourceGenerator struct {
driverFunc sourceDriverFunc // Parses the data from URL or flat file.
url string // The URL or path of the flat file.
}
func (s sourceGenerator) Generate(datacentre string, logger log.DebugLogger) (
*mdb.Mdb, error) {
return loadMdb(s.driverFunc, s.url, datacentre, logger)
}
func loadMdb(driverFunc sourceDriverFunc, url string, datacentre string,
logger log.Logger) (*mdb.Mdb, error) {
if strings.HasPrefix(url, "http://") || strings.HasPrefix(url, "https://") {
return loadHttpMdb(driverFunc, url, datacentre, logger)
}
file, err := os.Open(url)
if err != nil {
return nil, errors.New(("Error opening file " + err.Error()))
}
defer file.Close()
return driverFunc(bufio.NewReader(file), datacentre, logger)
}
func loadHttpMdb(driverFunc sourceDriverFunc, url string, datacentre string,
logger log.Logger) (*mdb.Mdb, error) {
response, err := http.Get(url)
if err != nil {
return nil, err
}
defer response.Body.Close()
if response.StatusCode != http.StatusOK {
return nil, errors.New("HTTP get failed")
}
return driverFunc(response.Body, datacentre, logger)
}