Commit 3475cc7b authored by Geoff Simmons's avatar Geoff Simmons

Add cmd/ and the main package.

parent db510fcc
*~
# Build aretfacts
/k8s-crt-dnldr
/cmd/main_version.go
......@@ -24,9 +24,11 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
all: build
all k8s-crt-dnldr: build
CGO_ENABLED=0 GOOS=linux go build -ldflags="-w -s" -o k8s-crt-dnldr \
cmd/*.go
CODE_SUBDIRS=./pkg/...
CODE_SUBDIRS=./pkg/... ./cmd/...
build:
go fmt $(CODE_SUBDIRS)
go generate $(CODE_SUBDIRS)
......@@ -37,9 +39,12 @@ check: build
golint ./pkg/pem/...
golint ./pkg/rest/...
golint ./pkg/k8s/...
golint ./cmd/...
go test -v ./pkg/crt/... ./pkg/pem/... ./pkg/rest/...
test: check
clean:
go clean $(CODE_SUBDIRS)
rm -f cmd/main_version.go
rm -f k8s-crt-dnldr
/*
* Copyright (c) 2020 UPLEX Nils Goroll Systemoptimierung
* All rights reserved
*
* Author: Geoffrey Simmons <geoffrey.simmons@uplex.de>
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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
//go:generate gogitversion -p main
import (
"flag"
"fmt"
"math"
"os"
"os/signal"
"strconv"
"strings"
"syscall"
"time"
"code.uplex.de/k8s/k8s-crt-dnldr/pkg/k8s"
"code.uplex.de/k8s/k8s-crt-dnldr/pkg/rest"
"github.com/sirupsen/logrus"
"golang.org/x/sys/unix"
api_v1 "k8s.io/api/core/v1"
"k8s.io/client-go/kubernetes"
k8s_rest "k8s.io/client-go/rest"
"k8s.io/client-go/tools/clientcmd"
)
var (
versionF = flag.Bool("version", false, "print version and exit")
loglvlF = flag.String("log-level", "INFO",
"log level: one of PANIC, FATAL, ERROR, WARN, INFO, DEBUG, \n"+
"or TRACE")
namespaceF = flag.String("namespace", api_v1.NamespaceAll,
"namespace in which to listen for resources (default all)")
masterURLF = flag.String("masterurl", "", "cluster master URL, for "+
"out-of-cluster runs")
kubeconfigF = flag.String("kubeconfig", "", "config path for the "+
"cluster master URL, for out-of-cluster runs")
monIntvlF = flag.Duration("monitorintvl", 30*time.Second,
"interval at which the monitor thread checks and updates\n"+
"the Varnish instance.\n"+
"Monitor deactivated when <= 0s")
metricsPortF = flag.Uint("metricsport", 8080,
"port at which to listen for the /metrics endpoint")
resyncPeriodF = flag.Duration("resyncPeriod", 30*time.Second,
"if non-zero, re-update the controller with the state of\n"+
"the cluster this often, even if nothing has changed,\n"+
"to synchronize state that may have been missed")
baseF = flag.String("base", "/etc/ssl/private",
"base directory in which PEM files are to be stored\n")
gidF = flag.Int("pemGid", -1,
"if >= 0, group id to set in the permissions of PEM files,\n"+
"(if negative, set from umask)")
addrF = flag.String("addr", ":4357",
"address at which the HTTP server for the REST API listens\n"+
"prefix with unix@ for a Unix domain socket")
udsGidF = flag.Int("udsGid", -1,
"if >= 0 and addr denotes a Unix domain socket,\n"+
"group ID for the permissions of the socket file")
udsModeF = flag.String("udsMode", "0644",
"if addr denotes a Unix domain socket,\n"+
"permission bits for the socket file (octal)")
logFormat = logrus.TextFormatter{
DisableColors: true,
FullTimestamp: true,
}
log = &logrus.Logger{
Out: os.Stdout,
Formatter: &logFormat,
Level: logrus.InfoLevel,
}
)
func main() {
flag.Parse()
if *versionF {
fmt.Printf("%s version %s\n", os.Args[0], version)
os.Exit(0)
}
lvl := strings.ToLower(*loglvlF)
switch lvl {
case "panic":
log.Level = logrus.PanicLevel
case "fatal":
log.Level = logrus.FatalLevel
case "error":
log.Level = logrus.ErrorLevel
case "warn":
log.Level = logrus.WarnLevel
case "debug":
log.Level = logrus.DebugLevel
case "trace":
log.Level = logrus.TraceLevel
case "info":
break
default:
fmt.Printf("Unknown log level %s, exiting", *loglvlF)
os.Exit(-1)
}
log.Info("Starting Kubernetes certificate downloader version: ",
version)
log.Info("Logging at level: ", lvl)
if info, err := os.Stat(*baseF); err != nil {
log.Fatalf("Cannot stat %s: %+v", *baseF, err)
os.Exit(-1)
} else if !info.Mode().IsDir() {
log.Fatalf("%s: not a directory", *baseF)
os.Exit(-1)
} else if err := unix.Access(*baseF, unix.W_OK); err != nil {
log.Fatalf("%s not writable: %+v", *baseF, err)
os.Exit(-1)
}
udsMode := int64(0644)
if strings.HasPrefix(*addrF, "unix@") {
var err error
udsMode, err = strconv.ParseInt(*udsModeF, 8, 0)
if err != nil {
log.Fatalf("udsMode: %+v", err)
os.Exit(-1)
}
}
if *metricsPortF > math.MaxUint16 {
log.Fatalf("metricsport %d out of range (max %d)",
*metricsPortF, math.MaxUint16)
os.Exit(-1)
}
var config *k8s_rest.Config
var err error
if *masterURLF == "" && *kubeconfigF == "" {
if config, err = k8s_rest.InClusterConfig(); err != nil {
log.Fatalf("error creating in-cluster config: %v", err)
}
} else if config, err = clientcmd.BuildConfigFromFlags(*masterURLF,
*kubeconfigF); err != nil {
log.Fatalf("error creating client config from "+
"masterURL=%s and kubeconfig=%s: %v",
*masterURLF, *kubeconfigF, err)
}
kubeClient, err := kubernetes.NewForConfig(config)
if err != nil {
log.Fatal("Failed to create client: ", err)
}
watcher, err := k8s.NewWatcher(log, kubeClient, *namespaceF, *baseF,
*gidF, *resyncPeriodF)
if err != nil {
log.Fatal("Cannot start Kubernetes client: ", err)
os.Exit(-1)
}
crtGetter := watcher.GetCrtGetter()
files := watcher.GetFiles()
server := rest.NewServer(*addrF, version, *udsGidF, int(udsMode), log,
files, crtGetter)
watcher.Run(uint16(*metricsPortF))
if err = server.Start(); err != nil {
log.Fatal("Cannot start HTTP server for REST API: ", err)
}
signalChan := make(chan os.Signal, 1)
signal.Notify(signalChan, syscall.SIGTERM, syscall.SIGINT)
sig := <-signalChan
log.Infof("Received signal (%s), shutting down", sig.String())
log.Info("Shutting down the REST API")
server.Stop()
log.Info("Shutting down the Kubernetes client")
watcher.Stop()
log.Info("Exiting")
os.Exit(0)
}
......@@ -63,6 +63,7 @@ github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI=
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
github.com/imdario/mergo v0.3.5 h1:JboBksRwiiAJWvIYJVo46AfV+IAIKZpfrSzVKj42R4Q=
github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
github.com/json-iterator/go v0.0.0-20180612202835-f2b4162afba3/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.7 h1:KfgG9LzI+pYjr4xvmz/5H4FXjokeP+rlHLhv3iH62Fo=
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment