Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
rkojedzinszky committed Jun 1, 2024
0 parents commit 178b935
Show file tree
Hide file tree
Showing 16 changed files with 1,193 additions and 0 deletions.
66 changes: 66 additions & 0 deletions .github/workflows/container-image.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
name: container image

on:
push:
branches:
- main
tags:
- "*.*.*"

env:
REGISTRY: ghcr.io

jobs:
build:
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup go
uses: actions/setup-go@v5
with:
go-version: "^1.22.0"

- name: Compile
env:
CGO_ENABLED: 0
run: |
GOARCH=amd64 go build -ldflags -s -o director.amd64 ./cmd/director/
GOARCH=arm go build -ldflags -s -o director.arm ./cmd/director/
GOARCH=arm64 go build -ldflags -s -o director.arm64 ./cmd/director/
- name: Setup qemu
uses: docker/setup-qemu-action@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Login to registry
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
password: ${{ github.token }}

- name: Extract metadata (tags, labels) for Docker
id: meta
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ github.repository }}
tags: |
type=semver,pattern={{major}}.{{minor}}.{{patch}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
# set latest tag for default branch
type=raw,value=latest,enable={{is_default_branch}}
- name: Build and publish
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64, linux/arm/v7, linux/arm64/v8
push: true
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
9 changes: 9 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
FROM scratch

ARG TARGETARCH

COPY director.${TARGETARCH} /director

USER 65534

CMD ["/director"]
26 changes: 26 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
Copyright (c) Richard Kojedzinszky <richard@kojedz.in>
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# go-dovecot-director

A [Dovecot Proxy](https://doc.dovecot.org/admin_manual/dovecot_proxy/) helper to map users to different backends. This application monitors backends running in Kubernetes. Simply, ready PODs are considered as live backends. They are monitored through Kubernetes endpoints.

Mapping is stored in PostgreSQL.
152 changes: 152 additions & 0 deletions cmd/director/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
/*
Copyright (c) Richard Kojedzinszky <richard@kojedz.in>
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the University nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS “AS IS” AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
*/

package main

import (
"context"
"fmt"
"log"
"net"
"os"
"os/signal"
"path/filepath"
"sync"
"syscall"
"time"

"github.com/jackc/pgx/v5/pgxpool"
"github.com/namsral/flag"

"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
"k8s.io/client-go/util/homedir"

"go-dovecot-director/pkg/allocator/postgres"
"go-dovecot-director/pkg/director"
kpool "go-dovecot-director/pkg/pool/kubernetes"
)

var (
kubeconfig = func() *string {
if home := homedir.HomeDir(); home != "" {
return flag.String("kubeconfig", filepath.Join(home, ".kube", "config"), "(optional) absolute path to the kubeconfig file")
}
return flag.String("kubeconfig", "", "absolute path to the kubeconfig file")
}()

namespace = flag.String("namespace", "", "Namespace of services to watch")
service = flag.String("service", "", "Service for backend PODs")

directorListenAddress = flag.String("director-listen-address", ":8080", "Listen address for director requests")

databaseHost = flag.String("database-host", "postgres", "Postfixadmin database hostname")
databasePort = flag.Int("database-port", 5432, "Postfixadmin database port")
databaseName = flag.String("database-name", "postfixadmin", "Postfixadmin database name")
databaseUser = flag.String("database-user", "postfixadmin", "Postfixadmin database username")
databasePassword = flag.String("database-password", "postfixadmin", "Postfixadmin database password")
)

func newClientSet() (*kubernetes.Clientset, error) {
config, err := rest.InClusterConfig()
if err != nil {
config, err = clientcmd.BuildConfigFromFlags("", *kubeconfig)
}

if err != nil {
return nil, err
}

return kubernetes.NewForConfig(config)
}

func main() {
flag.Parse()

directorListener, err := net.Listen("tcp", *directorListenAddress)
if err != nil {
log.Fatal(err)
}

db, err := pgxpool.New(context.TODO(),
fmt.Sprintf(
"host=%s port=%d database=%s user=%s password=%s sslmode=disable pool_max_conns=2",
*databaseHost, *databasePort, *databaseName, *databaseUser, *databasePassword,
),
)
if err != nil {
log.Fatal(err)
}

client, err := newClientSet()
if err != nil {
log.Fatal(err)
}

pool, err := kpool.New(client, *namespace, *service)
if err != nil {
log.Fatal(err)
}

allocator := postgres.New(db, pool)
dir := director.New(allocator)

ctx, cancel := context.WithCancel(context.Background())
defer cancel()

wg := &sync.WaitGroup{}

// start poolmonitor
wg.Add(1)
go func() {
defer wg.Done()

pool.Run(ctx)
}()

// start dovecot server
wg.Add(1)
go func() {
defer wg.Done()

dir.Serve(ctx, directorListener)
}()

sigchan := make(chan os.Signal, 1)
signal.Notify(sigchan, syscall.SIGTERM, syscall.SIGINT)
<-sigchan

log.Print("Exiting gracefully...")
time.Sleep(5 * time.Second)

cancel()

wg.Wait()
}
57 changes: 57 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
module go-dovecot-director

go 1.22.0

toolchain go1.22.3

require (
github.com/jackc/pgx/v5 v5.6.0
github.com/namsral/flag v1.7.4-pre
k8s.io/api v0.30.1
k8s.io/apimachinery v0.30.1
k8s.io/client-go v0.30.1
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
github.com/go-logr/logr v1.4.1 // indirect
github.com/go-openapi/jsonpointer v0.19.6 // indirect
github.com/go-openapi/jsonreference v0.20.2 // indirect
github.com/go-openapi/swag v0.22.3 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/gnostic-models v0.6.8 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/imdario/mergo v0.3.6 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
github.com/jackc/pgservicefile v0.0.0-20221227161230-091c0ba34f0a // indirect
github.com/jackc/puddle/v2 v2.2.1 // indirect
github.com/josharian/intern v1.0.0 // indirect
github.com/json-iterator/go v1.1.12 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
github.com/spf13/pflag v1.0.5 // indirect
golang.org/x/crypto v0.21.0 // indirect
golang.org/x/net v0.23.0 // indirect
golang.org/x/oauth2 v0.10.0 // indirect
golang.org/x/sync v0.1.0 // indirect
golang.org/x/sys v0.18.0 // indirect
golang.org/x/term v0.18.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/time v0.3.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/protobuf v1.33.0 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
k8s.io/klog/v2 v2.120.1 // indirect
k8s.io/kube-openapi v0.0.0-20240228011516-70dd3763d340 // indirect
k8s.io/utils v0.0.0-20230726121419-3b25d923346b // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.4.1 // indirect
sigs.k8s.io/yaml v1.3.0 // indirect
)
Loading

0 comments on commit 178b935

Please sign in to comment.