forked from openshift/origin
/
server.go
123 lines (110 loc) · 3.32 KB
/
server.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
package server
import (
"crypto/tls"
"fmt"
"net"
"net/http"
"strconv"
"time"
)
// Server is a http.Handler which exposes netutils functionality over HTTP.
type Server struct {
ipam IpamInterface
mux *http.ServeMux
}
type TLSOptions struct {
Config *tls.Config
CertFile string
KeyFile string
}
// IpamInterface contains all the methods required by the server.
type IpamInterface interface {
GetIP() (*net.IPNet, error)
ReleaseIP(ip *net.IPNet) error
//GetStats() string
}
// ListenAndServeNetutilServer initializes a server to respond to HTTP network requests on the ipam interface
func ListenAndServeNetutilServer(ipam IpamInterface, address net.IP, port uint, tlsOptions *TLSOptions) {
handler := NewServer(ipam)
s := &http.Server{
Addr: net.JoinHostPort(address.String(), strconv.FormatUint(uint64(port), 10)),
Handler: handler,
ReadTimeout: 5 * time.Minute,
WriteTimeout: 5 * time.Minute,
MaxHeaderBytes: 1 << 20,
}
if tlsOptions != nil {
s.TLSConfig = tlsOptions.Config
s.ListenAndServeTLS(tlsOptions.CertFile, tlsOptions.KeyFile)
} else {
s.ListenAndServe()
}
}
// NewServer initializes and configures the netutils_server.Server object to handle HTTP requests.
func NewServer(ipam IpamInterface) *Server {
server := Server{
ipam: ipam,
mux: http.NewServeMux(),
}
server.InstallDefaultHandlers()
return &server
}
// InstallDefaultHandlers registers the default set of supported HTTP request patterns with the mux.
func (s *Server) InstallDefaultHandlers() {
s.mux.HandleFunc("/netutils/subnet", s.handleSubnet)
s.mux.HandleFunc("/netutils/ip/", s.handleIP)
s.mux.HandleFunc("/netutils/gateway", s.handleGateway)
s.mux.HandleFunc("/stats", s.handleStats)
}
// error serializes an error object into an HTTP response.
func (s *Server) error(w http.ResponseWriter, err error) {
msg := fmt.Sprintf("Internal Error: %v", err)
http.Error(w, msg, http.StatusInternalServerError)
}
// handleSubnet handles gateway requests
func (s *Server) handleSubnet(w http.ResponseWriter, req *http.Request) {
w.Header().Add("Content-type", "application/json")
w.Write([]byte("Not implemented"))
return
}
// handleGateway handles gateway requests
func (s *Server) handleGateway(w http.ResponseWriter, req *http.Request) {
w.Header().Add("Content-type", "application/json")
w.Write([]byte("Not implemented"))
return
}
// handleIP handles IP requests
func (s *Server) handleIP(w http.ResponseWriter, req *http.Request) {
if req.Method == "GET" {
w.Header().Add("Content-type", "application/json")
ipnet, err := s.ipam.GetIP()
if err != nil {
s.error(w, err)
} else {
w.Write([]byte(ipnet.String()))
}
} else if req.Method == "DELETE" {
ip, ipNet, err := net.ParseCIDR(req.URL.Path[len("/netutils/ip/"):])
if err != nil {
s.error(w, err)
}
delIP := &net.IPNet{IP: ip, Mask: ipNet.Mask}
err = s.ipam.ReleaseIP(delIP)
if err != nil {
s.error(w, err)
}
} else {
http.Error(w, "Method can only be GET/DELETE", http.StatusNotFound)
}
return
}
// handleStats handles stats requests
func (s *Server) handleStats(w http.ResponseWriter, req *http.Request) {
w.Header().Add("Content-type", "application/json")
w.Write([]byte("Not implemented"))
return
}
// ServeHTTP responds to HTTP requests
func (s *Server) ServeHTTP(w http.ResponseWriter, req *http.Request) {
s.mux.ServeHTTP(w, req)
}