[WIP] first implementation stubs
This commit is contained in:
31
internal/config.go
Normal file
31
internal/config.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/jinzhu/configor"
|
||||
)
|
||||
|
||||
type Config = struct {
|
||||
LogLevel string `default:"Info" env:"MAIL_DNS_SERVICE_LOGLEVEL"`
|
||||
LabelSelector string `default:"kops.k8s.io/instance-role=Node" env:"MAIL_DNS_SERVICE_LABELSELECTOR"`
|
||||
HcloudToken string `default:"" env:"MAIL_DNS_SERVICE_HCLOUD_TOKEN"`
|
||||
}
|
||||
|
||||
func GenConfig() (cfg *Config, err error) {
|
||||
|
||||
cfg = &Config{}
|
||||
|
||||
err = configor.New(&configor.Config{
|
||||
ENVPrefix: "METALLB_IP_FLOATER",
|
||||
AutoReload: true,
|
||||
Silent: true,
|
||||
AutoReloadInterval: time.Minute}).Load(cfg, "config.json")
|
||||
if err != nil {
|
||||
return nil, errors.New(fmt.Sprintf("Error generating Config: %s", err.Error()))
|
||||
}
|
||||
return cfg, nil
|
||||
|
||||
}
|
22
internal/config_test.go
Normal file
22
internal/config_test.go
Normal file
@@ -0,0 +1,22 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
)
|
||||
|
||||
var defaultConfig = Config{
|
||||
LogLevel: "Info",
|
||||
LabelSelector: "kops.k8s.io/instance-role=Node",
|
||||
HcloudToken: "",
|
||||
}
|
||||
|
||||
func TestConfigDefaults(t *testing.T) {
|
||||
cfg, err := GenConfig()
|
||||
if err != nil {
|
||||
t.Errorf("%s", err.Error())
|
||||
}
|
||||
if !reflect.DeepEqual(&defaultConfig, cfg) {
|
||||
t.Errorf("got %+v, want %+v", cfg, defaultConfig)
|
||||
}
|
||||
}
|
31
internal/health.go
Normal file
31
internal/health.go
Normal file
@@ -0,0 +1,31 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func StartHealthEndpoint() {
|
||||
r := mux.NewRouter()
|
||||
r.Use(mux.CORSMethodMiddleware(r))
|
||||
r.HandleFunc("/health", send200).Methods(http.MethodGet)
|
||||
err := http.ListenAndServe("0.0.0.0:8080", r)
|
||||
if err != nil {
|
||||
log.WithFields(log.Fields{
|
||||
"Caller": "StartHealthEndpoint",
|
||||
}).Error(fmt.Sprintf("Error creating health endpoint: %s", err.Error()))
|
||||
}
|
||||
}
|
||||
|
||||
func send200(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
_, err := w.Write([]byte{})
|
||||
if err != nil {
|
||||
log.WithFields(log.Fields{
|
||||
"Caller": "send200",
|
||||
}).Error(fmt.Sprintf("Error answering health endpoint: %s", err.Error()))
|
||||
}
|
||||
}
|
23
internal/health_test.go
Normal file
23
internal/health_test.go
Normal file
@@ -0,0 +1,23 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestHealth(t *testing.T) {
|
||||
go func() {
|
||||
StartHealthEndpoint()
|
||||
}()
|
||||
request, _ := http.NewRequest(http.MethodGet, "http://localhost:8080/health", strings.NewReader(""))
|
||||
resp, err := http.DefaultClient.Do(request)
|
||||
|
||||
if err != nil {
|
||||
t.Errorf("Health endpoint did not start: %v", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
t.Errorf("Bad response from health endpoint. Want: %d, got %d", http.StatusOK, resp.StatusCode)
|
||||
}
|
||||
}
|
41
internal/hetzner.go
Normal file
41
internal/hetzner.go
Normal file
@@ -0,0 +1,41 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/hetznercloud/hcloud-go/hcloud"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func GetAllNodes(cfg *Config) ([]*hcloud.Server, error) {
|
||||
client := hcloud.NewClient(hcloud.WithToken(cfg.HcloudToken))
|
||||
servers, _, err := client.Server.List(context.TODO(), hcloud.ServerListOpts{
|
||||
ListOpts: hcloud.ListOpts{
|
||||
LabelSelector: cfg.LabelSelector,
|
||||
}})
|
||||
if err != nil {
|
||||
return nil, errors.New(fmt.Sprintf("Error listing Hetzner Nodes: %s", err.Error()))
|
||||
}
|
||||
|
||||
if servers == nil {
|
||||
return nil, errors.New(fmt.Sprintf("No Nodes found with label selector: %s", cfg.LabelSelector))
|
||||
}
|
||||
return servers, nil
|
||||
|
||||
}
|
||||
|
||||
func GetAllIps(servers []*hcloud.Server) ([]string, error) {
|
||||
ips := make([]string, len(servers))
|
||||
for i, instance := range servers {
|
||||
if len(instance.PrivateNet) == 0 || instance.PrivateNet[0].IP == nil {
|
||||
return []string{""}, errors.New(fmt.Sprintf("Instance %s has no attached IP", instance.Name))
|
||||
}
|
||||
log.WithFields(log.Fields{
|
||||
"Caller": "GetAllIps",
|
||||
}).Info(fmt.Sprintf("Found IP: %s", instance.PrivateNet[0].IP.String()))
|
||||
ips[i] = instance.PrivateNet[0].IP.String()
|
||||
}
|
||||
return ips, nil
|
||||
}
|
30
internal/hetzner_test.go
Normal file
30
internal/hetzner_test.go
Normal file
@@ -0,0 +1,30 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/hetznercloud/hcloud-go/hcloud"
|
||||
)
|
||||
|
||||
func TestGetAllIps(t *testing.T) {
|
||||
|
||||
servers := []*hcloud.Server{{
|
||||
Status: hcloud.ServerStatusRunning,
|
||||
Name: "Test",
|
||||
}}
|
||||
|
||||
servers = append(servers, &hcloud.Server{
|
||||
Status: hcloud.ServerStatusRunning,
|
||||
Name: "Test2",
|
||||
})
|
||||
|
||||
expectedError := "Instance Test has no attached IP"
|
||||
_, err := GetAllIps(servers)
|
||||
if err == nil {
|
||||
t.Error("GetAllIps did not error with missing data")
|
||||
}
|
||||
if err.Error() != expectedError {
|
||||
t.Errorf("Wrong error message. want %s, got %s", expectedError, err.Error())
|
||||
}
|
||||
|
||||
}
|
61
internal/k8s.go
Normal file
61
internal/k8s.go
Normal file
@@ -0,0 +1,61 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"errors"
|
||||
"fmt"
|
||||
"html/template"
|
||||
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/rest"
|
||||
)
|
||||
|
||||
func RecreateDnsCrd() error {
|
||||
k8s_config, err := rest.InClusterConfig()
|
||||
if err != nil {
|
||||
return errors.New(fmt.Sprintf("Could not create in cluster k8s config: %v", err))
|
||||
}
|
||||
_, err = kubernetes.NewForConfig(k8s_config)
|
||||
if err != nil {
|
||||
return errors.New(fmt.Sprintf("Could not create k8s client: %v", err))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
var CRD_TEMPLATE = `
|
||||
apiVersion: externaldns.k8s.io/v1alpha1
|
||||
kind: DNSEndpoint
|
||||
metadata:
|
||||
name: {{ .Name }}
|
||||
annotations:
|
||||
external.dns/provider: cf
|
||||
spec:
|
||||
endpoints:
|
||||
- dnsName: mail
|
||||
recordTTL: 180
|
||||
recordType: A
|
||||
targets:
|
||||
- {{ .IP }}
|
||||
`
|
||||
|
||||
type CrdConfig struct {
|
||||
Name string
|
||||
IP string
|
||||
}
|
||||
|
||||
func generateCrd(name string, ip string) (string, error) {
|
||||
config := CrdConfig{
|
||||
Name: name,
|
||||
IP: ip,
|
||||
}
|
||||
tmpl, err := template.New("crd").Parse(CRD_TEMPLATE)
|
||||
if err != nil {
|
||||
return "", errors.New(fmt.Sprintf("Errors in crd template: %s", err.Error()))
|
||||
}
|
||||
var buf bytes.Buffer
|
||||
err = tmpl.Execute(&buf, &config)
|
||||
if err != nil {
|
||||
return "", errors.New(fmt.Sprintf("Could not render crd template: %s", err.Error()))
|
||||
}
|
||||
return buf.String(), nil
|
||||
}
|
28
internal/utils/logging.go
Normal file
28
internal/utils/logging.go
Normal file
@@ -0,0 +1,28 @@
|
||||
package utils
|
||||
|
||||
import (
|
||||
"os"
|
||||
|
||||
"git.uploadfilter24.eu/covidnetes/mail-dns-service/internal"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func ConfigureLogger(cfg *internal.Config) {
|
||||
|
||||
switch cfg.LogLevel {
|
||||
case "Debug":
|
||||
log.SetLevel(log.DebugLevel)
|
||||
case "Info":
|
||||
log.SetLevel(log.InfoLevel)
|
||||
case "Warn":
|
||||
log.SetLevel(log.WarnLevel)
|
||||
case "Error":
|
||||
log.SetLevel(log.ErrorLevel)
|
||||
default:
|
||||
log.SetLevel(log.InfoLevel)
|
||||
log.Warnf("Home: invalid log level supplied: '%s'", cfg.LogLevel)
|
||||
}
|
||||
|
||||
log.SetFormatter(&log.JSONFormatter{})
|
||||
log.SetOutput(os.Stdout)
|
||||
}
|
Reference in New Issue
Block a user