Skip to content

Commit

Permalink
server configs now are being read recursively from the main dir
Browse files Browse the repository at this point in the history
  • Loading branch information
realDragonium committed Aug 5, 2021
1 parent 9fa5e44 commit a776ab3
Show file tree
Hide file tree
Showing 6 changed files with 117 additions and 81 deletions.
10 changes: 2 additions & 8 deletions .github/workflows/go.yml → .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
name: Go
name: Build

on:
push:
tags:
- v*
workflow_dispatch:

jobs:

build:
runs-on: ubuntu-latest
steps:
Expand All @@ -20,6 +17,3 @@ jobs:
- name: Build
working-directory: ./cmd/ultraviolet
run: go build

- name: Test
run: go test ./...
21 changes: 21 additions & 0 deletions .github/workflows/unit-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
name: Unit tests

on:
push:
branches: *
pull_request:
branches: *

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2

- name: Set up Go
uses: actions/setup-go@v2
with:
go-version: 1.16

- name: Test
run: go test ./...
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Ultraviolet - Alpha v0.10
# Ultraviolet - Alpha v0.10.2

## What is Ultraviolet?
[infrared](https://github.com/haveachin/infrared) but different.
Expand Down Expand Up @@ -35,7 +35,7 @@ IMPORTANT: There is a limit of one 'parent' process. So when you reload Ultravio
`-configs` specifies the path to the config directory [default: `"/etc/ultraviolet/"`]

The main config file needs have the name `ultraviolet.json`.
Every server config needs to be in a directory called `config` and end it needs to end with `.json`. Server config files can also be placed inside other directories in the config directory.
Every server config needs to end with `.json`. Server config files will be searched for recursively.

## How does some stuff work
### rate limiting
Expand Down
3 changes: 3 additions & 0 deletions config/file.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ func ReadServerConfigs(path string) ([]ServerConfig, error) {
if filepath.Ext(path) != ".json" {
return nil
}
if info.Name() == "ultraviolet" {
return nil
}
filePaths = append(filePaths, path)
return nil
})
Expand Down
114 changes: 63 additions & 51 deletions config/file_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (

func TestReadServerConfig(t *testing.T) {
cfg := config.ServerConfig{
Domains: []string{"infrared"},
Domains: []string{"ultraviolet"},
ProxyTo: ":25566",
}
tmpfile, err := ioutil.TempFile("", "example*.json")
Expand All @@ -49,61 +49,73 @@ func TestReadServerConfig(t *testing.T) {
}

func TestReadServerConfigs(t *testing.T) {
generateNumberOfFile := 3
cfg := config.ServerConfig{
Domains: []string{"infrared"},
Domains: []string{"ultraviolet"},
ProxyTo: ":25566",
}
tmpDir, _ := ioutil.TempDir("", "configs")
for i := 0; i < 3; i++ {
file, _ := json.MarshalIndent(cfg, "", " ")
tmpfile, err := ioutil.TempFile(tmpDir, "example*.json")
if err != nil {
t.Fatal(err)
}
defer os.Remove(tmpfile.Name())
if _, err := tmpfile.Write(file); err != nil {
t.Fatal(err)
}
if err := tmpfile.Close(); err != nil {
t.Fatal(err)
}
}
loadedCfgs, _ := config.ReadServerConfigs(tmpDir)
for i, loadedCfg := range loadedCfgs {
loadedCfg.FilePath = ""
if !reflect.DeepEqual(cfg, loadedCfg) {
t.Errorf("index: %d \nWanted:%v \n got: %v", i, cfg, loadedCfg)
}
tt := []struct {
testName string
hasDifferentFile bool
specialName string
expectedReadFile int
}{
{
testName: "normal configs",
hasDifferentFile: false,
expectedReadFile: generateNumberOfFile,
},
{
testName: "doesnt read file with no extension",
hasDifferentFile: true,
specialName: "example*",
expectedReadFile: generateNumberOfFile - 1,
},
{
testName: "doesnt read file with different extension",
hasDifferentFile: true,
specialName: "example*.yml",
expectedReadFile: generateNumberOfFile - 1,
},
{
testName: "doesnt read ultraviolet config file",
hasDifferentFile: true,
specialName: "ultraviolet.json",
expectedReadFile: generateNumberOfFile - 1,
},
}
}

func TestReadServerConfigs_OnlyReadJson(t *testing.T) {
cfg := config.ServerConfig{
Domains: []string{"infrared"},
ProxyTo: ":25566",
}
tmpDir, _ := ioutil.TempDir("", "configs")
for i := 0; i < 3; i++ {
fileName := "example*.json"
if i == 0 {
fileName = "example*"
}
file, _ := json.MarshalIndent(cfg, "", " ")
tmpfile, err := ioutil.TempFile(tmpDir, fileName)
if err != nil {
t.Fatal(err)
}
defer os.Remove(tmpfile.Name())
if _, err := tmpfile.Write(file); err != nil {
t.Fatal(err)
}
if err := tmpfile.Close(); err != nil {
t.Fatal(err)
}
}
loadedCfgs, _ := config.ReadServerConfigs(tmpDir)
if len(loadedCfgs) != 2 {
t.Errorf("Expected 2 configs to be read but there are %d configs read", len(loadedCfgs))
for _, tc := range tt {
t.Run(tc.testName, func(t *testing.T) {
tmpDir, _ := ioutil.TempDir("", "configs")
bb, _ := json.MarshalIndent(cfg, "", " ")
for i := 0; i < generateNumberOfFile; i++ {
fileName := "example*.json"
if tc.hasDifferentFile && i == 0 {
fileName = tc.specialName
}
tmpfile, err := ioutil.TempFile(tmpDir, fileName)
if err != nil {
t.Fatal(err)
}
if _, err := tmpfile.Write(bb); err != nil {
t.Fatal(err)
}
if err := tmpfile.Close(); err != nil {
t.Fatal(err)
}
}
loadedCfgs, _ := config.ReadServerConfigs(tmpDir)
for i, loadedCfg := range loadedCfgs {
loadedCfg.FilePath = ""
if !reflect.DeepEqual(cfg, loadedCfg) {
t.Errorf("index: %d \nWanted:%v \n got: %v", i, cfg, loadedCfg)
}
}
if len(loadedCfgs) != tc.expectedReadFile {
t.Errorf("Expected %v configs to be read but there are %d configs read", tc.expectedReadFile, len(loadedCfgs))
}
})
}
}

Expand Down
46 changes: 26 additions & 20 deletions proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"os"
"os/signal"
"path/filepath"
"runtime"
"syscall"
"time"

Expand All @@ -29,7 +30,7 @@ var (
)

func RunProxy() {
log.Println("Starting up Alpha-v0.10")
log.Println("Starting up Alpha-v0.10.2")
var (
cfgDir = flag.String("configs", defaultCfgPath, "`Path` to config directory")
)
Expand All @@ -41,8 +42,7 @@ func RunProxy() {
log.Fatalf("Read main config file at '%s' - error: %v", mainCfgPath, err)
}

serverCfgsPath := filepath.Join(*cfgDir, "config")
serverCfgs, err := config.ReadServerConfigs(serverCfgsPath)
serverCfgs, err := config.ReadServerConfigs(*cfgDir)
if err != nil {
log.Fatalf("Something went wrong while reading config files: %v", err)
}
Expand All @@ -60,27 +60,33 @@ func RunProxy() {
}

func createListener(listenAddr string, useProxyProtocol bool, pidFile string) net.Listener {
upg, err := tableflip.New(tableflip.Options{
PIDFile: pidFile,
})
if err != nil {
log.Fatal(err)
}
go func() {
sig := make(chan os.Signal, 1)
signal.Notify(sig, syscall.SIGHUP)
for range sig {
err := upg.Upgrade()
if err != nil {
log.Println("upgrade failed:", err)
}
var ln net.Listener
var err error
if runtime.GOOS == "windows" {
ln, err = net.Listen("tcp", listenAddr)
} else {
upg, err := tableflip.New(tableflip.Options{
PIDFile: pidFile,
})
if err != nil {
log.Fatal(err)
}
}()

ln, err := upg.Listen("tcp", listenAddr)
go func() {
sig := make(chan os.Signal, 1)
signal.Notify(sig, syscall.SIGHUP)
for range sig {
err := upg.Upgrade()
if err != nil {
log.Println("upgrade failed:", err)
}
}
}()
ln, err = upg.Listen("tcp", listenAddr)
}
if err != nil {
log.Fatalf("Can't listen: %v", err)
}

if useProxyProtocol {
proxyListener := &proxyproto.Listener{
Listener: ln,
Expand Down

0 comments on commit a776ab3

Please sign in to comment.