started working on the templating system
[VSCPweb/.git] / vscpweb.go
1 // This is a system for playing with SDN based openvswitches using a simple web
2 // interface. This project will be combined with a CLI version or probably just
3 // made compatible with a core version in the future.
4 package main
5
6 import (
7         "flag"
8         "fmt"
9         "html/template"
10         "math/rand"
11         "net/http"
12         "strconv"
13
14         hh "healthHandlers"
15         //mh "managementHandlers"
16         //vh "virtualAPIHandlers"
17         //ch "controllerHandlers"
18         //sh "staticHandlers"
19
20         "github.com/go-chi/chi/v5"
21         "github.com/go-chi/chi/v5/middleware"
22 )
23
24 func main() {
25         //create a new server and mount the handlers:
26         s := CreateNewServer()
27         s.MountHandlers()
28
29         //Handle the static files
30         fs := http.FileServer(http.Dir("./static/"))
31         s.Router.Handle("/static/*", http.StripPrefix("/static/", fs))
32
33         //staring up the server:
34         port := flag.Int("port", 8001, "Port in which the server will be started")
35         flag.Parse()
36         s.port = strconv.Itoa(*port)
37         s.port = ":" + s.port
38
39         s.startUp()
40 }
41
42 type server struct {
43         Router *chi.Mux
44     port string
45         //suggestion to add config settings or DB in here
46 }
47
48 func CreateNewServer() *server {
49         s := &server{}
50         s.Router = chi.NewRouter()
51         return s
52 }
53
54 //startUp is the function for the server to start listening
55 func (s *server) startUp() {
56     //TODO(josuer08) add other things needed at startup
57     http.ListenAndServe(s.port,s.Router)
58 }
59
60 func (s *server) MountHandlers() {
61
62         //Creation of the router:
63         //logging enables as a middleware
64         s.Router.Use(middleware.Logger)
65         //recover from panics and send a 500 internal error
66         s.Router.Use(middleware.Recoverer)
67         //a middleware to check if the server is alive
68         s.Router.Use(middleware.Heartbeat("/ping"))
69         //a profiler to check healt of server
70         s.Router.Mount("/debug", middleware.Profiler())
71         //personalized 404
72         s.Router.NotFound(GenericHandler404)
73         //personalized 405
74         s.Router.MethodNotAllowed(GenericHandler405)
75
76         //example:
77         //example of a get function and its handler
78         s.Router.Get("/example/{first}/{second:[0-9]+}", ExampleHandler)
79         //s.Router.Get("/", indexHandler)
80
81         //Creating subrouters:
82         //healthRouter check on the health of nodes or main server
83         healthRouter := chi.NewRouter()
84         //controllerRouter Agnostic openVswitch controller bridge
85         controllerRouter := chi.NewRouter()
86         //managementRouter Start, stop, monitoring of the core (mininet)
87         managementRouter := chi.NewRouter()
88         //mininetApiRouter Interface with the virtual environment inside the core (mininet)
89         mininetApiRouter := chi.NewRouter()
90         //might want to check https://go-chi.io/#/pages/routing?id=routing-groups
91         //in order to make groups where you have other middleware like authentication
92
93         //////////////////////////////////possible routing/////////////////////////////
94         //s.Router.Connect(pattern string, h http.HandlerFunc)
95         //s.Router.Delete(pattern string, h http.HandlerFunc)
96         //s.Router.Get(pattern string, h http.HandlerFunc)
97         //s.Router.Head(pattern string, h http.HandlerFunc)
98         //s.Router.Options(pattern string, h http.HandlerFunc)
99         //s.Router.Patch(pattern string, h http.HandlerFunc)
100         //s.Router.Post(pattern string, h http.HandlerFunc)
101         //s.Router.Put(pattern string, h http.HandlerFunc)
102         //s.Router.Trace(pattern string, h http.HandlerFunc)
103         ///////////////////////////////////////////////////////////////////////////////
104
105         //generic ryu version at first...
106         s.Router.Get("/", indexHandler)
107         s.Router.Get("/access", accessHandler)
108         s.Router.Get("/stats",  statsHandler)
109         s.Router.Get("/topology", topologyHandler)
110         //s.Router.Get("/mpstat", )//DEPRECATED see: /masterHealth
111         //s.Router.Get("/ifstat", )//DEPRECATED see: /masterHealth
112         //s.Router.Get("/showtemp", )//DEPRECATED see: /masterHealth
113         //healthRouter.Get("/", )//this renders the health page "/health"
114         //healthRouter.Get("/ping", )// "/rpiping"
115         healthRouter.Get("/masterHealth", hh.MasterHealthHandler) //return a JSON with healt of the master "/free"
116         //controllerRouter.Delete("/flow", )//this is an external request "/flowdel"
117         //controllerRouter.Get("/resetflows", )//not sure if here or managementRouter
118         //controllerRouter.Get("/listswitch", )
119         //controllerRouter.Get("/portDescription", )// "/portsdesc"
120         //controllerRouter.Get("/portStatus", )// "/portsstat"
121         //controllerRouter.Get("/tablestatus", )
122         //controllerRouter.Get("/topology", )// "/gettopo"
123         //controllerRouter.Get("/status", )
124         //mininetApiRouter.Get("/net", )
125         //mininetApiRouter.Get("/nodes", )
126         //mininetApiRouter.Get("/status", )// "/statusnodes"
127         //mininetApiRouter.Get("/intfs", )
128         //mininetApiRouter.Get("/iperf", )
129         //mininetApiRouter.Get("/pingall", )
130         //mininetApiRouter.Get("/sendCommand", )// "/sendcommand"
131         //mininetApiRouter.Get("/placement", )
132         //managementRouter.Get("/controllerData", ) // "/getcontrollerdata"
133         //managementRouter.Get("/vscpData", )// "/getvsorcdata"
134         //managementRouter.Get("/startController", )// "/startcontroller"
135         //managementRouter.Get("/startcontrollerAPI", )// "/startcontrollerrouter"
136         //managementRouter.Get("/stopController", )// "/stopcontroller"
137         //managementRouter.Get("/cancel", )// "/cancel"
138         //managementRouter.Get("/startVsorc", )// "/startvsorc"
139         //managementRouter.Get("/stopVsorc", )// "/stopvsorc"
140         //http.Handle("/", r)
141
142         //Mounting all of the subrouters:
143         s.Router.Mount("/health", healthRouter)
144         s.Router.Mount("/controller", controllerRouter)
145         s.Router.Mount("/management", managementRouter)
146         s.Router.Mount("/virtualAPI", mininetApiRouter)
147
148 }
149
150 // GenericHandler404 is the universal 404 response of this front end
151 func GenericHandler404(w http.ResponseWriter, r *http.Request) {
152
153         w.WriteHeader(404)
154         messages := []string{"route does not exist", "page not found", "resource not found"}
155         randomIndex := rand.Intn(len(messages))
156         w.Write([]byte(messages[randomIndex]))
157 }
158
159 // GenericHandler405 is the universal 405 response of this front end
160 func GenericHandler405(w http.ResponseWriter, r *http.Request) {
161         w.WriteHeader(405)
162         w.Write([]byte("Method not valid"))
163 }
164 func ExampleHandler(w http.ResponseWriter, r *http.Request) {
165         var1 := chi.URLParam(r, "first")
166         var2 := chi.URLParam(r, "second")
167         w.WriteHeader(http.StatusOK)
168         fmt.Fprintf(w, "First: %v\nSecond: %v", var1, var2)
169 }
170
171 /////////THIS BLOCK LOOKS LIKE IT IS NOT DRY BUT IT IS BECAUSE IT WILL LATER
172 //DIFFER WIDELY FROM ONE FUNCTION TO THE NEXT
173 ////////////////////////////////////////////////////////////////////////////////
174 func indexHandler(w http.ResponseWriter, r *http.Request) {
175         passarg := "some passing argument done"
176     viewsHandlerHelper(w, r, "templates/views/index.html", passarg)
177 }
178 func accessHandler(w http.ResponseWriter, r *http.Request) {
179         passarg := "some passing argument done"
180     viewsHandlerHelper(w, r, "templates/views/handler.html", passarg)
181 }
182 func statsHandler(w http.ResponseWriter, r *http.Request) {
183         passarg := "some passing argument done"
184     viewsHandlerHelper(w, r, "templates/views/stats.html", passarg)
185 }
186 func topologyHandler(w http.ResponseWriter, r *http.Request) {
187         passarg := "some passing argument done"
188     viewsHandlerHelper(w, r, "templates/views/topology.html", passarg)
189 }
190 ////////////////////////////////////////////////////////////////////////////////
191
192 func viewsHandlerHelper(w http.ResponseWriter, r *http.Request, file string, argument any) {
193         w.WriteHeader(http.StatusOK)
194
195         indexTemplate := template.Must(template.ParseFiles(file))
196         //check for go partial templates so you can extract blocks you want to use
197         indexTemplate.Execute(w, argument)
198
199 }