blob: d4ec36dff3e080959fbe80a524405a15c8417b0e [file] [log] [blame]
David K. Bainbridgef694f5a2016-06-10 16:21:27 -07001package main
2
3import (
4 "encoding/json"
5 "fmt"
6 "log"
7 "net/url"
8 "os"
9 "strings"
10 "time"
11)
12
13func NewStorage(spec string) (Storage, error) {
14 u, err := url.Parse(spec)
15 if err != nil {
16 return nil, err
17 }
18 switch u.Scheme {
19 case "memory":
20 return NewMemoryStorage(u)
21 default:
22 }
23 return nil, fmt.Errorf("Unknown storage scheme specified, '%s'", u.Scheme)
24}
25
26type Storage interface {
27 Switchq(mac string) (bool, error)
28 LastMACCheck(mac string) (*time.Time, error)
29 MarkMACCheck(mac string, when *time.Time) error
30 LastProvisioned(mac string) (*time.Time, error)
31 MarkProvisioned(mac string, when *time.Time) error
32}
33
34type VendorRec struct {
35 Prefix string `json:"prefix"`
36 Vendor string `json:"vendor"`
37 Provision bool `json:"provision"`
38}
39
40type MemoryStorage struct {
41 Vendors map[string]VendorRec
42 Checks map[string]time.Time
43 Times map[string]time.Time
44}
45
46func NewMemoryStorage(u *url.URL) (Storage, error) {
47
48 s := MemoryStorage{}
49 s.Vendors = make(map[string]VendorRec)
50
51 if u.Path != "" {
52 file, err := os.Open(u.Path)
53 if err != nil {
54 return nil, err
55 }
56 defer file.Close()
57
58 data := make([]VendorRec, 0)
59 decoder := json.NewDecoder(file)
60 err = decoder.Decode(&data)
61 if err != nil {
62 return nil, err
63 }
64 for _, rec := range data {
65 s.Vendors[rec.Prefix] = rec
66 }
67 log.Printf("[debug] %v", s.Vendors)
68
69 } else {
70 log.Printf("[warn] no vendors have been set, no switches will be provisioned")
71 }
72 return &s, nil
73}
74
75func (s *MemoryStorage) Switchq(mac string) (bool, error) {
76 if len(mac) < 8 {
77 return false, nil
78 }
79 rec, ok := s.Vendors[strings.ToUpper(mac[0:8])]
80 if !ok || !rec.Provision {
81 return false, nil
82 }
83
84 return true, nil
85}
86
87func (s *MemoryStorage) LastMACCheck(mac string) (*time.Time, error) {
88 when, ok := s.Checks[mac]
89 if !ok {
90 return nil, nil
91 }
92 result := when
93 return &result, nil
94}
95
96func (s *MemoryStorage) MarkMACCheck(mac string, when *time.Time) error {
97 s.Checks[mac] = *when
98 return nil
99}
100
101func (s *MemoryStorage) LastProvisioned(mac string) (*time.Time, error) {
102 when, ok := s.Times[mac]
103 if !ok {
104 return nil, nil
105 }
106 result := when
107 return &result, nil
108}
109
110func (s *MemoryStorage) MarkProvisioned(mac string, when *time.Time) error {
111 s.Times[mac] = *when
112 return nil
113}