check point of code to identify and provision switches
Change-Id: I692d83127cbb718f03d359911689d0f688fa4a3d
diff --git a/switchq/storage.go b/switchq/storage.go
new file mode 100644
index 0000000..d4ec36d
--- /dev/null
+++ b/switchq/storage.go
@@ -0,0 +1,113 @@
+package main
+
+import (
+ "encoding/json"
+ "fmt"
+ "log"
+ "net/url"
+ "os"
+ "strings"
+ "time"
+)
+
+func NewStorage(spec string) (Storage, error) {
+ u, err := url.Parse(spec)
+ if err != nil {
+ return nil, err
+ }
+ switch u.Scheme {
+ case "memory":
+ return NewMemoryStorage(u)
+ default:
+ }
+ return nil, fmt.Errorf("Unknown storage scheme specified, '%s'", u.Scheme)
+}
+
+type Storage interface {
+ Switchq(mac string) (bool, error)
+ LastMACCheck(mac string) (*time.Time, error)
+ MarkMACCheck(mac string, when *time.Time) error
+ LastProvisioned(mac string) (*time.Time, error)
+ MarkProvisioned(mac string, when *time.Time) error
+}
+
+type VendorRec struct {
+ Prefix string `json:"prefix"`
+ Vendor string `json:"vendor"`
+ Provision bool `json:"provision"`
+}
+
+type MemoryStorage struct {
+ Vendors map[string]VendorRec
+ Checks map[string]time.Time
+ Times map[string]time.Time
+}
+
+func NewMemoryStorage(u *url.URL) (Storage, error) {
+
+ s := MemoryStorage{}
+ s.Vendors = make(map[string]VendorRec)
+
+ if u.Path != "" {
+ file, err := os.Open(u.Path)
+ if err != nil {
+ return nil, err
+ }
+ defer file.Close()
+
+ data := make([]VendorRec, 0)
+ decoder := json.NewDecoder(file)
+ err = decoder.Decode(&data)
+ if err != nil {
+ return nil, err
+ }
+ for _, rec := range data {
+ s.Vendors[rec.Prefix] = rec
+ }
+ log.Printf("[debug] %v", s.Vendors)
+
+ } else {
+ log.Printf("[warn] no vendors have been set, no switches will be provisioned")
+ }
+ return &s, nil
+}
+
+func (s *MemoryStorage) Switchq(mac string) (bool, error) {
+ if len(mac) < 8 {
+ return false, nil
+ }
+ rec, ok := s.Vendors[strings.ToUpper(mac[0:8])]
+ if !ok || !rec.Provision {
+ return false, nil
+ }
+
+ return true, nil
+}
+
+func (s *MemoryStorage) LastMACCheck(mac string) (*time.Time, error) {
+ when, ok := s.Checks[mac]
+ if !ok {
+ return nil, nil
+ }
+ result := when
+ return &result, nil
+}
+
+func (s *MemoryStorage) MarkMACCheck(mac string, when *time.Time) error {
+ s.Checks[mac] = *when
+ return nil
+}
+
+func (s *MemoryStorage) LastProvisioned(mac string) (*time.Time, error) {
+ when, ok := s.Times[mac]
+ if !ok {
+ return nil, nil
+ }
+ result := when
+ return &result, nil
+}
+
+func (s *MemoryStorage) MarkProvisioned(mac string, when *time.Time) error {
+ s.Times[mac] = *when
+ return nil
+}