Coveralls logob
Coveralls logo
  • Home
  • Features
  • Pricing
  • Docs
  • Sign In

weaveworks / weave / 10517

2 Aug 2018 - 10:34 coverage increased (+0.2%) to 71.094%
10517

Pull #3270

circleci

Bryan Boreham
Specify https for security
Pull Request #3270: Convert CI build to CircleCI 2.0

8522 of 11987 relevant lines covered (71.09%)

85434.02 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

52.7
/ipam/http.go
1
package ipam
2

3
import (
4
        "encoding/json"
5
        "fmt"
6
        "net/http"
7

8
        "github.com/gorilla/mux"
9

10
        "github.com/weaveworks/weave/common"
11
        "github.com/weaveworks/weave/common/docker"
12
        "github.com/weaveworks/weave/net/address"
13
)
14

UNCOV
15
func badRequest(w http.ResponseWriter, err error) {
!
UNCOV
16
        http.Error(w, err.Error(), http.StatusBadRequest)
!
UNCOV
17
        common.Log.Warningln("[allocator]:", err.Error())
!
UNCOV
18
}
!
19

20
func parseCIDR(w http.ResponseWriter, cidrStr string, net bool) (address.CIDR, bool) {
108×
21
        var cidr address.CIDR
108×
22
        var err error
108×
23
        if net {
126×
24
                cidr, err = ParseCIDRSubnet(cidrStr)
18×
25
        } else {
108×
26
                cidr, err = address.ParseCIDR(cidrStr)
90×
27
        }
90×
28
        if err != nil {
108×
UNCOV
29
                badRequest(w, err)
!
UNCOV
30
                return address.CIDR{}, false
!
UNCOV
31
        }
!
32
        return cidr, true
108×
33
}
34

35
func writeAddresses(w http.ResponseWriter, cidrs []address.CIDR) {
11×
36
        for i, cidr := range cidrs {
16×
37
                fmt.Fprint(w, cidr)
5×
38
                if i < len(cidrs)-1 {
5×
39
                        w.Write([]byte{' '})
!
40
                }
!
41
        }
42
}
43

44
func hasBeenCancelled(dockerCli *docker.Client, closedChan <-chan bool, ident string, checkAlive bool) func() bool {
202×
45
        return func() bool {
428×
46
                select {
226×
47
                case <-closedChan:
!
48
                        return true
!
49
                default:
226×
50
                        res := checkAlive && dockerCli != nil && dockerCli.IsContainerNotRunning(ident)
226×
51
                        checkAlive = false // we check only once; if the container dies later we learn about that through events
226×
52
                        return res
226×
53
                }
54
        }
55
}
56

57
func cancellationErr(w http.ResponseWriter, err error) bool {
!
58
        if _, ok := err.(*errorCancelled); ok {
!
59
                common.Log.Infoln("[allocator]:", err.Error())
!
60
                fmt.Fprint(w, "cancelled")
!
61
                return true
!
62
        }
!
63
        return false
!
64
}
65

66
func (alloc *Allocator) handleHTTPAllocate(dockerCli *docker.Client, w http.ResponseWriter, ident string, checkAlive bool, subnet address.CIDR) {
112×
67
        addr, err := alloc.Allocate(ident, subnet, checkAlive,
112×
68
                hasBeenCancelled(dockerCli, w.(http.CloseNotifier).CloseNotify(), ident, checkAlive))
112×
69
        if err != nil {
112×
70
                if !cancellationErr(w, err) {
!
71
                        badRequest(w, err)
!
72
                }
!
73
                return
!
74
        }
75
        fmt.Fprintf(w, "%s/%d", addr, subnet.PrefixLen)
111×
76
}
77

78
func (alloc *Allocator) handleHTTPClaim(dockerCli *docker.Client, w http.ResponseWriter, ident string, cidr address.CIDR, checkAlive, noErrorOnUnknown bool) {
90×
79
        err := alloc.Claim(ident, cidr, checkAlive, noErrorOnUnknown,
90×
80
                hasBeenCancelled(dockerCli, w.(http.CloseNotifier).CloseNotify(), ident, checkAlive))
90×
81
        if err != nil {
90×
82
                if !cancellationErr(w, err) {
!
83
                        badRequest(w, fmt.Errorf("Unable to claim: %s", err))
!
84
                }
!
85
                return
!
86
        }
87
        w.WriteHeader(204)
90×
88
}
89

90
// HandleHTTP wires up ipams HTTP endpoints to the provided mux.
91
func (alloc *Allocator) HandleHTTP(router *mux.Router, defaultSubnet address.CIDR, dockerCli *docker.Client) {
110×
92
        router.Methods("GET").Path("/ipinfo/defaultsubnet").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
110×
93
                fmt.Fprintf(w, "%s", defaultSubnet)
!
94
        })
!
95

96
        router.Methods("PUT").Path("/ip/{id}/{ip}/{prefixlen}").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
200×
97
                vars := mux.Vars(r)
90×
98
                if cidr, ok := parseCIDR(w, vars["ip"]+"/"+vars["prefixlen"], false); ok {
180×
99
                        ident := vars["id"]
90×
100
                        checkAlive := r.FormValue("check-alive") == "true"
90×
101
                        noErrorOnUnknown := r.FormValue("noErrorOnUnknown") == "true"
90×
102
                        alloc.handleHTTPClaim(dockerCli, w, ident, cidr, checkAlive, noErrorOnUnknown)
90×
103
                }
90×
104
        })
105

106
        router.Methods("GET").Path("/ring").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
115×
107
                alloc.Prime()
5×
108
        })
5×
109

110
        router.Methods("GET").Path("/ip/{id}/{ip}/{prefixlen}").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
114×
111
                vars := mux.Vars(r)
4×
112
                if subnet, ok := parseCIDR(w, vars["ip"]+"/"+vars["prefixlen"], true); ok {
8×
113
                        cidrs, err := alloc.Lookup(vars["id"], subnet.HostRange())
4×
114
                        if err != nil {
4×
115
                                http.NotFound(w, r)
!
116
                                return
!
117
                        }
!
118
                        writeAddresses(w, cidrs)
4×
119
                }
120
        })
121

122
        router.Methods("GET").Path("/ip/{id}").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
117×
123
                addrs, err := alloc.Lookup(mux.Vars(r)["id"], defaultSubnet.HostRange())
7×
124
                if err != nil {
7×
125
                        http.NotFound(w, r)
!
126
                        return
!
127
                }
!
128
                writeAddresses(w, addrs)
7×
129
        })
130

131
        router.Methods("GET").Path("/ip").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
110×
132
                type mapping struct {
!
133
                        ContainerID string   `json:"containerid"`
!
134
                        Addrs       []string `json:"addrs"`
!
135
                }
!
136

!
137
                type mappings struct {
!
138
                        Owned []mapping `json:"owned"`
!
139
                }
!
140

!
141
                resultChan := make(chan mappings)
!
142
                alloc.actionChan <- func() {
!
143
                        ms := mappings{}
!
144
                        for containerid, d := range alloc.owned {
!
145
                                m := mapping{
!
146
                                        ContainerID: containerid,
!
147
                                        Addrs:       []string{},
!
148
                                }
!
149
                                for _, addr := range d.Cidrs {
!
150
                                        m.Addrs = append(m.Addrs, addr.String())
!
151
                                }
!
152
                                ms.Owned = append(ms.Owned, m)
!
153
                        }
154
                        resultChan <- ms
!
155
                }
156
                ms := <-resultChan
!
157

!
158
                w.Header().Set("Content-Type", "application/json")
!
159
                if err := json.NewEncoder(w).Encode(ms); err != nil {
!
160
                        common.Log.Warningln("[allocator]:", err.Error())
!
161
                }
!
162
        })
163

164
        router.Methods("POST").Path("/ip/{id}/{ip}/{prefixlen}").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
124×
165
                vars := mux.Vars(r)
14×
166
                if subnet, ok := parseCIDR(w, vars["ip"]+"/"+vars["prefixlen"], true); ok {
28×
167
                        alloc.handleHTTPAllocate(dockerCli, w, vars["id"], r.FormValue("check-alive") == "true", subnet)
14×
168
                }
14×
169
        })
170

171
        router.Methods("POST").Path("/ip/{id}").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
208×
172
                vars := mux.Vars(r)
98×
173
                alloc.handleHTTPAllocate(dockerCli, w, vars["id"], r.FormValue("check-alive") == "true", defaultSubnet)
98×
174
        })
98×
175

176
        router.Methods("DELETE").Path("/ip/{id}/{ip}").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
111×
177
                vars := mux.Vars(r)
1×
178
                ident := vars["id"]
1×
179
                ipStr := vars["ip"]
1×
180
                if ip, err := address.ParseIP(ipStr); err != nil {
1×
181
                        badRequest(w, err)
!
182
                        return
!
183
                } else if err := alloc.Free(ident, ip); err != nil {
1×
184
                        badRequest(w, fmt.Errorf("Unable to free: %s", err))
!
185
                        return
!
186
                }
!
187

188
                w.WriteHeader(204)
1×
189
        })
190

191
        router.Methods("DELETE").Path("/ip/{id}").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
119×
192
                ident := mux.Vars(r)["id"]
9×
193
                if err := alloc.Delete(ident); err != nil {
9×
194
                        badRequest(w, err)
!
195
                        return
!
196
                }
!
197

198
                w.WriteHeader(204)
9×
199
        })
200

201
        router.Methods("GET").Path("/ipinfo/tracker").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
210×
202
                fmt.Fprintf(w, alloc.tracker.String())
100×
203
        })
100×
204
}
Troubleshooting · Open an Issue · Sales · Support · ENTERPRISE · CAREERS · STATUS
BLOG · TWITTER · Legal & Privacy · Supported CI Services · What's a CI service? · Automated Testing

© 2022 Coveralls, Inc