Compare commits
8 commits
Author | SHA1 | Date | |
---|---|---|---|
64ad90084c | |||
b1340d23a9 | |||
14470b3c0c | |||
0713fcc887 | |||
aa4b4d7d3c | |||
d0126c97ff | |||
ba9e9ab9ab | |||
8ab7522c55 |
14 changed files with 225 additions and 91 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -3,3 +3,4 @@ epee-service
|
|||
dist/
|
||||
dist/*
|
||||
.DS_STORE
|
||||
epee-*
|
32
.woodpecker/docker.yaml
Normal file
32
.woodpecker/docker.yaml
Normal file
|
@ -0,0 +1,32 @@
|
|||
steps:
|
||||
- name: publish_image
|
||||
image: woodpeckerci/plugin-docker-buildx:5.2
|
||||
settings:
|
||||
repo: git.gnous.eu/${CI_REPO_OWNER}/epee-service
|
||||
dockerfile: Dockerfile
|
||||
platforms: linux/amd64
|
||||
registry: https://git.gnous.eu
|
||||
tag: ${CI_COMMIT}
|
||||
username:
|
||||
from_secret: docker_username
|
||||
password:
|
||||
from_secret: docker_password
|
||||
when:
|
||||
branch: ${CI_REPO_DEFAULT_BRANCH}
|
||||
event: push
|
||||
- name: publish_image_tag
|
||||
image: woodpeckerci/plugin-docker-buildx:5.2
|
||||
settings:
|
||||
repo: git.gnous.eu/${CI_REPO_OWNER}/epee-service
|
||||
dockerfile: Dockerfile
|
||||
platforms: linux/amd64
|
||||
registry: https://git.gnous.eu
|
||||
tags:
|
||||
- ${CI_COMMIT_TAG##v} # Remove v from tag
|
||||
- stable
|
||||
username:
|
||||
from_secret: docker_username
|
||||
password:
|
||||
from_secret: docker_password
|
||||
when:
|
||||
event: tag
|
|
@ -1,6 +1,6 @@
|
|||
steps:
|
||||
lint:
|
||||
image: golang:1.22
|
||||
image: golang:1.24
|
||||
commands:
|
||||
- go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest
|
||||
- golangci-lint run
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
steps:
|
||||
- name: Build
|
||||
image: golang:1.22
|
||||
image: golang:1.24
|
||||
commands:
|
||||
- go mod download
|
||||
- go get
|
||||
- CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags "-w -s" -o epee-linux-amd64 # Enable static binary, target Linux, remove debug information and strip binary
|
||||
- CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -ldflags "-w -s" -o epee-linux-arm64
|
||||
- CGO_ENABLED=0 GOOS=linux GOARCH=arm go build -ldflags "-w -s" -o epee-linux-arm
|
||||
|
@ -15,7 +16,7 @@ steps:
|
|||
files:
|
||||
- "epee-*"
|
||||
api_key:
|
||||
from_secret: release_token
|
||||
from_secret: gnous_cicd_token
|
||||
target: main
|
||||
when:
|
||||
event: tag
|
17
Dockerfile
Normal file
17
Dockerfile
Normal file
|
@ -0,0 +1,17 @@
|
|||
FROM golang:1.24 AS builder
|
||||
|
||||
ARG TARGETPLATFORM
|
||||
ARG BUILDPLATFORM
|
||||
ARG TARGETOS
|
||||
ARG TARGETARCH
|
||||
|
||||
WORKDIR /app/
|
||||
ADD . .
|
||||
RUN CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -ldflags="-w -s" -o epee main.go
|
||||
|
||||
FROM scratch
|
||||
WORKDIR /app/
|
||||
COPY --from=builder /app/epee /app/epee
|
||||
|
||||
EXPOSE 5900
|
||||
ENTRYPOINT ["/app/epee"]
|
4
go.sum
4
go.sum
|
@ -3,8 +3,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
|
|||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
|
||||
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
|
||||
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
|
|
39
main.go
39
main.go
|
@ -6,6 +6,8 @@ import (
|
|||
"fmt"
|
||||
"html/template"
|
||||
"net/http"
|
||||
"sort"
|
||||
"strconv"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
@ -18,8 +20,9 @@ var templatesFS embed.FS
|
|||
|
||||
// Error model
|
||||
type Error struct {
|
||||
Title string `json:"title"`
|
||||
Message string `json:"message"`
|
||||
Title string `json:"title"`
|
||||
Description string `json:"description"`
|
||||
Message template.HTML `json:"message"`
|
||||
}
|
||||
|
||||
func main() {
|
||||
|
@ -42,6 +45,13 @@ func main() {
|
|||
func errorHandler(w http.ResponseWriter, r *http.Request) {
|
||||
errorCode := r.URL.Query().Get("error")
|
||||
|
||||
// Set status code based on error code
|
||||
errorCodeInt, err := strconv.Atoi(errorCode)
|
||||
if err != nil || errorCodeInt < 400 || errorCodeInt > 599 {
|
||||
errorCodeInt = http.StatusInternalServerError
|
||||
}
|
||||
w.WriteHeader(errorCodeInt)
|
||||
|
||||
// Load error messages from JSON file
|
||||
jsonData, err := templatesFS.ReadFile("templates/errors.json")
|
||||
if err != nil {
|
||||
|
@ -54,10 +64,10 @@ func errorHandler(w http.ResponseWriter, r *http.Request) {
|
|||
generateInternalServerError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
errorData := errors[errorCode]
|
||||
if errorData.Title == "" {
|
||||
errorData.Title = "Oops 🤓"
|
||||
errorData.Message = "It seems like something went wrong. Please try again later."
|
||||
errorData = errors["500"] // Fallback to 500 error if specific error not found
|
||||
}
|
||||
|
||||
// Render error page
|
||||
|
@ -71,20 +81,29 @@ func errorHandler(w http.ResponseWriter, r *http.Request) {
|
|||
generateInternalServerError(w, err)
|
||||
return
|
||||
}
|
||||
t.Execute(w, errorData)
|
||||
|
||||
if err := t.Execute(w, errorData); err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
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"}`))
|
||||
if _, err := w.Write([]byte(`{"error": "Internal Server Error"}`)); err != nil {
|
||||
log.Error(err)
|
||||
}
|
||||
}
|
||||
|
||||
func headersHandler(w http.ResponseWriter, r *http.Request) {
|
||||
for name, headers := range r.Header {
|
||||
for _, h := range headers {
|
||||
fmt.Fprintf(w, "%v: %v\n", name, h)
|
||||
}
|
||||
headersName := make([]string, 0, len(r.Header))
|
||||
for hName := range r.Header {
|
||||
headersName = append(headersName, hName)
|
||||
}
|
||||
sort.Strings(headersName)
|
||||
|
||||
for _, hName := range headersName {
|
||||
fmt.Fprintf(w, "%v: %v\n", hName, r.Header.Get(hName))
|
||||
}
|
||||
}
|
||||
|
|
BIN
static/Format_1452.eot
Normal file
BIN
static/Format_1452.eot
Normal file
Binary file not shown.
BIN
static/Format_1452.woff
Normal file
BIN
static/Format_1452.woff
Normal file
Binary file not shown.
BIN
static/Format_1452.woff2
Normal file
BIN
static/Format_1452.woff2
Normal file
Binary file not shown.
Binary file not shown.
121
static/main.css
121
static/main.css
|
@ -1,61 +1,108 @@
|
|||
@import url('https://fonts.googleapis.com/css2?family=Nunito:wght@500;800&display=swap');
|
||||
@font-face {
|
||||
font-family: "Format 1452";
|
||||
src: url("/cdn-cgi/static/Format_1452.woff2") format("woff2"),
|
||||
url("/cdn-cgi/static/Format_1452.woff") format("woff"),
|
||||
url("/cdn-cgi/static/Format_1452.eot") format("embedded-opentype");
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
* {
|
||||
margin: 0px;
|
||||
padding: 0px;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
body {
|
||||
font-family: 'Nunito', sans-serif;
|
||||
background-color: #f1efe9;
|
||||
color: #282828;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
h1 {
|
||||
font-weight: 800;
|
||||
}
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
min-height: 100vh;
|
||||
min-height: 100dvh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
font-family: "Format 1452", sans-serif;
|
||||
color: #fff;
|
||||
background-color: #424cff;
|
||||
|
||||
background-image:
|
||||
repeating-radial-gradient(circle at 0 0, transparent 0, #424cff 40px),
|
||||
repeating-linear-gradient(#00000055, #000000);
|
||||
background-size: auto;
|
||||
background-repeat: repeat;
|
||||
}
|
||||
|
||||
.main {
|
||||
flex: 1;
|
||||
.request-id {
|
||||
font-weight: bold;
|
||||
color: #ffcc00;
|
||||
}
|
||||
|
||||
.header {
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
.error-container {
|
||||
font-size: clamp(2rem, 10vw, 5em);
|
||||
word-wrap: break-word;
|
||||
overflow-wrap: break-word;
|
||||
}
|
||||
|
||||
.main {
|
||||
width: 80%;
|
||||
margin: 0 auto;
|
||||
margin-top: 5vh;
|
||||
.error-description {
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
.main h1 {
|
||||
font-size: 8vh;
|
||||
header {
|
||||
font-size: 1.5em;
|
||||
padding: 3em;
|
||||
padding-bottom: 0px;
|
||||
}
|
||||
|
||||
.main p {
|
||||
padding-top: 0.5vh;
|
||||
.blur {
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.footer {
|
||||
background-color: #282828;
|
||||
color: #f1efe9;
|
||||
padding: 20px;
|
||||
text-align: center;
|
||||
.flex {
|
||||
padding: 3em;
|
||||
padding-top: clamp(3em, 10vw, 5em);
|
||||
border-radius: 10px;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
flex-wrap: wrap;
|
||||
max-width: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.main a {
|
||||
color: #7d5fff;
|
||||
.col {
|
||||
flex: 1 1 0;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.footer a {
|
||||
color: #f1efe9;
|
||||
|
||||
footer {
|
||||
margin-top: auto;
|
||||
padding: 3em;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #ffcc00;
|
||||
text-decoration: none;
|
||||
}
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
@media (max-width: 1000px) {
|
||||
.col {
|
||||
flex: 1 1 100%;
|
||||
margin: 1em;
|
||||
}
|
||||
header {
|
||||
font-size: 1.2em;
|
||||
padding: 2em;
|
||||
}
|
||||
.flex, footer {
|
||||
padding: 2em;
|
||||
}
|
||||
}
|
|
@ -1,32 +1,44 @@
|
|||
<!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="/cdn-cgi/static/main.css">
|
||||
</head>
|
||||
<body class="blur">
|
||||
<header>
|
||||
<p>EnPLS Network_</p>
|
||||
</header>
|
||||
<main>
|
||||
<div class="flex">
|
||||
<div class="col">
|
||||
<div class="error-container">
|
||||
<h1>{{.Title}}</h1>
|
||||
<p>{{.Description}}</p>
|
||||
</div>
|
||||
<p>Request ID <span class="request-id">917553</span></p>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div class="error-description">
|
||||
<p>
|
||||
{{.Message}}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<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="/cdn-cgi/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 <span id="year"></span> EnPLS Network - <a href="https://enpls.org">enpls.org</a> </p>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
document.getElementById("year").innerHTML = new Date().getFullYear();
|
||||
</script>
|
||||
</body>
|
||||
|
||||
<footer>
|
||||
<p>Copyright <span id="year"></span> <a href="https://enpls.org">EnPLS Network</a></p>
|
||||
<p>Font ~ Format 1452 by Frank Adebiaye, with the contribution
|
||||
of Anton
|
||||
Moglia.
|
||||
Distributed by velvetyne.fr.</p>
|
||||
</footer>
|
||||
<script type="text/javascript">
|
||||
document.getElementById("year").innerHTML = new Date().getFullYear();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,22 +1,27 @@
|
|||
{
|
||||
"404": {
|
||||
"title": "404, Page Not Found.",
|
||||
"message": "Ooops! It looks like the ressource you were looking for is no were to be found."
|
||||
"title": "404",
|
||||
"description": "Not Found",
|
||||
"message": "The requested resource could not be found.<br />This could be due to a misconfiguration in the EnPLS Edge Service, or the resource being moved or deleted.<br /><br />If you think this is an error, please reach the website administrator."
|
||||
},
|
||||
"403": {
|
||||
"title": "403, Access Denied.",
|
||||
"message": "Ooops! It looks like you don't have the right to access this ressource."
|
||||
"title": "403",
|
||||
"description": "Forbidden",
|
||||
"message": "You do not have permission to access this resource.<br />This could be due to a misconfiguration in the EnPLS Edge Service, or the resource being restricted.<br /><br />If you think this is an error, please reach the website administrator."
|
||||
},
|
||||
"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."
|
||||
"title": "502",
|
||||
"description": "Bad Gateway",
|
||||
"message": "The EnPLS Edge Service worker was not able to reach the defined backend service.<br />This could be due to the backend service being down, or a misconfiguration in the EnPLS Edge Service.<br /><br />If the problem persists, please reach the website administrator."
|
||||
},
|
||||
"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."
|
||||
"title": "503",
|
||||
"description": "Backend Service Unavailable",
|
||||
"message": "The EnPLS Edge Service worker was not able to reach the defined backend service.<br />This could be due to the backend service being down, or a misconfiguration in the EnPLS Edge Service.<br /><br />If the problem persists, please reach the website administrator."
|
||||
},
|
||||
"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."
|
||||
"title": "500",
|
||||
"description": "Backend Service Unavailable",
|
||||
"message": "The EnPLS Edge Service worker was not able to reach the defined backend service.<br />This could be due to the backend service being down, or a misconfiguration in the EnPLS Edge Service.<br /><br />If the problem persists, please reach the website administrator."
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue