Init
This commit is contained in:
commit
1a9481bd83
7 changed files with 253 additions and 0 deletions
61
Makefile
Normal file
61
Makefile
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
EXTENSION ?=
|
||||||
|
DIST_DIR ?= dist/
|
||||||
|
GOOS ?= linux
|
||||||
|
ARCH ?= $(shell uname -m)
|
||||||
|
BUILDINFOSDET ?=
|
||||||
|
|
||||||
|
SOFT_NAME := epee_service
|
||||||
|
SOFT_VERSION := $(shell git describe --tags $(git rev-list --tags --max-count=1))
|
||||||
|
VERSION_PKG := $(shell echo $(SOFT_VERSION) | sed 's/^v//g')
|
||||||
|
ARCH := x86_64
|
||||||
|
LICENSE := AGPL-3
|
||||||
|
URL := https://git.gnous.eu/enpls/epee-service
|
||||||
|
DESCRIPTION := EnPLS Epee (Enpls Proxy EnginE) Utility Service
|
||||||
|
BUILDINFOS := ($(shell date +%FT%T%z)$(BUILDINFOSDET))
|
||||||
|
LDFLAGS := '-X main.version=$(SOFT_VERSION) -X main.buildinfos=$(BUILDINFOS)'
|
||||||
|
|
||||||
|
OUTPUT_SOFT := $(DIST_DIR)frite-$(SOFT_VERSION)-$(GOOS)-$(ARCH)$(EXTENSION)
|
||||||
|
|
||||||
|
.PHONY: vet
|
||||||
|
vet:
|
||||||
|
go vet main.go
|
||||||
|
|
||||||
|
.PHONY: test
|
||||||
|
test:
|
||||||
|
go test -v ./...
|
||||||
|
|
||||||
|
.PHONY: prepare
|
||||||
|
prepare:
|
||||||
|
mkdir -p $(DIST_DIR)
|
||||||
|
|
||||||
|
.PHONY: clean
|
||||||
|
clean:
|
||||||
|
rm -rf $(DIST_DIR)
|
||||||
|
|
||||||
|
.PHONY: build
|
||||||
|
build: prepare
|
||||||
|
go build -ldflags $(LDFLAGS) -o $(OUTPUT_SOFT)
|
||||||
|
|
||||||
|
.PHONY: package-deb
|
||||||
|
package-deb: prepare
|
||||||
|
fpm -s dir -t deb -n $(SOFT_NAME) -v $(VERSION_PKG) \
|
||||||
|
--description "$(DESCRIPTION)" \
|
||||||
|
--url "$(URL)" \
|
||||||
|
--architecture $(ARCH) \
|
||||||
|
--license "$(LICENSE)" \
|
||||||
|
--package $(DIST_DIR) \
|
||||||
|
$(OUTPUT_SOFT)=/usr/bin/frite-web \
|
||||||
|
extra/links.txt.example=/etc/frite/links.txt \
|
||||||
|
extra/frite-web.service=/usr/lib/systemd/system/frite-web.service
|
||||||
|
|
||||||
|
.PHONY: package-rpm
|
||||||
|
package-rpm: prepare
|
||||||
|
fpm -s dir -t rpm -n $(SOFT_NAME) -v $(VERSION_PKG) \
|
||||||
|
--description "$(DESCRIPTION)" \
|
||||||
|
--url "$(URL)" \
|
||||||
|
--architecture $(ARCH) \
|
||||||
|
--license "$(LICENSE) "\
|
||||||
|
--package $(DIST_DIR) \
|
||||||
|
$(OUTPUT_SOFT)=/usr/bin/frite-web \
|
||||||
|
extra/links.txt.example=/etc/frite/links.txt \
|
||||||
|
extra/frite-web.service=/usr/lib/systemd/system/frite-web.service
|
3
go.mod
Normal file
3
go.mod
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
module git.gnous.eu/enpls/epee-service
|
||||||
|
|
||||||
|
go 1.19
|
77
main.go
Normal file
77
main.go
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"embed"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"html/template"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:embed static
|
||||||
|
var staticFS embed.FS
|
||||||
|
|
||||||
|
//go:embed templates
|
||||||
|
var templatesFS embed.FS
|
||||||
|
|
||||||
|
// Error model
|
||||||
|
type Error struct {
|
||||||
|
Title string `json:"title"`
|
||||||
|
Message string `json:"message"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
port := "5900"
|
||||||
|
|
||||||
|
http.Handle("/static/", http.FileServer(http.FS(staticFS)))
|
||||||
|
http.HandleFunc("/", errorHandler)
|
||||||
|
|
||||||
|
log.Printf("Listening on :%s...", port)
|
||||||
|
err := http.ListenAndServe(fmt.Sprintf(":%s", port), nil)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func errorHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
|
errorCode := r.URL.Query().Get("error")
|
||||||
|
|
||||||
|
// Load error messages from JSON file
|
||||||
|
jsonData, err := templatesFS.ReadFile("templates/errors.json")
|
||||||
|
if err != nil {
|
||||||
|
generateInternalServerError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
errors := make(map[string]Error)
|
||||||
|
err = json.Unmarshal(jsonData, &errors)
|
||||||
|
if err != nil {
|
||||||
|
generateInternalServerError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
errorData := errors[errorCode]
|
||||||
|
if errorData.Title == "" {
|
||||||
|
errorData.Title = "Error"
|
||||||
|
errorData.Message = "An error occurred."
|
||||||
|
}
|
||||||
|
|
||||||
|
// Render error page
|
||||||
|
tmpl, err := templatesFS.ReadFile("templates/error.html")
|
||||||
|
if err != nil {
|
||||||
|
generateInternalServerError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t, err := template.New("error").Parse(string(tmpl))
|
||||||
|
if err != nil {
|
||||||
|
generateInternalServerError(w, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
t.Execute(w, errorData)
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateInternalServerError(w http.ResponseWriter, err error) {
|
||||||
|
log.Println(err)
|
||||||
|
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
w.Write([]byte(`{"error": "Internal Server Error"}`))
|
||||||
|
}
|
BIN
static/Nunito-VariableFont_wght.ttf
Normal file
BIN
static/Nunito-VariableFont_wght.ttf
Normal file
Binary file not shown.
61
static/main.css
Normal file
61
static/main.css
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
@import url('https://fonts.googleapis.com/css2?family=Nunito:wght@500;800&display=swap');
|
||||||
|
|
||||||
|
* {
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
font-family: 'Nunito', sans-serif;
|
||||||
|
background-color: #f1efe9;
|
||||||
|
color: #282828;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1 {
|
||||||
|
font-weight: 800;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
display: flex;
|
||||||
|
min-height: 100vh;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main {
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
padding: 20px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main {
|
||||||
|
width: 80%;
|
||||||
|
margin: 0 auto;
|
||||||
|
margin-top: 5vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main h1 {
|
||||||
|
font-size: 8vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main p {
|
||||||
|
padding-top: 0.5vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer {
|
||||||
|
background-color: #282828;
|
||||||
|
color: #f1efe9;
|
||||||
|
padding: 20px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.main a {
|
||||||
|
color: #7d5fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.footer a {
|
||||||
|
color: #f1efe9;
|
||||||
|
}
|
29
templates/error.html
Normal file
29
templates/error.html
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>{{.Title}}</title>
|
||||||
|
<link rel="stylesheet" href="/static/main.css">
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<div class="header">
|
||||||
|
<h1>EnPLS Network </h1>
|
||||||
|
</div>
|
||||||
|
<div class="main">
|
||||||
|
<h1>{{.Title}}</h1>
|
||||||
|
<p>{{.Message}}</p>
|
||||||
|
<p>If you believe that this situation is unusual, please don't hesitate to <a
|
||||||
|
href="mailto:mael@enpls.org">contact us</a>.
|
||||||
|
</div>
|
||||||
|
<div class="footer">
|
||||||
|
<p>© Copyright {{.Year}} EnPLS Network - <a href="https://enpls.org">enpls.org</a> </p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
22
templates/errors.json
Normal file
22
templates/errors.json
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
{
|
||||||
|
"404": {
|
||||||
|
"title": "404, Page Not Found.",
|
||||||
|
"message": "Ooops! It looks like the ressource you were looking for is no were to be found."
|
||||||
|
},
|
||||||
|
"403": {
|
||||||
|
"title": "403, Access Denied.",
|
||||||
|
"message": "Ooops! It looks like you don't have the right to access this ressource."
|
||||||
|
},
|
||||||
|
"502": {
|
||||||
|
"title": "502, Backend Unavailable.",
|
||||||
|
"message": "Ooops! The requested backend service is unavailable. This error might be due to an ongoing maintenance or a service disruption. You might want to take a look at our service status page."
|
||||||
|
},
|
||||||
|
"503": {
|
||||||
|
"title": "503, Service Unavailable.",
|
||||||
|
"message": "Ooops! The requested service is unavailable. This error might be due to an ongoing maintenance or a service disruption. You might want to take a look at our service status page."
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"title": "500, Internal Server Error.",
|
||||||
|
"message": "Ooops! It looks like something went wrong on our side. We are working on it and will be back shortly."
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue