CORD-313 refactor configuration generator
Change-Id: I4428ff0b67ee8d6ebb9b7009cd82413416c25a84
diff --git a/config-generator/configGen.go b/config-generator/configGen.go
index b0460f0..c23ce53 100644
--- a/config-generator/configGen.go
+++ b/config-generator/configGen.go
@@ -14,83 +14,29 @@
package main
import (
- "encoding/json"
- "errors"
"fmt"
+ "net/http"
+
+ "github.com/Sirupsen/logrus"
+
"github.com/gorilla/mux"
"github.com/kelseyhightower/envconfig"
- "io/ioutil"
- "log"
- "net/http"
- "os"
- "strings"
- "text/template"
)
-var unmarshalError = errors.New("Error Unmarshaling the JSON Data\n")
-
type Config struct {
- Port string `default:"8181"`
- IP string `default:"127.0.0.1"`
- SwitchCount int `default:"0"`
- HostCount int `default:"0"`
- Username string `default:"karaf"`
- Password string `default:"karaf"`
- LogLevel string `default:"warning" envconfig:"LOG_LEVEL"`
- LogFormat string `default:"text" envconfig:"LOG_FORMAT"`
- ConfigServerPort string `default:"1337"`
- ConfigServerIP string `default:"127.0.0.1"`
-}
+ Port int `default:"1337"`
+ Listen string `default:"0.0.0.0"`
+ Controller string `default:"http://%s:%s@127.0.0.1:8181"`
+ Username string `default:"karaf"`
+ Password string `default:"karaf"`
+ LogLevel string `default:"warning" envconfig:"LOG_LEVEL"`
+ LogFormat string `default:"text" envconfig:"LOG_FORMAT"`
-type hosts struct {
- Host []struct {
- Mac string `json:"mac"`
- IpAddresses []string `json:"ipAddresses"`
- Location struct {
- ElementID string `json:"elementId`
- Port string `json:"port"`
- } `json:"location"`
- Comma string
- Gateway string
- } `json:"hosts"`
-}
-
-type devices struct {
- Device []struct {
- Id string `json:"id"`
- ChassisId string `json:"chassisId"`
- Annotations struct {
- ManagementAddress string `json:"managementAddress"`
- } `json:"annotations"`
- Comma string `default:","`
- } `json:"devices"`
-}
-
-type onosLinks struct {
- Links []struct {
- Src struct {
- Port string `json:"port"`
- Device string `json:"device"`
- } `json:"src"`
- Dst struct {
- Port string `json:"port"`
- Device string `json:"device"`
- } `json:"dst"`
- } `json:"links"`
-}
-
-type linkStructJSON struct {
- Val string
- Comma string
-}
-
-type ConfigParam struct {
- SwitchCount int `json:"switchcount"`
- HostCount int `json:"hostcount"`
- ONOSIP string `json:"onosip"`
+ connect string
}
var c Config
+var log = logrus.New()
func main() {
@@ -99,207 +45,39 @@
log.Fatalf("[ERROR] Unable to parse configuration options : %s", err)
}
+ switch c.LogFormat {
+ case "json":
+ log.Formatter = &logrus.JSONFormatter{}
+ default:
+ log.Formatter = &logrus.TextFormatter{
+ FullTimestamp: true,
+ ForceColors: true,
+ }
+ }
+
+ level, err := logrus.ParseLevel(c.LogLevel)
+ if err != nil {
+ level = logrus.WarnLevel
+ }
+ log.Level = level
+
+ log.Infof(`Configuration:
+ LISTEN: %s
+ PORT: %d
+ CONTROLLER: %s
+ USERNAME: %s
+ PASSWORD: %s
+ LOG_LEVEL: %s
+ LOG_FORMAT: %s`,
+ c.Listen, c.Port, c.Controller,
+ c.Username, c.Password,
+ c.LogLevel, c.LogFormat)
+
router := mux.NewRouter()
- router.HandleFunc("/config/", ConfigGenHandler).Methods("POST")
+ router.HandleFunc("/config/", c.configGenHandler).Methods("POST")
http.Handle("/", router)
- fmt.Println("Config Generator server listening at: " + c.ConfigServerIP + ":" + c.ConfigServerPort)
+ c.connect = fmt.Sprintf(c.Controller, c.Username, c.Password)
- http.ListenAndServe(c.ConfigServerIP+":"+c.ConfigServerPort, nil)
-
-}
-
-func ConfigGenHandler(w http.ResponseWriter, r *http.Request) {
- var para ConfigParam
-
- decoder := json.NewDecoder(r.Body)
- defer r.Body.Close()
- if err := decoder.Decode(¶); err != nil {
- fmt.Errorf("Unable to decode request to provision : %s", err)
- http.Error(w, err.Error(), http.StatusBadRequest)
- return
- }
-
- c.HostCount = para.HostCount
- c.SwitchCount = para.SwitchCount
- c.IP = para.ONOSIP
-
- onos := "http://" + c.Username + ":" + c.Password + "@" + c.IP + ":" + c.Port
-
- err := os.Remove("network-cfg.json")
- if err != nil {
- log.Println("Warning: no file called network-cfg.json (ignore if this is the first run)")
- }
- err = generateDevicesJSON(onos)
- if err != nil {
- w.WriteHeader(http.StatusInternalServerError)
- fmt.Fprintf(w, err.Error())
- return
- }
- err = generateLinkJSON(onos)
- if err != nil {
- w.WriteHeader(http.StatusInternalServerError)
- fmt.Fprintf(w, err.Error())
- return
- }
- err = generateHostJSON(onos)
- if err != nil {
- w.WriteHeader(http.StatusInternalServerError)
- fmt.Fprintf(w, err.Error())
- return
- }
-
- fmt.Println("Config file generated: network-cfg.json")
-
- data, err := ioutil.ReadFile("network-cfg.json")
- check(err)
-
- w.WriteHeader(http.StatusAccepted)
- fmt.Fprintf(w, string(data))
-
-}
-
-func writeToFile(object interface{}, t string) {
- f, err := os.OpenFile("network-cfg.json", os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
- if err != nil {
- panic(err)
- }
-
- defer f.Close()
-
- tpl, err := template.ParseFiles(t)
- check(err)
- err = tpl.Execute(f, object)
- check(err)
-}
-
-func generateDevicesJSON(onos string) error {
- ds, err := getData(onos + "/onos/v1/devices")
- if err != nil {
- return err
- }
-
- var d devices
- err = json.Unmarshal(ds, &d)
- if err != nil {
- return unmarshalError
- }
-
- if len(d.Device) != c.SwitchCount {
- _ = os.Remove("network-cfg.json")
- log.Println("[INFO] Cleaning up unfinished config file")
- e := fmt.Sprintf("[ERROR] Number of switches configured don't match actual switches connected to the controller. Configured: %d, connected: %d", c.SwitchCount, len(d.Device))
- log.Println(e)
- return errors.New(e)
- }
-
- for k, _ := range d.Device {
- d.Device[k].Comma = ","
- if k >= len(d.Device)-1 {
- d.Device[k].Comma = ""
- }
- }
-
- writeToFile(d.Device, "devices.tpl")
- return nil
-
-}
-
-func generateHostJSON(onos string) error {
- hs, err := getData(onos + "/onos/v1/hosts")
- if err != nil {
- return err
- }
- var h hosts
- err = json.Unmarshal(hs, &h)
- if err != nil {
- return unmarshalError
- }
-
- if len(h.Host) != c.HostCount {
- _ = os.Remove("network-cfg.json")
- log.Println("[INFO] Cleaning up unfinished config file")
- e := fmt.Sprintf("[ERROR] Number of hosts configured don't match actual hosts visible to the controller. Configured: %d, connected: %d", c.HostCount, len(h.Host))
- log.Println(e)
- return errors.New(e)
- }
-
- for k, _ := range h.Host {
-
- h.Host[k].Comma = ","
- if k >= len(h.Host)-1 {
- h.Host[k].Comma = ""
- }
-
- parts := strings.Split(h.Host[k].IpAddresses[0], ".")
- ip := ""
- for _, v := range parts[:len(parts)-1] {
- ip = ip + v + "."
- }
- h.Host[k].Gateway = ip
- }
-
- writeToFile(h.Host, "ports.tpl")
-
- writeToFile(h.Host, "hosts.tpl")
- return nil
-
-}
-
-func generateLinkJSON(onos string) error {
-
- links, err := getData(onos + "/onos/v1/links")
- if err != nil {
- return err
- }
-
- var l onosLinks
- err = json.Unmarshal(links, &l)
- if err != nil {
- return unmarshalError
- }
-
- var in []linkStructJSON
-
- for k, v := range l.Links {
-
- comma := ","
- val := fmt.Sprint(v.Src.Device + "/" + v.Src.Port + "-" + v.Dst.Device + "/" + v.Dst.Port)
- if k >= len(l.Links)-1 {
- comma = ""
- }
-
- tmp := linkStructJSON{val, comma}
- in = append(in, tmp)
-
- }
-
- writeToFile(in, "links.tpl")
-
- return nil
-
-}
-
-func getData(url string) ([]byte, error) {
-
- resp, err := http.Get(url)
- if err != nil {
- return nil, errors.New("Error getting data from the URL\n")
- }
-
- defer resp.Body.Close()
-
- body, err := ioutil.ReadAll(resp.Body)
- if err != nil {
- return nil, errors.New("Error reading data from response body\n")
- }
-
- return body, nil
-
-}
-
-func check(e error) {
- if e != nil {
- panic(e)
- }
+ panic(http.ListenAndServe(fmt.Sprintf(":%d", c.Port), nil))
}