move to echo... still not sure about this plugin method

This commit is contained in:
devinchristianson
2020-03-06 15:16:32 -05:00
parent 3b254b0eed
commit e336412272
10 changed files with 96 additions and 256 deletions
-21
View File
@@ -1,21 +0,0 @@
The MIT License (MIT)
Copyright (c) 2011-2014 Dave Gamache
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-68
View File
@@ -1,68 +0,0 @@
# [Skeleton](http://getskeleton.com)
Skeleton is a simple, responsive boilerplate to kickstart any responsive project.
Check out <http://getskeleton.com> for documentation and details.
## Getting started
There are a couple ways to download Skeleton:
- [Download the zip](https://github.com/dhg/Skeleton/releases/download/2.0.4/Skeleton-2.0.4.zip)
- Clone the repo: `git clone https://github.com/dhg/Skeleton.git` (Note: this is under active development, so if you're looking for stable and safe, use the zipped download)
### What's in the download?
The download includes Skeleton's CSS, Normalize CSS as a reset, a sample favicon, and an index.html as a starting point.
```
Skeleton/
├── index.html
├── css/
│ ├── normalize.min.css
│ └── skeleton.css
└── images/
└── favicon.ico
```
### Why it's awesome
Skeleton is lightweight and simple. It styles only raw HTML elements (with a few exceptions) and provides a responsive grid. Nothing more.
- Around 400 lines of CSS unminified and with comments
- It's a starting point, not a UI framework
- No compiling or installing...just vanilla CSS
## Browser support
- Chrome latest
- Firefox latest
- Opera latest
- Safari latest
- IE latest
The above list is non-exhaustive. Skeleton works perfectly with almost all older versions of the browsers above, though IE certainly has large degradation prior to IE9.
## License
All parts of Skeleton are free to use and abuse under the [open-source MIT license](https://github.com/dhg/Skeleton/blob/master/LICENSE.md).
## Extensions
The following are extensions to Skeleton built by the community. They are not officially supported, but all have been tested and are compatible with v2.0 (exact release noted):
- [Skeleton on LESS](https://github.com/whatsnewsaes/Skeleton-less): Skeleton built with LESS for easier replacement of grid, color, and media queries. (Last update was to match v2.0.1)
- [Skeleton on Sass](https://github.com/whatsnewsaes/Skeleton-Sass): Skeleton built with Sass for easier replacement of grid, color, and media queries. (Last update was to match v2.0.1)
Have an extension you want to see here? Just shoot an email to hi@getskeleton.com with your extension!
## Colophon
Skeleton was built using [Sublime Text 3](http://www.sublimetext.com/3) and designed with [Sketch](http://bohemiancoding.com/sketch). The typeface [Raleway](http://www.google.com/fonts/specimen/Raleway) was created by [Matt McInerney](http://matt.cc/) and [Pablo Impallari](http://www.impallari.com/). Code highlighting by Google's [Prettify library](https://code.google.com/p/google-code-prettify/). Icons in the header of the documentation are all derivative work of icons from [The Noun Project](http://thenounproject.com). [Feather](http://thenounproject.com/term/feather/22073) by Zach VanDeHey, [Pen](http://thenounproject.com/term/pen/21163) (with cap) by Ed Harrison, [Pen](http://thenounproject.com/term/pen/32847) (with clicker) by Matthew Hall, and [Watch](http://thenounproject.com/term/watch/48015) by Julien Deveaux.
## Acknowledgement
Skeleton was created by [Dave Gamache](https://twitter.com/dhg) for a better web.
-21
View File
@@ -1,21 +0,0 @@
{
"name": "skeleton",
"version": "2.0.4",
"homepage": "http://getskeleton.com/",
"repository": {
"type": "git",
"url": "https://github.com/dhg/Skeleton"
},
"authors": [
"Dave Gamache <hello@davegamache.com> (http://davegamache.com/)"
],
"description": "Skeleton is a dead-simple, responsive boilerplate to kickstart any responsive project.",
"main": "css/skeleton.css",
"keywords": [
"css",
"skeleton",
"responsive",
"boilerplate"
],
"license": "MIT"
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

-35
View File
@@ -1,35 +0,0 @@
package assets
import (
"fmt"
"net/http"
"strings"
"core-networkmanager/frontend/plugins"
)
func setup() bool {
fileserver := http.FileServer(FileSystem{http.Dir("./assets")})
plugins.RegisterEndpoint("/assets/", http.StripPrefix("/assets", fileserver).ServeHTTP)
return true
}
//FileSystem implements http.Filesystem, with Open() that doesnt allow Dirs
type FileSystem struct {
fs http.FileSystem
}
//Open overrides http.FileSystem.Open in order to prevent Directory access
func (cfs FileSystem) Open(path string) (http.File, error) {
fmt.Println("filepath",path)
f, err := cfs.fs.Open(path)
if err != nil {
return nil, err
}
st, err := f.Stat()
if st.IsDir() {
fmt.Println("Dir", path, "is not allowed")
index := strings.TrimSuffix(path, "/") + "/index.html"
if _, err := cfs.fs.Open(index); err != nil {
return nil, err
}
}
return f, nil
}
-32
View File
@@ -1,32 +0,0 @@
package assets
import (
"sync"
"core-networkmanager/frontend/plugins"
)
var (
mux sync.Mutex
active bool
)
//init registers the plugin as available with Plugin manager
func init() {
plugins.RegisterPlugin("assets", &plugin{})
}
//plugin struct that for the plugin to impliment required and optional interfaces as defined in Plugin package
type plugin struct {}
//Activate sets up endpoints and databases, and any other initialization
func (p plugin ) Activate () {
if(!active) {
mux.Lock()
active = setup()
mux.Unlock()
}
}
//Active returns true if the plugin has already been activated
func (p plugin ) Active () bool {
return active
}
+44 -27
View File
@@ -1,25 +1,32 @@
package plugins
import (
"database/sql"
"log"
"sync"
"net/http"
"database/sql"
"github.com/labstack/echo"
)
//Global variables
var (
pluginMu sync.RWMutex
plugins = make(map[string]Plugin)
activePlugins = make(map[string]Plugin)
universalPlugins [] UniversalHandlerPlugin
endpointMappings = make(map[string]func(http.ResponseWriter, *http.Request))
mux *http.ServeMux
db *sql.DB
pluginMu sync.RWMutex
plugins = make(map[string]Plugin)
activePlugins = make(map[string]Plugin)
universalPlugins []UniversalHandlerPlugin
endpointMappings = make([]map[string]func(echo.Context) error, 4)
mux *echo.Echo
db *sql.DB
)
func init() {
for key := range endpointMappings {
endpointMappings[key] = make(map[string]func(echo.Context) error)
}
}
//SetupPlugins activates plugins and loads endpoints
func SetupPlugins(m *http.ServeMux, d *sql.DB, names[] string) {
func SetupPlugins(m *echo.Echo, d *sql.DB, names []string) {
mux = m
db = d
for _, n := range names {
@@ -31,26 +38,36 @@ func SetupPlugins(m *http.ServeMux, d *sql.DB, names[] string) {
universalPlugins = append(universalPlugins, p)
}
}
for key, element := range endpointMappings {
mux.HandleFunc(key, chainUniversalHandlers(element))
}
mux.Static("/assets", "assets ")
for key, element := range endpointMappings[GET] {
mux.GET(key, chainUniversalHandlers(element))
}
for key, element := range endpointMappings[PUT] {
mux.GET(key, chainUniversalHandlers(element))
}
for key, element := range endpointMappings[POST] {
mux.GET(key, chainUniversalHandlers(element))
}
for key, element := range endpointMappings[DELETE] {
mux.GET(key, chainUniversalHandlers(element))
}
}
func chainUniversalHandlers(h http.HandlerFunc) http.HandlerFunc {
func chainUniversalHandlers(h func(echo.Context) error) func(echo.Context) error {
if len(universalPlugins) < 1 {
return h
return h
}
wrapped := h
// loop in reverse to preserve middleware order
for i := len(universalPlugins) - 1; i >= 0; i-- {
wrapped = universalPlugins[i].UniversalHandler(wrapped)
wrapped = universalPlugins[i].UniversalHandler(wrapped)
}
return wrapped
}
}
//RegisterPlugin registers plugins. Should be called using init function in plugin package
func RegisterPlugin(name string, p Plugin) {
@@ -62,16 +79,16 @@ func RegisterPlugin(name string, p Plugin) {
if _, duplicate := plugins[name]; duplicate {
log.Fatal("Plugin name already taken")
}
plugins[name] = p
plugins[name] = p
}
//RegisterEndpoint points an endpoint to a specific plugin while keeping
func RegisterEndpoint(pattern string, handler func(http.ResponseWriter, *http.Request)) {
//RegisterEndpoint points an endpoint to a specific plugin while keeping
func RegisterEndpoint(request REQUEST, pattern string, handler func(echo.Context) error) {
if handler == nil {
log.Fatalf("Handler for endpoint %s is nil", pattern)
}
if _, duplicate := endpointMappings[pattern]; duplicate {
if _, duplicate := endpointMappings[request][pattern]; duplicate {
log.Fatalf("Endpoint %s has already been allocated to a different plugin", pattern)
}
endpointMappings[pattern] = handler
}
endpointMappings[request][pattern] = handler
}
+9 -32
View File
@@ -1,46 +1,23 @@
package root
package root
import (
"fmt"
"log"
"net/http"
"html/template"
"core-networkmanager/frontend/plugins"
"net/http"
"github.com/labstack/echo"
)
func setup() bool {
plugins.RegisterEndpoint("/", homePage)
plugins.RegisterEndpoint(plugins.GET, "/", homePage)
return true
}
//Page struct to hold per-page data
type page struct {
Location string
Name string
Name string
}
func homePage(w http.ResponseWriter, r *http.Request) {
if r.Method == "GET" {
t, err := template.ParseFiles("index.gohtml")
if err != nil {
log.Fatal("Parse failed: ", err)
}
home := page{Location: "/", Name: "Home"}
search := page{Location: "/search", Name: "Search"}
data := struct {
Pages []*page
Hosts []*plugins.CoreHost
}{
[]*page{ &home, &search },
nil,
}
if err := t.ExecuteTemplate(w, "index", data); err != nil {
log.Fatal("ExecuteTemplate failed:", err)
}
} else {
r.ParseForm()
// logic part of log in
fmt.Println("username:", r.Form["username"])
fmt.Println("password:", r.Form["password"])
}
}
func homePage(c echo.Context) error {
return c.String(http.StatusOK, "Hello, World!")
}
+35 -11
View File
@@ -1,56 +1,80 @@
package plugins
import (
"net/http"
"net"
"github.com/labstack/echo"
)
//REQUEST - endpoint request type
type REQUEST int
const (
//GET - get endpoint behavior
GET REQUEST = 0
//PUT - put endpoint behavior
PUT REQUEST = 1
//POST - post endpoint behavior
POST REQUEST = 2
//DELETE - delete endpoint behavior
DELETE REQUEST = 3
)
//Plugin is an interface defining all plugin exported functions
type Plugin interface {
Activate() //should register endpoints and add database tables etc
Activate() //should register endpoints and add database tables etc
Active() bool //should check if plugin has already been activated
}
//UniversalHandlerPlugin is an interface that extends the Plugin interface, for if a plugin needs to be called on all endpoints
type UniversalHandlerPlugin interface {
Plugin
UniversalHandler(http.HandlerFunc) http.HandlerFunc
UniversalHandler(func(echo.Context) error) func(echo.Context) error
}
//HostHandlerPlugin is an interface that extends the Plugin interface, in order to modify Hosts
type HostHandlerPlugin interface {
Plugin
HostHandler(CoreHost, CoreOption) (CoreHost, CoreOption)
}
//DomainHandlerPlugin is an interface that extends the Plugin interface, in order to modify Domains
type DomainHandlerPlugin interface {
Plugin
DomainHandler(CoreDomain, CoreOption) (CoreDomain, CoreOption)
}
//NetworkHandlerPlugin is an interface that extends the Plugin interface, in order to modify Networks
type NetworkHandlerPlugin interface {
Plugin
NetworkHandler(CoreNetwork, CoreOption) (CoreNetwork, CoreOption)
}
//CoreHost is the struct used to pass host data between plugins and the plugin package
type CoreHost struct {
ips [] net.IP
name string
domain CoreDomain
ips []net.IP
name string
domain CoreDomain
options map[string]CoreOption
}
//CoreDomain is the struct used to pass Domain data between plugins and the plugin package
type CoreDomain struct {
domain string
tld string
domain string
tld string
options map[string]CoreOption
}
//CoreNetwork is the struct used to pass Network data between plugins and the plugin package
type CoreNetwork struct {
network net.IPNet
options map[string]CoreOption
}
//CoreOption is the struct used to pass Network data between plugins and the plugin package
type CoreOption struct {
s string
i int
}
s string
i int
display string
linkto string
}
+8 -9
View File
@@ -1,23 +1,22 @@
package main
import (
"core-networkmanager/frontend/plugins"
_ "core-networkmanager/frontend/plugins/root"
"log"
"net/http"
"strconv"
"core-networkmanager/frontend/plugins"
_ "core-networkmanager/frontend/plugins/root"
_ "core-networkmanager/frontend/plugins/assets"
"github.com/labstack/echo"
)
func main() {
initDB()
defer db.Close()
var port = 8080
mux := http.NewServeMux()
activePlugins := []string{"root", "assets"}
mux := echo.New()
activePlugins := []string{"root"}
plugins.SetupPlugins(mux, nil, activePlugins)
err := http.ListenAndServe(":" + strconv.Itoa(port), mux)
if(err != nil) {
err := http.ListenAndServe(":"+strconv.Itoa(port), mux)
if err != nil {
log.Fatal("ListenAndServe failed with error: ", err)
}