Skip to content

Commit 8c9bbbe

Browse files
first running version
1 parent b72dd96 commit 8c9bbbe

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

95 files changed

+25867
-0
lines changed

.bumpversion.cfg

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[bumpversion]
2+
current_version = 0.0.0
3+
files = main.go
4+
commit = True
5+
tag = True

.drone.yml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
workspace:
2+
base: /drone/src
3+
path: /usr/local/src/github.com/qnib/doxy
4+
5+
pipeline:
6+
alpine:
7+
image: qnib/alplain-golang
8+
commands:
9+
- govendor build -o doxy_alpine
10+
x86:
11+
image: qnib/uplain-golang
12+
commands:
13+
- govendor build -o doxy_x86

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,6 @@
1212

1313
# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736
1414
.glide/
15+
16+
# binaries
17+
doxy_*

doxy.pattern

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
# List and inspect containers
2+
^/(v\d\.\d+/)?containers(/\w+)?/json$
3+
# List and inspect services
4+
^/(v\d\.\d+/)?services(/[0-9a-f]+)?$
5+
# List and inspect tasks
6+
^/(v\d\.\d+/)?tasks(/\w+)?$
7+
# List and inspect networks
8+
^/(v\d\.\d+/)?networks(/\w+)?$
9+
# List and inspect nodes
10+
^/(v\d\.\d+/)?nodes(/\w+)?$
11+
# Show engine info
12+
^/(v\d\.\d+/)?info$
13+
# Healthcheck
14+
^/_ping$

main.go

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
package main
2+
3+
import (
4+
"os"
5+
"log"
6+
"github.com/zpatrick/go-config"
7+
"github.com/codegangsta/cli"
8+
"github.com/qnib/doxy/proxy"
9+
"bufio"
10+
"strings"
11+
)
12+
13+
func ReadPatterns(path string) (patterns []string, err error) {
14+
file, err := os.Open(path)
15+
if err != nil {
16+
return
17+
}
18+
defer file.Close()
19+
20+
scanner := bufio.NewScanner(file)
21+
for scanner.Scan() {
22+
line := scanner.Text()
23+
if ! strings.HasPrefix(line, "#") {
24+
patterns = append(patterns, line)
25+
}
26+
}
27+
return
28+
}
29+
30+
func RunApp(ctx *cli.Context) {
31+
log.Printf("[II] Start Version: %s", ctx.App.Version)
32+
cfg := config.NewConfig([]config.Provider{config.NewCLI(ctx, true)})
33+
newSock, _ := cfg.String("proxy-socket")
34+
dockerSock, _ := cfg.String("docker-socket")
35+
debug, _ := cfg.Bool("debug")
36+
patternsFile, _ := cfg.String("pattern-file")
37+
patterns, err := ReadPatterns(patternsFile)
38+
if err != nil {
39+
log.Printf("Error reading patterns file (%s), using default patterns\n", err.Error())
40+
patterns = []string{
41+
`^/(v\d\.\d+/)?containers(/\w+)?/json$`,
42+
`^/(v\d\.\d+/)?services(/[0-9a-f]+)?$`,
43+
`^/(v\d\.\d+/)?tasks(/\w+)?$`,
44+
`^/(v\d\.\d+/)?networks(/\w+)?$`,
45+
`^/(v\d\.\d+/)?nodes(/\w+)?$`,
46+
`^/(v\d\.\d+/)?info$`,
47+
"^/_ping$",
48+
}
49+
if debug {
50+
for i, p := range patterns {
51+
log.Printf("%-3d: %s\n", i,p)
52+
}
53+
54+
}
55+
}
56+
p := proxy.NewProxy(newSock, dockerSock, debug)
57+
p.AddPatterns(patterns)
58+
p.Run()
59+
}
60+
61+
func main() {
62+
app := cli.NewApp()
63+
app.Name = "Start container to terminate SSL for others."
64+
app.Usage = "go-byfahrer [options]"
65+
app.Version = "0.0.0"
66+
app.Flags = []cli.Flag{
67+
cli.StringFlag{
68+
Name: "docker-socket",
69+
Value: "/var/run/docker.sock",
70+
Usage: "Docker host to connect to.",
71+
EnvVar: "DOXY_DOCKER_SOCKET",
72+
}, cli.StringFlag{
73+
Name: "proxy-socket",
74+
Value: "/tmp/doxy.sock",
75+
Usage: "Proxy socket to be created",
76+
EnvVar: "DOXY_PROXY_SOCKET",
77+
}, cli.BoolFlag{
78+
Name: "debug",
79+
Usage: "Print proxy requests",
80+
EnvVar: "DOXY_DEBUG",
81+
}, cli.StringFlag{
82+
Name: "pattern-file",
83+
Value: "/etc/doxy.pattern",
84+
Usage: "File holding line-separated regex-patterns to be allowed (comments allowed, use #)",
85+
EnvVar: "DOXY_PATTERN_FILE",
86+
},
87+
}
88+
app.Action = RunApp
89+
app.Run(os.Args)
90+
}

proxy/main.go

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
package proxy
2+
3+
import (
4+
"net/http"
5+
"os"
6+
"syscall"
7+
"os/signal"
8+
"github.com/urfave/negroni"
9+
10+
)
11+
12+
type Proxy struct {
13+
dockerSocket, newSocket string
14+
debug bool
15+
patterns []string
16+
}
17+
18+
func NewProxy(newsock, oldsock string, debug bool) Proxy {
19+
return Proxy{
20+
dockerSocket: oldsock,
21+
newSocket: newsock,
22+
debug: debug,
23+
patterns: []string{},
24+
}
25+
}
26+
27+
func (p *Proxy) AddPatterns(patterns []string) {
28+
p.patterns = append(p.patterns,patterns...)
29+
}
30+
31+
func (p *Proxy) AddPattern(pattern string) {
32+
p.patterns = append(p.patterns,pattern)
33+
}
34+
35+
func (p *Proxy) Run() {
36+
upstream := NewUpstream(p.dockerSocket, p.patterns)
37+
sigc := make(chan os.Signal, 1)
38+
signal.Notify(sigc, os.Interrupt, os.Kill, syscall.SIGTERM)
39+
l, err := ListenToNewSock(p.newSocket, sigc)
40+
if err != nil {
41+
panic(err)
42+
}
43+
n := negroni.New() // Includes some default middlewares
44+
if p.debug {
45+
n.Use(negroni.NewLogger())
46+
}
47+
n.UseHandler(upstream)
48+
if err = http.Serve(l, n); err != nil {
49+
panic(err)
50+
}
51+
}
52+

proxy/newsock.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package proxy
2+
3+
import (
4+
"path/filepath"
5+
"log"
6+
"os"
7+
"net"
8+
)
9+
10+
func ListenToNewSock(newsock string, sigc chan os.Signal) (l net.Listener, err error) {
11+
// extract directory for newsock
12+
dir, _ := filepath.Split(newsock)
13+
// attempt to create dir and ignore if it's already existing
14+
_ = os.Mkdir(dir, 0777)
15+
l, err = net.Listen("unix", newsock)
16+
if err != nil {
17+
panic(err)
18+
}
19+
os.Chmod(newsock, 0666)
20+
log.Println("[gk-soxy] Listening on " + newsock)
21+
go func(c chan os.Signal) {
22+
sig := <-c
23+
log.Printf("[gk-soxy] Caught signal %s: shutting down.\n", sig)
24+
if err := l.Close(); err != nil {
25+
panic(err)
26+
}
27+
os.Exit(0)
28+
}(sigc)
29+
return
30+
}

proxy/proxy.go

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package proxy
2+
3+
import (
4+
"net"
5+
"fmt"
6+
"net/url"
7+
"net/http"
8+
"net/http/httputil"
9+
"regexp"
10+
)
11+
12+
type UpStream struct {
13+
Name string
14+
proxy http.Handler
15+
allowed []*regexp.Regexp
16+
}
17+
18+
// UnixSocket just provides the path, so that I can test it
19+
type UnixSocket struct {
20+
path string
21+
}
22+
23+
// NewUnixSocket return a socket using the path
24+
func NewUnixSocket(path string) UnixSocket {
25+
return UnixSocket{
26+
path: path,
27+
}
28+
}
29+
30+
func (us *UnixSocket) connectSocket(proto, addr string) (net.Conn, error) {
31+
conn, err := net.Dial("unix", us.path)
32+
return conn, err
33+
}
34+
35+
func newReverseProxy(dial func(network, addr string) (net.Conn, error)) *httputil.ReverseProxy {
36+
return &httputil.ReverseProxy{
37+
Director: func(req *http.Request) {
38+
param := ""
39+
if len(req.URL.RawQuery) > 0 {
40+
param = "?" + req.URL.RawQuery
41+
}
42+
u, _ := url.Parse("http://docker" + req.URL.Path + param)
43+
*req.URL = *u
44+
},
45+
Transport: &http.Transport{
46+
Dial: dial,
47+
},
48+
}
49+
}
50+
51+
// NewUpstream returns a new socket (magic)
52+
func NewUpstream(socket string, regs []string) *UpStream {
53+
us := NewUnixSocket(socket)
54+
a := []*regexp.Regexp{}
55+
for _, r := range regs {
56+
p, _ := regexp.Compile(r)
57+
a = append(a, p)
58+
}
59+
return &UpStream{
60+
Name: socket,
61+
proxy: newReverseProxy(us.connectSocket),
62+
allowed: a,
63+
}
64+
}
65+
66+
func (u *UpStream) ServeHTTP(w http.ResponseWriter, req *http.Request) {
67+
if req.Method != "GET" {
68+
http.Error(w, fmt.Sprintf("Only GET requests are allowed, req.Method: %s", req.Method), 400)
69+
return
70+
}
71+
for _, a := range u.allowed {
72+
if a.MatchString(req.URL.Path) {
73+
u.proxy.ServeHTTP(w, req)
74+
return
75+
}
76+
}
77+
http.Error(w, fmt.Sprintf("'%s' is not allowed.", req.URL.Path), 403)
78+
}

vendor/github.com/BurntSushi/toml/COMPATIBLE

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vendor/github.com/BurntSushi/toml/COPYING

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)