Skip to content
Snippets Groups Projects
http.go 4.67 KiB
Newer Older
  • Learn to ignore specific revisions
  • Manuel Kieweg's avatar
    Manuel Kieweg committed
    package nucleus
    
    import (
    	"code.fbi.h-da.de/cocsn/gosdn/forks/goarista/gnmi"
    
    	"context"
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    	"fmt"
    	"github.com/google/uuid"
    	gpb "github.com/openconfig/gnmi/proto/gnmi"
    	log "github.com/sirupsen/logrus"
    	"net/http"
    	"net/url"
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    	"sync"
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    var httpOnce sync.Once
    
    
    func stopHttpServer() error {
    	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
    	defer cancel()
    	log.Info("shutting down http server")
    	return c.httpServer.Shutdown(ctx)
    }
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    func registerHttpHandler() {
    
    	defer func() {
    		if r := recover(); r != nil {
    			fmt.Println("Recovered in f", r)
    		}
    	}()
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    	http.HandleFunc("/api", httpHandler)
    
    	http.HandleFunc("/livez", healthCheck)
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    	http.HandleFunc("/readyz", readynessCheck)
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    
    
    // deprecated
    
    func httpAPI() (err error) {
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    	coreLock.Lock()
    	defer coreLock.Unlock()
    	httpOnce.Do(registerHttpHandler)
    
    	c.httpServer = &http.Server{Addr: ":8080"}
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    	go func() {
    
    		err = c.httpServer.ListenAndServe()
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    		if err != nil {
    			return
    		}
    	}()
    	return nil
    }
    
    
    func healthCheck(writer http.ResponseWriter, request *http.Request) {
    	writer.WriteHeader(http.StatusOK)
    }
    
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    func readynessCheck(writer http.ResponseWriter, request *http.Request) {
    	writer.WriteHeader(http.StatusOK)
    }
    
    
    // nolint
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    func httpHandler(writer http.ResponseWriter, request *http.Request) {
    	log.WithFields(log.Fields{
    		"request": request,
    	}).Debug("incoming request")
    
    	query, err := url.ParseQuery(request.URL.RawQuery)
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    	if err != nil {
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    		log.Error(err)
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    		writer.WriteHeader(http.StatusBadRequest)
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    		return
    	}
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    
    	id, err := uuid.Parse(query.Get("uuid"))
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    	if err != nil {
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    		log.Error(err)
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    	}
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    
    	pid, err := uuid.Parse(query.Get("pnd"))
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    	if err != nil {
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    		log.Error(err)
    
    	sid, err := uuid.Parse(query.Get("sbi"))
    	if err != nil {
    		log.Error(err)
    	}
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    
    
    	var pnd PrincipalNetworkDomain
    	var sbi SouthboundInterface
    	if query.Get("q") != "init" && query.Get("q") != "getIDs" {
    		pnd, err = c.pndc.get(pid)
    		if err != nil {
    			log.Error(err)
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    			writer.WriteHeader(http.StatusInternalServerError)
    			return
    
    		}
    		sbic := pnd.GetSBIs()
    		sbi, err = sbic.(*sbiStore).get(sid)
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    		if err != nil {
    			log.WithFields(log.Fields{
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    				"requested uuid":  sid,
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    				"available uuids": sbic.(*sbiStore).UUIDs(),
    			}).Error(err)
    			writer.WriteHeader(http.StatusInternalServerError)
    			return
    		}
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    	switch query.Get("q") {
    	case "addDevice":
    		d, err := NewDevice(sbi, &GnmiTransportOptions{
    			Config: gnmi.Config{
    				Addr:     query.Get("address"),
    				Password: query.Get("password"),
    				Username: query.Get("username"),
    				Encoding: gpb.Encoding_JSON_IETF,
    			},
    			SetNode:   sbi.SetNode(),
    			Unmarshal: sbi.(*OpenConfig).Unmarshal(),
    			RespChan:  make(chan *gpb.SubscribeResponse),
    		})
    		err = pnd.AddDevice(d)
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    		if err != nil {
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    			writer.WriteHeader(http.StatusInternalServerError)
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    			log.Error(err)
    			return
    		}
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    		writer.WriteHeader(http.StatusCreated)
    		fmt.Fprintf(writer, "device added\n")
    
    		fmt.Fprintf(writer, "UUID: %v\n", d.UUID)
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    	case "request":
    		err = pnd.Request(id, query.Get("path"))
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    		if err != nil {
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    			switch err.(type) {
    			case *ErrNotFound:
    				writer.WriteHeader(http.StatusNotFound)
    			default:
    				writer.WriteHeader(http.StatusInternalServerError)
    			}
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    			log.Error(err)
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    			return
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    		}
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    		writer.WriteHeader(http.StatusOK)
    	case "requestAll":
    		err = pnd.RequestAll(query.Get("path"))
    		if err != nil {
    			switch err.(type) {
    			case *ErrNotFound:
    				writer.WriteHeader(http.StatusNotFound)
    			default:
    				writer.WriteHeader(http.StatusInternalServerError)
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    			}
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    			log.Error(err)
    			return
    		}
    		writer.WriteHeader(http.StatusOK)
    	case "getDevice":
    		device, err := pnd.MarshalDevice(id)
    		if err != nil {
    			switch err.(type) {
    			case *ErrNotFound:
    				writer.WriteHeader(http.StatusNotFound)
    			default:
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    				writer.WriteHeader(http.StatusInternalServerError)
    			}
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    			log.Error(err)
    			return
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    		}
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    		writer.Header().Set("Content-Type", "application/json")
    		fmt.Fprintf(writer, "%v", device)
    	case "getIDs":
    
    		writeIDs := func(typ string, ids []uuid.UUID) {
    			fmt.Fprintf(writer, "%v:\n", typ)
    			for i, id := range ids {
    				fmt.Fprintf(writer, "%v: %v\n", i+1, id)
    			}
    		}
    		writeIDs("PNDs", c.pndc.UUIDs())
    		writeIDs("SBIs", c.sbic.UUIDs())
    		if pnd != nil {
    			writeIDs("Devices", pnd.(*pndImplementation).devices.UUIDs())
    		}
    	case "init":
    		writeIDs := func(typ string, ids []uuid.UUID) {
    			for _, id := range ids {
    				fmt.Fprintf(writer, "%v", id)
    			}
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    		}
    
    		writeIDs("PNDs", c.pndc.UUIDs())
    		writeIDs("SBIs", c.sbic.UUIDs())
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    	case "set":
    		resp, err := pnd.(*pndImplementation).Set(id, query.Get("path"), query.Get("value"))
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    		if err != nil {
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    			writer.WriteHeader(http.StatusInternalServerError)
    			log.Error(err)
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    			return
    		}
    
    Manuel Kieweg's avatar
    Manuel Kieweg committed
    		writer.WriteHeader(http.StatusOK)
    		fmt.Fprintln(writer, resp)
    	default:
    		writer.WriteHeader(http.StatusBadRequest)
    	}