blob: 1f71d22a5449a2f97a1a08b6beecf50fdf6556bb [file] [log] [blame]
David K. Bainbridgedf9df632016-07-07 18:47:46 -07001// Copyright 2016 Open Networking Laboratory
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
David K. Bainbridge068e87d2016-06-30 13:53:19 -070014package main
15
16import (
17 "bytes"
18 "encoding/json"
19 "fmt"
20 "net/http"
21)
22
23type ProvisionStatus int
24
25const (
26 Pending ProvisionStatus = iota
27 Running
28 Complete
29 Failed
30)
31
32func (s ProvisionStatus) String() string {
33 switch s {
34 case Pending:
35 return "PENDING"
36 case Running:
37 return "RUNNING"
38 case Complete:
39 return "COMPLETE"
40 case Failed:
41 return "FAILED"
42 }
43 return "INVALID TASK STATUS"
44}
45
46type ProvisionRecord struct {
47 Status ProvisionStatus `json:"status"`
48 Timestamp int64
49}
50
51type ProvisionRequest struct {
52 Id string `json:"id"`
53 Name string `json:"name"`
54 Ip string `json:"ip"`
55 Mac string `json:"mac"`
56}
57
58type Provisioner interface {
59 Get(id string) (*ProvisionRecord, error)
60 Provision(prov *ProvisionRequest) error
61 Clear(id string) error
62}
63
64type ProvisionerConfig struct {
65 Url string
66}
67
68func NewProvisioner(config *ProvisionerConfig) Provisioner {
69 return config
70}
71
72func (p *ProvisionerConfig) Get(id string) (*ProvisionRecord, error) {
73 resp, err := http.Get(p.Url + "/" + id)
74 if err != nil {
75 return nil, err
76 }
77 defer resp.Body.Close()
78 decoder := json.NewDecoder(resp.Body)
79
80 var record ProvisionRecord
81
82 switch resp.StatusCode {
83 case http.StatusOK, http.StatusAccepted:
84 err = decoder.Decode(&record)
85 if err != nil {
86 return nil, err
87 }
88 return &record, nil
89 case http.StatusNotFound:
90 return nil, nil
91 default:
92 return nil, fmt.Errorf(resp.Status)
93 }
94}
95
96func (p *ProvisionerConfig) Provision(prov *ProvisionRequest) error {
97 hc := http.Client{}
98 data, err := json.Marshal(prov)
99 if err != nil {
100 return err
101 }
102 req, err := http.NewRequest("POST", p.Url, bytes.NewReader(data))
103 if err != nil {
104 return err
105 }
106 req.Header.Add("Content-Type", "application/json")
107 resp, err := hc.Do(req)
108 if err != nil {
109 return err
110 }
111 defer resp.Body.Close()
112 if resp.StatusCode != http.StatusAccepted {
113 return fmt.Errorf("Unexpected response : %s", resp.Status)
114 }
115 return nil
116}
117
118func (p *ProvisionerConfig) Clear(id string) error {
119 hc := http.Client{}
120 req, err := http.NewRequest("DELETE", p.Url+"/"+id, nil)
121 if err != nil {
122 return err
123 }
124
125 resp, err := hc.Do(req)
126 if err != nil {
127 return err
128 }
129 defer resp.Body.Close()
130 if resp.StatusCode != http.StatusOK {
131 return fmt.Errorf("Unexpected response : %s", resp.Status)
132 }
133 return nil
134}