forked from OpenPDU/openpdu
first mockup in go
This commit is contained in:
196
source/exmain.go
Normal file
196
source/exmain.go
Normal file
@@ -0,0 +1,196 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"gopkg.in/macaron.v1"
|
||||
// "github.com/go-macaron/pongo2"
|
||||
mypongo2 "github.com/flosch/pongo2"
|
||||
"log"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const CFGFILE = "/config/config.json"
|
||||
|
||||
const WEBSITETPLFILE = "/app/website.tpl"
|
||||
const WEBSITENGINXFILE = "/etc/nginx/conf.d/websites.conf"
|
||||
|
||||
const ADMINTPLFILE = "/app/admin.tpl"
|
||||
const ADMINNGINXFILE = "/etc/nginx/conf.d/admin.conf"
|
||||
|
||||
var Config struct {
|
||||
Admin Website `json:"admin"`
|
||||
Websites []Website `json:"websites"`
|
||||
}
|
||||
|
||||
type Website struct {
|
||||
Name string `json:"name"`
|
||||
Enabled bool `json:"enabled"`
|
||||
Url string `json:"url"`
|
||||
Aliases []string `json:"aliases"`
|
||||
Http Http `json:"http"`
|
||||
Https Https `json:"https"`
|
||||
}
|
||||
|
||||
type Http struct {
|
||||
Redirect_to_https bool `json:"redirect_to_https"`
|
||||
Locations []Location `json:"locations"`
|
||||
}
|
||||
|
||||
type Https struct {
|
||||
Http2 bool `json:"http2"`
|
||||
Letsencrypt bool `json:"letsencrypt"`
|
||||
Locations []Location `json:"locations"`
|
||||
}
|
||||
|
||||
type Location struct {
|
||||
Location string `json:"location"`
|
||||
Destination string `json:"destination"`
|
||||
}
|
||||
|
||||
func loadConfig() {
|
||||
jsonFile, err := os.Open(CFGFILE)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
}
|
||||
defer jsonFile.Close()
|
||||
|
||||
jsonParser := json.NewDecoder(jsonFile)
|
||||
if err = jsonParser.Decode(&Config); err != nil {
|
||||
log.Println("Error parsing config file: ", err.Error())
|
||||
}
|
||||
log.Println("Successfully parsed: " + CFGFILE)
|
||||
|
||||
}
|
||||
|
||||
func startServer() {
|
||||
m := macaron.Classic()
|
||||
// m.Use(macaron.Static("public")) // static files served by nginx
|
||||
m.Get("/", myHandler)
|
||||
|
||||
log.Println("Server is running...")
|
||||
log.Println(http.ListenAndServe("0.0.0.0:4000", m))
|
||||
}
|
||||
|
||||
func main() {
|
||||
loadConfig()
|
||||
writeAdminTemplate()
|
||||
writeTemplate()
|
||||
nginxReloadConfig()
|
||||
startServer()
|
||||
}
|
||||
|
||||
func nginxReloadConfig() {
|
||||
// TODO: check why this is always in error but it's working...
|
||||
_, err := exec.Command("/usr/sbin/nginx", "-s", "reload").Output()
|
||||
|
||||
if err != nil {
|
||||
log.Printf("Successfully reloaded nginx config")
|
||||
} else {
|
||||
log.Printf("could not reload nginx: %s", err)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func writeTemplate() {
|
||||
t, err := mypongo2.FromFile(WEBSITETPLFILE)
|
||||
|
||||
if err != nil {
|
||||
log.Printf("could not render: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
f, err := os.Create(WEBSITENGINXFILE)
|
||||
if err != nil {
|
||||
log.Printf("cannot open: %s", WEBSITENGINXFILE)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
for _, v := range Config.Websites {
|
||||
|
||||
var http_locations []map[string]string
|
||||
var https_locations []map[string]string
|
||||
|
||||
for _, s := range v.Http.Locations {
|
||||
loc := map[string]string{
|
||||
"location": s.Location,
|
||||
"destination": s.Destination,
|
||||
}
|
||||
http_locations = append(http_locations, loc)
|
||||
}
|
||||
|
||||
for _, s := range v.Https.Locations {
|
||||
loc := map[string]string{
|
||||
"location": s.Location,
|
||||
"destination": s.Destination,
|
||||
}
|
||||
https_locations = append(https_locations, loc)
|
||||
}
|
||||
|
||||
data := mypongo2.Context{
|
||||
"url": v.Url,
|
||||
"name": v.Name,
|
||||
"http2": v.Https.Http2,
|
||||
"aliases": v.Aliases,
|
||||
"http_redirect_to_https": v.Http.Redirect_to_https,
|
||||
"https_locations": https_locations,
|
||||
"http_locations": http_locations,
|
||||
}
|
||||
|
||||
if err := t.ExecuteWriter(data, f); err != nil {
|
||||
log.Printf("could not execute: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
log.Printf("Successfully created: %s", WEBSITENGINXFILE)
|
||||
}
|
||||
|
||||
func writeAdminTemplate() {
|
||||
t, err := mypongo2.FromFile(ADMINTPLFILE)
|
||||
|
||||
if err != nil {
|
||||
log.Printf("could not render: %s", err)
|
||||
return
|
||||
}
|
||||
|
||||
f, err := os.Create(ADMINNGINXFILE)
|
||||
if err != nil {
|
||||
log.Printf("cannot open: %s", ADMINNGINXFILE)
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
data := mypongo2.Context{
|
||||
"url": Config.Admin.Url,
|
||||
"http2": Config.Admin.Https.Http2,
|
||||
"http_redirect_to_https": Config.Admin.Http.Redirect_to_https,
|
||||
}
|
||||
|
||||
if err := t.ExecuteWriter(data, f); err != nil {
|
||||
log.Printf("could not execute: %s", err)
|
||||
}
|
||||
|
||||
log.Printf("Successfully created: %s", ADMINNGINXFILE)
|
||||
}
|
||||
|
||||
func myHandler(ctx *macaron.Context) string {
|
||||
return "The request path is: " + ctx.Req.RequestURI
|
||||
}
|
||||
|
||||
func init() {
|
||||
mypongo2.RegisterFilter("filterdomaindots", PongoFilterDomainDots)
|
||||
}
|
||||
|
||||
func PongoFilterDomainDots(in *mypongo2.Value, param *mypongo2.Value) (out *mypongo2.Value, err *mypongo2.Error) {
|
||||
if !in.IsString() {
|
||||
return nil, &mypongo2.Error{
|
||||
Sender: "you should use only strings",
|
||||
}
|
||||
}
|
||||
|
||||
s := in.String()
|
||||
s = strings.Replace(s, ".", "\\.", -1)
|
||||
|
||||
return mypongo2.AsValue(s), nil
|
||||
}
|
||||
138
source/main.go
Normal file
138
source/main.go
Normal file
@@ -0,0 +1,138 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
// "encoding/json"
|
||||
"github.com/go-macaron/pongo2"
|
||||
|
||||
"gopkg.in/macaron.v1"
|
||||
"net/http"
|
||||
"log"
|
||||
// "periph.io/x/periph"
|
||||
"periph.io/x/periph/host"
|
||||
"periph.io/x/periph/conn/i2c"
|
||||
"periph.io/x/periph/conn/i2c/i2creg"
|
||||
"time"
|
||||
"github.com/spf13/viper"
|
||||
)
|
||||
|
||||
type Dictionary map[string]interface{}
|
||||
|
||||
func readConfig() {
|
||||
viper.SetConfigName("openpdu.yaml") // name of config file (without extension)
|
||||
viper.SetConfigType("yaml")
|
||||
viper.AddConfigPath("/etc/openpdu/") // path to look for the config file in
|
||||
viper.AddConfigPath(".") // optionally look for config in the working directory
|
||||
err := viper.ReadInConfig() // Find and read the config file
|
||||
if err != nil { // Handle errors reading the config file
|
||||
log.Printf("Fatal error config file: %s \n", err)
|
||||
}
|
||||
|
||||
viper.SetDefault("hostname","openpdu")
|
||||
}
|
||||
|
||||
func initI2C() {
|
||||
// Make sure periph is initialized.
|
||||
if _, err := host.Init(); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// Use i2creg I²C bus registry to find the first available I²C bus.
|
||||
b, err := i2creg.Open("/dev/i2c-0")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer b.Close()
|
||||
|
||||
// bus 0
|
||||
// Dev is a valid conn.Conn.
|
||||
d := &i2c.Dev{Addr: 0x27, Bus: b}
|
||||
|
||||
// Send a command 0x10 and expect a 5 bytes reply.
|
||||
// write := []byte{0x10}
|
||||
write := []byte{0x0}
|
||||
// read := make([]byte, 5)
|
||||
// if err := d.Tx(write, read); err != nil {
|
||||
if _, err := d.Write(write); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
|
||||
for i := 0; i < 2; i++ {
|
||||
|
||||
write := []byte{0x0A}
|
||||
read := make([]byte, 5)
|
||||
if err := d.Tx(write, read); err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
log.Printf("%v\n", read)
|
||||
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
// func myHandler(ctx *macaron.Context) string {
|
||||
// ctx.Data["name"] = "jeremy"
|
||||
// ctx.HTML(200, "hello") // 200 is the response code.
|
||||
|
||||
// return "The request path is: " + ctx.Req.RequestURI
|
||||
// }
|
||||
|
||||
func startServer() {
|
||||
m := macaron.Classic()
|
||||
m.Use(pongo2.Pongoer())
|
||||
m.Use(macaron.Static("static"))
|
||||
// m.Get("/", myHandler)
|
||||
|
||||
m.Get("/", func(ctx *macaron.Context) {
|
||||
ctx.Data["pluglist"] = []Dictionary{
|
||||
{"id": 1, "description": "p1"},
|
||||
{"id": 2, "description": "p2"},
|
||||
{"id": 3, "description": "p3"},
|
||||
{"id": 4, "description": "p4"},
|
||||
{"id": 5, "description": "p5"},
|
||||
{"id": 6, "description": "p6"},
|
||||
{"id": 7, "description": "p7"},
|
||||
{"id": 8, "description": "p8"},
|
||||
}
|
||||
ctx.HTML(200, "status") // 200 is the response code.
|
||||
})
|
||||
|
||||
m.Get("/boards", func(ctx *macaron.Context) {
|
||||
ctx.HTML(200, "boards") // 200 is the response code.
|
||||
})
|
||||
|
||||
log.Println("Server is running...")
|
||||
log.Println(http.ListenAndServe("0.0.0.0:4000", m))
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
||||
readConfig()
|
||||
|
||||
nam := viper.Get("name")
|
||||
log.Printf("name: %v\n", nam)
|
||||
|
||||
|
||||
initI2C()
|
||||
startServer()
|
||||
}
|
||||
|
||||
|
||||
|
||||
// https://github.com/ColorlibHQ/AdminLTE/archive/v2.4.17.tar.gz
|
||||
|
||||
/* TODO
|
||||
|
||||
- config reset gpio
|
||||
- classi per board
|
||||
- classi per outlet
|
||||
- fai funzionare toggle
|
||||
- scan i2c
|
||||
- impostazioni log
|
||||
- impostazioni mqtt
|
||||
|
||||
|
||||
*/
|
||||
Reference in New Issue
Block a user