Feature - Gateway (#12)

* feat: add geateway config

* feat: add ping controller for check by gateway

* feat: add new env vars for gateway

* feat: update config

* gateway request wip

* feat: add auth header for gateway request

* feat: separate gateway folder

* update endpoint for gateway

* add makefile

* lint

* swap png to svg

* add url of board to request to gateway

* change deployed path prefix

* add env in compose

* add body log on gateway connect
This commit is contained in:
Yanislav Igonin 2022-02-28 09:18:44 +02:00 committed by GitHub
parent 140d56b627
commit 79e6cc8e5b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 115 additions and 6 deletions

View File

@ -5,4 +5,9 @@ IS_RATE_LIMITER_ENABLED=true
THREADS_MAX_COUNT=50 THREADS_MAX_COUNT=50
POSTGRES_URL=postgres://localhost/micrach?pool_max_conns=5 POSTGRES_URL=postgres://localhost/micrach?pool_max_conns=5
THREAD_BUMP_LIMIT=500 THREAD_BUMP_LIMIT=500
IS_CAPTCHA_ACTIVE=true IS_CAPTCHA_ACTIVE=true
GATEWAY_URL=http://localhost:3001
GATEWAY_API_KEY=example
GATEWAY_BOARD_ID=b
GATEWAY_BOARD_URL=http://localhost:3000
GATEWAY_BOARD_DESCRIPTION=Random

2
Makefile Normal file
View File

@ -0,0 +1,2 @@
dev:
nodemon --exec go run main.go --signal SIGTERM

View File

@ -7,6 +7,14 @@ import (
"strconv" "strconv"
) )
type GatewayConfig struct {
Url string
ApiKey string
BoardId string
BoardUrl string
BoardDescription string
}
type AppConfig struct { type AppConfig struct {
Env string Env string
Port int Port int
@ -15,6 +23,7 @@ type AppConfig struct {
ThreadsMaxCount int ThreadsMaxCount int
ThreadBumpLimit int ThreadBumpLimit int
IsCaptchaActive bool IsCaptchaActive bool
Gateway GatewayConfig
} }
type DbConfig struct { type DbConfig struct {
@ -46,6 +55,22 @@ func getValueOrDefaultString(value string, defaultValue string) string {
return value return value
} }
func getGatewayConfig() GatewayConfig {
url := os.Getenv("GATEWAY_URL")
apiKey := os.Getenv("GATEWAY_API_KEY")
boardId := os.Getenv("GATEWAY_BOARD_ID")
description := os.Getenv("GATEWAY_BOARD_DESCRIPTION")
boardUrl := os.Getenv("GATEWAY_BOARD_URL")
return GatewayConfig{
Url: url,
ApiKey: apiKey,
BoardId: boardId,
BoardUrl: boardUrl,
BoardDescription: description,
}
}
func getAppConfig() AppConfig { func getAppConfig() AppConfig {
env := getValueOrDefaultString(os.Getenv("ENV"), "release") env := getValueOrDefaultString(os.Getenv("ENV"), "release")
port := getValueOrDefaultInt(os.Getenv("PORT"), 3000) port := getValueOrDefaultInt(os.Getenv("PORT"), 3000)
@ -54,6 +79,7 @@ func getAppConfig() AppConfig {
threadsMaxCount := getValueOrDefaultInt(os.Getenv("THREADS_MAX_COUNT"), 50) threadsMaxCount := getValueOrDefaultInt(os.Getenv("THREADS_MAX_COUNT"), 50)
threadBumpLimit := getValueOrDefaultInt(os.Getenv("THREAD_BUMP_LIMIT"), 500) threadBumpLimit := getValueOrDefaultInt(os.Getenv("THREAD_BUMP_LIMIT"), 500)
isCaptchaActive := getValueOrDefaultBoolean(os.Getenv("IS_CAPTCHA_ACTIVE"), true) isCaptchaActive := getValueOrDefaultBoolean(os.Getenv("IS_CAPTCHA_ACTIVE"), true)
gateway := getGatewayConfig()
return AppConfig{ return AppConfig{
Env: env, Env: env,
@ -63,6 +89,7 @@ func getAppConfig() AppConfig {
ThreadsMaxCount: threadsMaxCount, ThreadsMaxCount: threadsMaxCount,
ThreadBumpLimit: threadBumpLimit, ThreadBumpLimit: threadBumpLimit,
IsCaptchaActive: isCaptchaActive, IsCaptchaActive: isCaptchaActive,
Gateway: gateway,
} }
} }

View File

@ -12,6 +12,13 @@ services:
IS_RATE_LIMITER_ENABLED: ${IS_RATE_LIMITER_ENABLED} IS_RATE_LIMITER_ENABLED: ${IS_RATE_LIMITER_ENABLED}
THREADS_MAX_COUNT: ${THREADS_MAX_COUNT} THREADS_MAX_COUNT: ${THREADS_MAX_COUNT}
POSTGRES_URL: ${POSTGRES_URL} POSTGRES_URL: ${POSTGRES_URL}
THREAD_BUMP_LIMIT: ${THREAD_BUMP_LIMIT}
IS_CAPTCHA_ACTIVE: ${IS_CAPTCHA_ACTIVE}
GATEWAY_URL: ${GATEWAY_URL}
GATEWAY_API_KEY: ${GATEWAY_API_KEY}
GATEWAY_BOARD_ID: ${GATEWAY_BOARD_ID}
GATEWAY_BOARD_URL: ${GATEWAY_BOARD_URL}
GATEWAY_BOARD_DESCRIPTION: ${GATEWAY_BOARD_DESCRIPTION}
volumes: volumes:
- /root/micrach-go/uploads:/app/uploads - /root/micrach-go/uploads:/app/uploads
deploy: deploy:
@ -33,11 +40,11 @@ services:
traefik.http.middlewares.micrach-https-redirect.redirectscheme.scheme: "https" traefik.http.middlewares.micrach-https-redirect.redirectscheme.scheme: "https"
traefik.http.routers.micrach.entrypoints: "http" traefik.http.routers.micrach.entrypoints: "http"
traefik.http.routers.micrach.rule: "Host(`micrach.igonin.dev`)" traefik.http.routers.micrach.rule: "Host(`micrach.igonin.dev`) && PathPrefix(`/${GATEWAY_BOARD_ID}`)"
traefik.http.routers.micrach.middlewares: "micrach-https-redirect" traefik.http.routers.micrach.middlewares: "micrach-https-redirect"
traefik.http.routers.micrach-secure.entrypoints: "https" traefik.http.routers.micrach-secure.entrypoints: "https"
traefik.http.routers.micrach-secure.rule: "Host(`micrach.igonin.dev`)" traefik.http.routers.micrach-secure.rule: "Host(`micrach.igonin.dev`) && PathPrefix(`/${GATEWAY_BOARD_ID}`)"
traefik.http.routers.micrach-secure.tls: "true" traefik.http.routers.micrach-secure.tls: "true"
traefik.http.routers.micrach-secure.service: "micrach" traefik.http.routers.micrach-secure.service: "micrach"

39
gateway/connect.go Normal file
View File

@ -0,0 +1,39 @@
package gateway
import (
"bytes"
"encoding/json"
"io/ioutil"
"log"
"net/http"
Config "micrach/config"
)
// Make http request to gateway to tell the board id and description
func Connect() {
requestBody, _ := json.Marshal(map[string]string{
"id": Config.App.Gateway.BoardId,
"name": Config.App.Gateway.BoardDescription,
"url": Config.App.Gateway.Url,
})
url := Config.App.Gateway.Url + "/api/boards"
req, err := http.NewRequest("POST", url, bytes.NewBuffer(requestBody))
if err != nil {
log.Panicln(err)
}
req.Header.Set("Authorization", Config.App.Gateway.ApiKey)
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
log.Panicln(err)
}
//We Read the response body on the line below.
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Panicln(err)
}
log.Println(string(body))
log.Println("gateway - online")
}

19
gateway/controllers.go Normal file
View File

@ -0,0 +1,19 @@
package gateway
import (
Config "micrach/config"
"net/http"
"github.com/gin-gonic/gin"
)
func Ping(c *gin.Context) {
headerKey := c.Request.Header.Get("Authorization")
if Config.App.Gateway.ApiKey != headerKey {
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"error": "Unauthorized"})
return
}
c.JSON(200, gin.H{
"message": "pong",
})
}

View File

@ -16,6 +16,7 @@ import (
Config "micrach/config" Config "micrach/config"
Controllers "micrach/controllers" Controllers "micrach/controllers"
Db "micrach/db" Db "micrach/db"
Gateway "micrach/gateway"
Repositories "micrach/repositories" Repositories "micrach/repositories"
Templates "micrach/templates" Templates "micrach/templates"
Utils "micrach/utils" Utils "micrach/utils"
@ -62,6 +63,10 @@ func main() {
} }
router.Static("/uploads", "./uploads") router.Static("/uploads", "./uploads")
router.Static("/static", "./static") router.Static("/static", "./static")
if Config.App.Gateway.Url != "" {
router.GET("/api/ping", Gateway.Ping)
Gateway.Connect()
}
router.GET("/", Controllers.GetThreads) router.GET("/", Controllers.GetThreads)
router.POST("/", Controllers.CreateThread) router.POST("/", Controllers.CreateThread)
router.GET("/:threadID", Controllers.GetThread) router.GET("/:threadID", Controllers.GetThread)

1
static/icons/github.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/></svg>

After

Width:  |  Height:  |  Size: 814 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.7 KiB

View File

@ -1,3 +1,7 @@
#pagesList { #pagesList {
flex-wrap: wrap flex-wrap: wrap
} }
.github-icon {
width: 2.5rem;
}

View File

@ -2,7 +2,7 @@
<footer class="py-4"> <footer class="py-4">
<div class="container text-center"> <div class="container text-center">
<a href="https://github.com/yanislav-igonin/micrach" target="blank"> <a href="https://github.com/yanislav-igonin/micrach" target="blank">
<img src="/static/images/github-icon.png" alt="GitHub icon"> <img class="github-icon" src="/static/icons/github.svg" alt="github icon">
</a> </a>
</div> </div>
</footer> </footer>

View File

@ -11,6 +11,6 @@
crossorigin="anonymous"> crossorigin="anonymous">
</script> </script>
<link rel="icon" href="/static/favicon.ico"/> <link rel="icon" href="/static/favicon.ico"/>
<link href="/static/styles/utils.css" rel="stylesheet"> <link href="/static/styles/utils.css" rel="stylesheet">
<link href="/static/styles/post-form.css" rel="stylesheet"> <link href="/static/styles/post-form.css" rel="stylesheet">
{{ end }} {{ end }}