ref(cmd/tiller): delete main tiller package

pull/3945/head
Adam Reese 7 years ago
parent dbf1ed0ba4
commit 61a9003a97
No known key found for this signature in database
GPG Key ID: 06F35E60A7A18DD6

@ -1,43 +0,0 @@
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main
import (
"net/http"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
func readinessProbe(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
}
func livenessProbe(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
}
func newProbesMux() *http.ServeMux {
mux := http.NewServeMux()
mux.HandleFunc("/readiness", readinessProbe)
mux.HandleFunc("/liveness", livenessProbe)
return mux
}
func addPrometheusHandler(mux *http.ServeMux) {
// Register HTTP handler for the global Prometheus registry.
mux.Handle("/metrics", promhttp.Handler())
}

@ -1,58 +0,0 @@
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main
import (
"net/http"
"net/http/httptest"
"testing"
)
func TestProbesServer(t *testing.T) {
mux := newProbesMux()
srv := httptest.NewServer(mux)
defer srv.Close()
resp, err := http.Get(srv.URL + "/readiness")
if err != nil {
t.Fatalf("GET /readiness returned an error (%s)", err)
}
if resp.StatusCode != http.StatusOK {
t.Fatalf("GET /readiness returned status code %d, expected %d", resp.StatusCode, http.StatusOK)
}
resp, err = http.Get(srv.URL + "/liveness")
if err != nil {
t.Fatalf("GET /liveness returned an error (%s)", err)
}
if resp.StatusCode != http.StatusOK {
t.Fatalf("GET /liveness returned status code %d, expected %d", resp.StatusCode, http.StatusOK)
}
}
func TestPrometheus(t *testing.T) {
mux := http.NewServeMux()
addPrometheusHandler(mux)
srv := httptest.NewServer(mux)
defer srv.Close()
resp, err := http.Get(srv.URL + "/metrics")
if err != nil {
t.Fatalf("GET /metrics returned an error (%s)", err)
}
if resp.StatusCode != http.StatusOK {
t.Fatalf("GET /metrics returned status code %d, expected %d", resp.StatusCode, http.StatusOK)
}
}

@ -1,288 +0,0 @@
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main // import "k8s.io/helm/cmd/tiller"
import (
"crypto/tls"
"flag"
"fmt"
"io/ioutil"
"log"
"net"
"net/http"
"os"
"path/filepath"
"strconv"
"strings"
"time"
goprom "github.com/grpc-ecosystem/go-grpc-prometheus"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/health"
healthpb "google.golang.org/grpc/health/grpc_health_v1"
"google.golang.org/grpc/keepalive"
"k8s.io/helm/pkg/kube"
"k8s.io/helm/pkg/proto/hapi/services"
"k8s.io/helm/pkg/storage"
"k8s.io/helm/pkg/storage/driver"
"k8s.io/helm/pkg/tiller"
"k8s.io/helm/pkg/tiller/environment"
"k8s.io/helm/pkg/tlsutil"
"k8s.io/helm/pkg/version"
)
const (
// tlsEnableEnvVar names the environment variable that enables TLS.
tlsEnableEnvVar = "TILLER_TLS_ENABLE"
// tlsVerifyEnvVar names the environment variable that enables
// TLS, as well as certificate verification of the remote.
tlsVerifyEnvVar = "TILLER_TLS_VERIFY"
// tlsCertsEnvVar names the environment variable that points to
// the directory where Tiller's TLS certificates are located.
tlsCertsEnvVar = "TILLER_TLS_CERTS"
// historyMaxEnvVar is the name of the env var for setting max history.
historyMaxEnvVar = "TILLER_HISTORY_MAX"
storageMemory = "memory"
storageConfigMap = "configmap"
storageSecret = "secret"
probeAddr = ":44135"
traceAddr = ":44136"
// defaultMaxHistory sets the maximum number of releases to 0: unlimited
defaultMaxHistory = 0
)
var (
grpcAddr = flag.String("listen", ":44134", "address:port to listen on")
enableTracing = flag.Bool("trace", false, "enable rpc tracing")
store = flag.String("storage", storageConfigMap, "storage driver to use. One of 'configmap', 'memory', or 'secret'")
remoteReleaseModules = flag.Bool("experimental-release", false, "enable experimental release modules")
tlsEnable = flag.Bool("tls", tlsEnableEnvVarDefault(), "enable TLS")
tlsVerify = flag.Bool("tls-verify", tlsVerifyEnvVarDefault(), "enable TLS and verify remote certificate")
keyFile = flag.String("tls-key", tlsDefaultsFromEnv("tls-key"), "path to TLS private key file")
certFile = flag.String("tls-cert", tlsDefaultsFromEnv("tls-cert"), "path to TLS certificate file")
caCertFile = flag.String("tls-ca-cert", tlsDefaultsFromEnv("tls-ca-cert"), "trust certificates signed by this CA")
maxHistory = flag.Int("history-max", historyMaxFromEnv(), "maximum number of releases kept in release history, with 0 meaning no limit")
printVersion = flag.Bool("version", false, "print the version number")
// rootServer is the root gRPC server.
//
// Each gRPC service registers itself to this server during init().
rootServer *grpc.Server
// env is the default environment.
//
// Any changes to env should be done before rootServer.Serve() is called.
env = environment.New()
logger *log.Logger
)
func main() {
// TODO: use spf13/cobra for tiller instead of flags
flag.Parse()
if *printVersion {
fmt.Println(version.GetVersion())
os.Exit(0)
}
if *enableTracing {
log.SetFlags(log.Lshortfile)
}
logger = newLogger("main")
start()
}
func start() {
healthSrv := health.NewServer()
healthSrv.SetServingStatus("Tiller", healthpb.HealthCheckResponse_NOT_SERVING)
clientset, err := kube.New(nil).ClientSet()
if err != nil {
logger.Fatalf("Cannot initialize Kubernetes connection: %s", err)
}
switch *store {
case storageMemory:
env.Releases = storage.Init(driver.NewMemory())
case storageConfigMap:
cfgmaps := driver.NewConfigMaps(clientset.Core().ConfigMaps(namespace()))
cfgmaps.Log = newLogger("storage/driver").Printf
env.Releases = storage.Init(cfgmaps)
env.Releases.Log = newLogger("storage").Printf
case storageSecret:
secrets := driver.NewSecrets(clientset.Core().Secrets(namespace()))
secrets.Log = newLogger("storage/driver").Printf
env.Releases = storage.Init(secrets)
env.Releases.Log = newLogger("storage").Printf
}
if *maxHistory > 0 {
env.Releases.MaxHistory = *maxHistory
}
kubeClient := kube.New(nil)
kubeClient.Log = newLogger("kube").Printf
env.KubeClient = kubeClient
if *tlsEnable || *tlsVerify {
opts := tlsutil.Options{CertFile: *certFile, KeyFile: *keyFile}
if *tlsVerify {
opts.CaCertFile = *caCertFile
}
}
var opts []grpc.ServerOption
if *tlsEnable || *tlsVerify {
cfg, err := tlsutil.ServerConfig(tlsOptions())
if err != nil {
logger.Fatalf("Could not create server TLS configuration: %v", err)
}
opts = append(opts, grpc.Creds(credentials.NewTLS(cfg)))
}
opts = append(opts, grpc.KeepaliveParams(keepalive.ServerParameters{
MaxConnectionIdle: 10 * time.Minute,
// If needed, we can configure the max connection age
}))
opts = append(opts, grpc.KeepaliveEnforcementPolicy(keepalive.EnforcementPolicy{
MinTime: time.Duration(20) * time.Second, // For compatibility with the client keepalive.ClientParameters
}))
rootServer = tiller.NewServer(opts...)
healthpb.RegisterHealthServer(rootServer, healthSrv)
lstn, err := net.Listen("tcp", *grpcAddr)
if err != nil {
logger.Fatalf("Server died: %s", err)
}
logger.Printf("Starting Tiller %s (tls=%t)", version.GetVersion(), *tlsEnable || *tlsVerify)
logger.Printf("GRPC listening on %s", *grpcAddr)
logger.Printf("Probes listening on %s", probeAddr)
logger.Printf("Storage driver is %s", env.Releases.Name())
logger.Printf("Max history per release is %d", *maxHistory)
if *enableTracing {
startTracing(traceAddr)
}
srvErrCh := make(chan error)
probeErrCh := make(chan error)
go func() {
svc := tiller.NewReleaseServer(env, clientset, *remoteReleaseModules)
svc.Log = newLogger("tiller").Printf
services.RegisterReleaseServiceServer(rootServer, svc)
if err := rootServer.Serve(lstn); err != nil {
srvErrCh <- err
}
}()
go func() {
mux := newProbesMux()
// Register gRPC server to prometheus to initialized matrix
goprom.Register(rootServer)
addPrometheusHandler(mux)
if err := http.ListenAndServe(probeAddr, mux); err != nil {
probeErrCh <- err
}
}()
healthSrv.SetServingStatus("Tiller", healthpb.HealthCheckResponse_SERVING)
select {
case err := <-srvErrCh:
logger.Fatalf("Server died: %s", err)
case err := <-probeErrCh:
logger.Printf("Probes server died: %s", err)
}
}
func newLogger(prefix string) *log.Logger {
if len(prefix) > 0 {
prefix = fmt.Sprintf("[%s] ", prefix)
}
return log.New(os.Stderr, prefix, log.Flags())
}
// namespace returns the namespace of tiller
func namespace() string {
if ns := os.Getenv("TILLER_NAMESPACE"); ns != "" {
return ns
}
// Fall back to the namespace associated with the service account token, if available
if data, err := ioutil.ReadFile("/var/run/secrets/kubernetes.io/serviceaccount/namespace"); err == nil {
if ns := strings.TrimSpace(string(data)); len(ns) > 0 {
return ns
}
}
return environment.DefaultTillerNamespace
}
func tlsOptions() tlsutil.Options {
opts := tlsutil.Options{CertFile: *certFile, KeyFile: *keyFile}
if *tlsVerify {
opts.CaCertFile = *caCertFile
// We want to force the client to not only provide a cert, but to
// provide a cert that we can validate.
// http://www.bite-code.com/2015/06/25/tls-mutual-auth-in-golang/
opts.ClientAuth = tls.RequireAndVerifyClientCert
}
return opts
}
func tlsDefaultsFromEnv(name string) (value string) {
switch certsDir := os.Getenv(tlsCertsEnvVar); name {
case "tls-key":
return filepath.Join(certsDir, "tls.key")
case "tls-cert":
return filepath.Join(certsDir, "tls.crt")
case "tls-ca-cert":
return filepath.Join(certsDir, "ca.crt")
}
return ""
}
func historyMaxFromEnv() int {
val := os.Getenv(historyMaxEnvVar)
if val == "" {
return defaultMaxHistory
}
ret, err := strconv.Atoi(val)
if err != nil {
log.Printf("Invalid max history %q. Defaulting to 0.", val)
return defaultMaxHistory
}
return ret
}
func tlsEnableEnvVarDefault() bool { return os.Getenv(tlsEnableEnvVar) != "" }
func tlsVerifyEnvVarDefault() bool { return os.Getenv(tlsVerifyEnvVar) != "" }

@ -1,47 +0,0 @@
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main
import (
"testing"
"k8s.io/helm/pkg/engine"
"k8s.io/helm/pkg/tiller/environment"
)
// These are canary tests to make sure that the default server actually
// fulfills its requirements.
var _ environment.Engine = &engine.Engine{}
func TestInit(t *testing.T) {
defer func() {
if recover() != nil {
t.Fatalf("Panic trapped. Check EngineYard.Default()")
}
}()
// This will panic if it is not correct.
env.EngineYard.Default()
e, ok := env.EngineYard.Get(environment.GoTplEngine)
if !ok {
t.Fatalf("Could not find GoTplEngine")
}
if e == nil {
t.Fatalf("Template engine GoTplEngine returned nil.")
}
}

@ -1,58 +0,0 @@
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main // import "k8s.io/helm/cmd/tiller"
import (
"net/http"
_ "net/http/pprof"
"google.golang.org/grpc"
)
func startTracing(addr string) {
logger.Printf("Tracing server is listening on %s\n", addr)
grpc.EnableTracing = true
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/" {
http.NotFound(w, r)
return
}
w.Header().Set("Content-Type", "text/html; charset=utf-8")
w.Write([]byte(traceIndexHTML))
})
go func() {
if err := http.ListenAndServe(addr, nil); err != nil {
logger.Printf("tracing error: %s", err)
}
}()
}
const traceIndexHTML = `<!DOCTYPE html>
<html>
<body>
<ul>
<li><a href="/debug/requests">requests</a></li>
<li><a href="/debug/events">events</a></li>
<li><a href="/debug/pprof">pprof</a></li>
<li><a href="/debug/vars">vars</a></li>
</ul>
</body>
</html>
`
Loading…
Cancel
Save