blob: 899cde5d4591069d851d192953fcc883644ff8de [file] [log] [blame]
David K. Bainbridge068e87d2016-06-30 13:53:19 -07001package main
2
3import (
4 "bytes"
5 "encoding/json"
6 "fmt"
7 "net/http"
8)
9
10type ProvisionStatus int
11
12const (
13 Pending ProvisionStatus = iota
14 Running
15 Complete
16 Failed
17)
18
19func (s ProvisionStatus) String() string {
20 switch s {
21 case Pending:
22 return "PENDING"
23 case Running:
24 return "RUNNING"
25 case Complete:
26 return "COMPLETE"
27 case Failed:
28 return "FAILED"
29 }
30 return "INVALID TASK STATUS"
31}
32
33type ProvisionRecord struct {
34 Status ProvisionStatus `json:"status"`
35 Timestamp int64
36}
37
38type ProvisionRequest struct {
39 Id string `json:"id"`
40 Name string `json:"name"`
41 Ip string `json:"ip"`
42 Mac string `json:"mac"`
43}
44
45type Provisioner interface {
46 Get(id string) (*ProvisionRecord, error)
47 Provision(prov *ProvisionRequest) error
48 Clear(id string) error
49}
50
51type ProvisionerConfig struct {
52 Url string
53}
54
55func NewProvisioner(config *ProvisionerConfig) Provisioner {
56 return config
57}
58
59func (p *ProvisionerConfig) Get(id string) (*ProvisionRecord, error) {
60 resp, err := http.Get(p.Url + "/" + id)
61 if err != nil {
62 return nil, err
63 }
64 defer resp.Body.Close()
65 decoder := json.NewDecoder(resp.Body)
66
67 var record ProvisionRecord
68
69 switch resp.StatusCode {
70 case http.StatusOK, http.StatusAccepted:
71 err = decoder.Decode(&record)
72 if err != nil {
73 return nil, err
74 }
75 return &record, nil
76 case http.StatusNotFound:
77 return nil, nil
78 default:
79 return nil, fmt.Errorf(resp.Status)
80 }
81}
82
83func (p *ProvisionerConfig) Provision(prov *ProvisionRequest) error {
84 hc := http.Client{}
85 data, err := json.Marshal(prov)
86 if err != nil {
87 return err
88 }
89 req, err := http.NewRequest("POST", p.Url, bytes.NewReader(data))
90 if err != nil {
91 return err
92 }
93 req.Header.Add("Content-Type", "application/json")
94 resp, err := hc.Do(req)
95 if err != nil {
96 return err
97 }
98 defer resp.Body.Close()
99 if resp.StatusCode != http.StatusAccepted {
100 return fmt.Errorf("Unexpected response : %s", resp.Status)
101 }
102 return nil
103}
104
105func (p *ProvisionerConfig) Clear(id string) error {
106 hc := http.Client{}
107 req, err := http.NewRequest("DELETE", p.Url+"/"+id, nil)
108 if err != nil {
109 return err
110 }
111
112 resp, err := hc.Do(req)
113 if err != nil {
114 return err
115 }
116 defer resp.Body.Close()
117 if resp.StatusCode != http.StatusOK {
118 return fmt.Errorf("Unexpected response : %s", resp.Status)
119 }
120 return nil
121}