Skip to content

Commit b34c71c

Browse files
author
Boris
committed
first commit
0 parents  commit b34c71c

File tree

10 files changed

+319
-0
lines changed

10 files changed

+319
-0
lines changed

.github/workflows/docker.yml

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
name: Docker Image
2+
3+
on:
4+
push:
5+
tags:
6+
- '**'
7+
8+
jobs:
9+
10+
build:
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- uses: actions/checkout@v4
15+
16+
- name: Docker meta
17+
id: meta
18+
uses: docker/metadata-action@v5
19+
with:
20+
images: ghcr.io/${{ github.repository }}
21+
tags: |
22+
type=schedule
23+
type=ref,event=branch
24+
type=ref,event=pr
25+
type=semver,pattern={{version}}
26+
type=semver,pattern={{major}}.{{minor}}
27+
type=semver,pattern={{major}}
28+
type=sha
29+
30+
- name: Set up Docker Buildx
31+
id: buildx
32+
uses: docker/setup-buildx-action@v3
33+
34+
- name: Login to Github Packages
35+
uses: docker/login-action@v3
36+
with:
37+
registry: ghcr.io
38+
username: ${{ github.repository_owner }}
39+
password: ${{ secrets.GITHUB_TOKEN }}
40+
41+
- name: Set build date
42+
run: echo "BUILD_DATE=$(date +%Y%m%d%H%M)" >> $GITHUB_ENV
43+
44+
- name: Build and push
45+
uses: docker/build-push-action@v5
46+
with:
47+
context: .
48+
build-args: |
49+
versionflags=-X 'main.appVersion=${{ github.ref_name }}'
50+
push: ${{ github.event_name != 'pull_request' }}
51+
tags: ${{ steps.meta.outputs.tags }}
52+
labels: ${{ steps.meta.outputs.labels }}

.github/workflows/go.yml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
name: Go
2+
3+
on:
4+
push:
5+
tags:
6+
- '**'
7+
8+
jobs:
9+
10+
build:
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- uses: actions/checkout@v4
15+
16+
- name: Set up Go
17+
uses: actions/setup-go@v5
18+
with:
19+
go-version: 1.25
20+
21+
- name: Build
22+
run: |
23+
versionflags="-X main.appVersion=${{ github.ref_name }}"
24+
for GOOS in linux; do
25+
for GOARCH in amd64 arm64; do
26+
export GOOS GOARCH
27+
CGO_ENABLED=0 go build -v -a -tags netgo -ldflags="-extldflags '-static' -s -w $versionflags" -o build/osctl-${GOOS}-${GOARCH} cmd/main.go
28+
done
29+
done
30+
cd build; sha256sum * > sha256sums.txt
31+
32+
- name: Release
33+
uses: softprops/action-gh-release@v1
34+
with:
35+
generate_release_notes: true
36+
token: ${{ secrets.GITHUB_TOKEN }}
37+
files: |
38+
build/*

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
vendor/
2+
build/

Makefile

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
GOPATH=$(shell pwd)/vendor:$(shell pwd)
2+
GOBIN=$(shell pwd)/build/
3+
GOFILES=./cmd/$(wildcard *.go)
4+
GONAME=$(shell basename "$(PWD)")
5+
PID=/tmp/go-$(GONAME).pid
6+
GOOS=linux
7+
#GOARCH=386
8+
BUILD=`date +%FT%T%z`
9+
MKDIR_P = mkdir -p
10+
11+
all :: build
12+
13+
get:
14+
@GOPATH=$(GOPATH) GOBIN=$(GOBIN) go get -d $(GOFILES)
15+
16+
build:
17+
@echo "Building $(GOFILES) to ./build"
18+
cd ../
19+
# go mod vendor
20+
@GOPATH=$(GOPATH) GOBIN=$(GOBIN) GOOS=$(GOOS) GOARCH=$(GOARCH) go build -mod=mod -ldflags "-s -w -X main.vBuild=${BUILD}" -o build/$(GONAME) $(GOFILES)
21+
strip ./build/$(GONAME)
22+
23+
run:
24+
@GOPATH=$(GOPATH) GOBIN=$(GOBIN) go run $(GOFILES)
25+
26+
clear:
27+
@clear
28+
29+
clean:
30+
@echo "Cleaning"
31+
@GOPATH=$(GOPATH) GOBIN=$(GOBIN) go clean
32+
33+
.PHONY: build get install run clean dirs
34+

cmd/main.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package main
2+
3+
import (
4+
"flag"
5+
"log"
6+
7+
"waitgreen/modules/config"
8+
"waitgreen/modules/wg"
9+
)
10+
11+
var (
12+
configfile string
13+
vBuild string
14+
cnf config.Config
15+
)
16+
17+
func init() {
18+
flag.StringVar(&configfile, "config", "main.yml", "Read configuration from this file")
19+
flag.StringVar(&configfile, "f", "main.yml", "Read configuration from this file")
20+
flag.Parse()
21+
22+
log.SetFlags(log.LstdFlags | log.Lshortfile)
23+
24+
log.Println("Bootstrap: build num.", vBuild)
25+
26+
cnf = config.Parse(configfile)
27+
log.Println("Bootstrap: successful parsing config file.")
28+
29+
}
30+
31+
func main() {
32+
wg.Run(cnf)
33+
}

example/main.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
app:
2+
port: 9900
3+
bind: 0.0.0.0
4+
timeout: 60
5+
waitgreen: true

go.mod

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
module waitgreen
2+
3+
go 1.23.2
4+
5+
require (
6+
github.com/uzhinskiy/lib.go v0.1.7
7+
gopkg.in/yaml.v2 v2.4.0
8+
)

go.sum

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
github.com/uzhinskiy/lib.go v0.1.7 h1:up/fZOtkn0OaE2QsG0gPVsSXOGUiBwwcf1McWenOYvM=
2+
github.com/uzhinskiy/lib.go v0.1.7/go.mod h1:JolhUn+z8ET3PxRuHx2fMJYZEPR2nc3PE1Hu9MvAHls=
3+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
4+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
5+
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
6+
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=

modules/config/config.go

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
// Copyright © 2020 Uzhinskiy Boris
2+
// Licensed under the Apache License, Version 2.0 (the "License");
3+
// you may not use this file except in compliance with the License.
4+
// You may obtain a copy of the License at
5+
//
6+
// http://www.apache.org/licenses/LICENSE-2.0
7+
//
8+
// Unless required by applicable law or agreed to in writing, software
9+
// distributed under the License is distributed on an "AS IS" BASIS,
10+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+
// See the License for the specific language governing permissions and
12+
// limitations under the License.
13+
14+
package config
15+
16+
import (
17+
"io/ioutil"
18+
"log"
19+
20+
"gopkg.in/yaml.v2"
21+
)
22+
23+
type Config struct {
24+
App struct {
25+
Port string `yaml:"port"`
26+
Bind string `yaml:"bind"`
27+
TimeOut int `yaml:"-"`
28+
TimeOutRaw *int `yaml:"timeout"`
29+
DefaultWG bool `yaml:"waitgreen"`
30+
} `yaml:"app"`
31+
}
32+
33+
func Parse(f string) Config {
34+
var c Config
35+
36+
yamlBytes, err := ioutil.ReadFile(f)
37+
if err != nil {
38+
log.Fatal(err)
39+
}
40+
41+
err = yaml.Unmarshal(yamlBytes, &c)
42+
if err != nil {
43+
log.Fatal(err)
44+
}
45+
46+
if c.App.Port == "" {
47+
c.App.Port = "9900"
48+
}
49+
50+
if c.App.Bind == "" {
51+
c.App.Bind = "0.0.0.0"
52+
}
53+
54+
c.App.TimeOut = 30
55+
if c.App.TimeOutRaw != nil {
56+
c.App.TimeOut = *c.App.TimeOutRaw
57+
}
58+
59+
return c
60+
}

modules/wg/wg.go

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package wg
2+
3+
import (
4+
"encoding/json"
5+
6+
"log"
7+
"net/http"
8+
9+
"waitgreen/modules/config"
10+
11+
"github.com/uzhinskiy/lib.go/helpers"
12+
)
13+
14+
type WaitGreen struct {
15+
conf config.Config
16+
}
17+
18+
type apiRequest struct {
19+
WaitGreen bool `json:"waitgreen"`
20+
}
21+
22+
var wgEnabled bool
23+
24+
func Run(cnf config.Config) {
25+
wg := WaitGreen{}
26+
wg.conf = cnf
27+
28+
wgEnabled = cnf.App.DefaultWG
29+
30+
http.HandleFunc("/", wg.ApiHandler)
31+
http.ListenAndServe(cnf.App.Bind+":"+cnf.App.Port, nil)
32+
}
33+
34+
func (wg *WaitGreen) ApiHandler(w http.ResponseWriter, r *http.Request) {
35+
var request apiRequest
36+
37+
defer r.Body.Close()
38+
remoteIP := helpers.GetIP(r.RemoteAddr, r.Header.Get("X-Real-IP"), r.Header.Get("X-Forwarded-For"))
39+
40+
w.Header().Add("Access-Control-Allow-Origin", "*")
41+
w.Header().Add("Access-Control-Allow-Methods", "POST,OPTIONS,GET")
42+
w.Header().Add("Access-Control-Allow-Credentials", "true")
43+
w.Header().Add("Access-Control-Allow-Headers", "Accept, Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token, Authorization")
44+
w.Header().Add("Content-Type", "application/json; charset=utf-8")
45+
w.Header().Set("X-Server", "wg")
46+
47+
if r.Method == "OPTIONS" {
48+
return
49+
}
50+
51+
switch r.Method {
52+
case http.MethodPost:
53+
{
54+
err := json.NewDecoder(r.Body).Decode(&request)
55+
if err != nil {
56+
http.Error(w, err.Error(), http.StatusInternalServerError)
57+
log.Println(remoteIP, "\t", r.Method, "\t", r.URL.Path, "\t", http.StatusInternalServerError, "\t", err.Error())
58+
return
59+
}
60+
61+
wgEnabled = request.WaitGreen
62+
resp := map[string]interface{}{
63+
"status": "Ok",
64+
}
65+
j, _ := json.Marshal(resp)
66+
log.Println(remoteIP, "\t", r.Method, "\t", r.URL.Path, "\t", "200", "\t", r.UserAgent())
67+
w.Write(j)
68+
69+
}
70+
case http.MethodGet:
71+
{
72+
resp := map[string]interface{}{
73+
"waitgreen": wgEnabled,
74+
}
75+
j, _ := json.Marshal(resp)
76+
log.Println(remoteIP, "\t", r.Method, "\t", r.URL.Path, "\t", "200", "\t", r.UserAgent())
77+
w.Write(j)
78+
}
79+
}
80+
81+
}

0 commit comments

Comments
 (0)