blob: 590585b7876cf85bba694e2d5072701d89b9b124 [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. Bainbridge8bc905c2016-05-31 14:07:10 -070014package main
15
16import (
David K. Bainbridge528b3182017-01-23 08:51:59 -080017 "flag"
David K. Bainbridge8bc905c2016-05-31 14:07:10 -070018 "fmt"
David K. Bainbridgea9c2e0a2016-07-01 18:33:50 -070019 "github.com/Sirupsen/logrus"
David K. Bainbridge8bc905c2016-05-31 14:07:10 -070020 "github.com/gorilla/mux"
21 "github.com/kelseyhightower/envconfig"
David K. Bainbridge8bc905c2016-05-31 14:07:10 -070022 "net/http"
David K. Bainbridge528b3182017-01-23 08:51:59 -080023 "os"
David K. Bainbridge8bc905c2016-05-31 14:07:10 -070024)
25
David K. Bainbridge528b3182017-01-23 08:51:59 -080026const appName = "ALLOCATE"
27
David K. Bainbridge8bc905c2016-05-31 14:07:10 -070028type Config struct {
David K. Bainbridge528b3182017-01-23 08:51:59 -080029 Port int `default:"4242" desc:"port on which to listen for requests"`
30 Listen string `default:"0.0.0.0" desc:"IP on which to listen for requests"`
31 Network string `default:"10.0.0.0/24" desc:"subnet to allocate via requests"`
32 RangeLow string `default:"10.0.0.2" envconfig:"RANGE_LOW" desc:"low value in range to allocate"`
33 RangeHigh string `default:"10.0.0.253" envconfig:"RANGE_HIGH" desc:"high value in range to allocate"`
34 LogLevel string `default:"warning" envconfig:"LOG_LEVEL" desc:"detail level for logging"`
35 LogFormat string `default:"text" envconfig:"LOG_FORMAT" desc:"log output format, text or json"`
David K. Bainbridge8bc905c2016-05-31 14:07:10 -070036}
37
38type Context struct {
39 storage Storage
40}
41
David K. Bainbridgea9c2e0a2016-07-01 18:33:50 -070042var log = logrus.New()
David K. Bainbridge528b3182017-01-23 08:51:59 -080043var appFlags = flag.NewFlagSet("", flag.ContinueOnError)
David K. Bainbridgea9c2e0a2016-07-01 18:33:50 -070044
David K. Bainbridge8bc905c2016-05-31 14:07:10 -070045func main() {
46 context := &Context{}
47
48 config := Config{}
David K. Bainbridge528b3182017-01-23 08:51:59 -080049 appFlags.Usage = func() {
50 envconfig.Usage(appName, &config)
51 }
52 if err := appFlags.Parse(os.Args[1:]); err != nil {
53 if err != flag.ErrHelp {
54 os.Exit(1)
55 } else {
56 return
57 }
58 }
59 err := envconfig.Process(appName, &config)
David K. Bainbridge8bc905c2016-05-31 14:07:10 -070060 if err != nil {
David K. Bainbridgea9c2e0a2016-07-01 18:33:50 -070061 log.Fatalf("Unable to parse configuration options : %s", err)
David K. Bainbridge8bc905c2016-05-31 14:07:10 -070062 }
63
David K. Bainbridgea9c2e0a2016-07-01 18:33:50 -070064 switch config.LogFormat {
65 case "json":
66 log.Formatter = &logrus.JSONFormatter{}
67 default:
68 log.Formatter = &logrus.TextFormatter{
69 FullTimestamp: true,
70 ForceColors: true,
71 }
72 }
73
74 level, err := logrus.ParseLevel(config.LogLevel)
75 if err != nil {
76 level = logrus.WarnLevel
77 }
78 log.Level = level
79
80 log.Infof(`Configuration:
David K. Bainbridgeca68f062016-10-27 11:04:33 -070081 LISTEN: %s
82 PORT: %d
83 NETWORK: %s
84 RANGE_LOW: %s
85 RANGE_HIGH: %s
86 LOG_LEVEL: %s
87 LOG_FORMAT: %s`,
88 config.Listen, config.Port,
89 config.Network, config.RangeLow, config.RangeHigh,
David K. Bainbridgea9c2e0a2016-07-01 18:33:50 -070090 config.LogLevel, config.LogFormat)
David K. Bainbridge8bc905c2016-05-31 14:07:10 -070091
92 context.storage = &MemoryStorage{}
David K. Bainbridgeca68f062016-10-27 11:04:33 -070093 context.storage.Init(config.Network, config.RangeLow, config.RangeHigh)
David K. Bainbridge8bc905c2016-05-31 14:07:10 -070094
95 router := mux.NewRouter()
96 router.HandleFunc("/allocations/{mac}", context.ReleaseAllocationHandler).Methods("DELETE")
97 router.HandleFunc("/allocations/{mac}", context.AllocationHandler).Methods("GET")
98 router.HandleFunc("/allocations/", context.ListAllocationsHandler).Methods("GET")
99 router.HandleFunc("/addresses/{ip}", context.FreeAddressHandler).Methods("DELETE")
100 http.Handle("/", router)
101
102 http.ListenAndServe(fmt.Sprintf("%s:%d", config.Listen, config.Port), nil)
103}