From c3c9979b61b46f0ae4df2fb8fa3bb37dfe5a5a71 Mon Sep 17 00:00:00 2001 From: darktech Date: Mon, 1 Nov 2021 08:16:06 +0200 Subject: [PATCH] injector ValidateServiceAccount --- cmd/injector/injector.go | 14 +++++++++----- cmd/rusid/sidecar.go | 7 ++++--- internal/metrics/metrics.go | 9 ++------- internal/metrics/prometheus.go | 15 ++++++++++++--- pkg/injector/config.go | 23 +++++++++++++++-------- pkg/injector/injector.go | 2 +- pkg/injector/pod_patch.go | 4 ++-- pkg/middleware/metrics.go | 4 ++-- pkg/runtime/config.go | 2 +- 9 files changed, 48 insertions(+), 32 deletions(-) diff --git a/cmd/injector/injector.go b/cmd/injector/injector.go index 3bc2c1b..a6045ae 100644 --- a/cmd/injector/injector.go +++ b/cmd/injector/injector.go @@ -14,6 +14,7 @@ func main() { //https://github.com/kubernetes/community/blob/master/contributors/devel/sig-instrumentation/logging.md klog.InitFlags(nil) kube.InitFlags(nil) + injector.BindConfigFlags(nil) flag.Parse() defer klog.Flush() @@ -25,12 +26,15 @@ func main() { ctx := context.Background() kubeClient := kube.GetKubeClient() - uids, err := injector.AllowedControllersServiceAccountUID(ctx, kubeClient) - if err != nil { - log.Fatalf("failed to get authentication uids from services accounts: %s", err) - } + var authUIDs []string - err = injector.NewInjector(uids, cfg, kubeClient).Run(ctx) + if cfg.ValidateServiceAccount { + authUIDs, err = injector.AllowedControllersServiceAccountUID(ctx, kubeClient) + if err != nil { + log.Fatalf("failed to get authentication uids from services accounts: %s", err) + } + } + err = injector.NewInjector(authUIDs, cfg, kubeClient).Run(ctx) if err != http.ErrServerClosed { klog.Fatal(err) } diff --git a/cmd/rusid/sidecar.go b/cmd/rusid/sidecar.go index 4b6cf6c..3ac0dc2 100644 --- a/cmd/rusid/sidecar.go +++ b/cmd/rusid/sidecar.go @@ -66,7 +66,7 @@ func main() { klog.InfoS("Rusid is using", "config", cfg) //Start diagnostics server - go startDiagnosticsServer(mainCtx, wg, cfg.DiagnosticsPort, cfg.EnableMetrics, + go startDiagnosticsServer(mainCtx, wg, cfg.AppID, cfg.DiagnosticsPort, cfg.EnableMetrics, // WithTimeout allows you to set a max overall timeout. healthcheck.WithTimeout(5*time.Second), healthcheck.WithChecker("component manager", compManager)) @@ -93,7 +93,7 @@ func shutdownOnInterrupt(cancel func()) { }() } -func startDiagnosticsServer(ctx context.Context, wg *sync.WaitGroup, port int, +func startDiagnosticsServer(ctx context.Context, wg *sync.WaitGroup, appId string, port int, enableMetrics bool, options ...healthcheck.Option) { wg.Add(1) defer wg.Done() @@ -102,7 +102,8 @@ func startDiagnosticsServer(ctx context.Context, wg *sync.WaitGroup, port int, router.Handle("/healthz", healthcheck.HandlerFunc(options...)) if enableMetrics { - router.Handle("/metrics", metrics.GetPrometheusMetricHandler()) + exporter := metrics.SetupPrometheusMetrics(appId) + router.HandleFunc("/metrics", exporter.ServeHTTP) } else { metrics.SetNoopMeterProvider() } diff --git a/internal/metrics/metrics.go b/internal/metrics/metrics.go index a225724..952855b 100644 --- a/internal/metrics/metrics.go +++ b/internal/metrics/metrics.go @@ -5,14 +5,13 @@ import ( "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/metric" "go.opentelemetry.io/otel/metric/global" - "os" + "sync" "time" ) type serviceMetrics struct { pubsubMeter metric.Meter - hostname string publishCount metric.Int64Counter subscribeDuration metric.Int64Histogram } @@ -22,7 +21,7 @@ var ( s *serviceMetrics ) -func DefaultMonitoring() *serviceMetrics { +func DefaultPubSubMetrics() *serviceMetrics { initOnce.Do(func() { s = newServiceMetrics() }) @@ -32,11 +31,9 @@ func DefaultMonitoring() *serviceMetrics { func newServiceMetrics() *serviceMetrics { meter := global.Meter("rusi.io/pubsub") pubsubM := metric.Must(meter) - hostname, _ := os.Hostname() return &serviceMetrics{ pubsubMeter: meter, - hostname: hostname, publishCount: pubsubM.NewInt64Counter("pubsub.publish.count", metric.WithDescription("The number of publishes")), subscribeDuration: pubsubM.NewInt64Histogram("pubsub.subscribe.duration", @@ -49,7 +46,6 @@ func (s *serviceMetrics) RecordPublishMessage(ctx context.Context, topic string, s.pubsubMeter.RecordBatch( ctx, []attribute.KeyValue{ - attribute.String("hostname", s.hostname), attribute.String("topic", topic), attribute.Bool("success", success), }, @@ -60,7 +56,6 @@ func (s *serviceMetrics) RecordSubscriberProcessingTime(ctx context.Context, top s.pubsubMeter.RecordBatch( ctx, []attribute.KeyValue{ - attribute.String("hostname", s.hostname), attribute.String("topic", topic), attribute.Bool("success", success), }, diff --git a/internal/metrics/prometheus.go b/internal/metrics/prometheus.go index e4d9066..04c8fef 100644 --- a/internal/metrics/prometheus.go +++ b/internal/metrics/prometheus.go @@ -1,6 +1,7 @@ package metrics import ( + "context" "go.opentelemetry.io/otel/exporters/prometheus" "go.opentelemetry.io/otel/metric/global" sdk_metric "go.opentelemetry.io/otel/sdk/export/metric" @@ -8,12 +9,18 @@ import ( controller "go.opentelemetry.io/otel/sdk/metric/controller/basic" processor "go.opentelemetry.io/otel/sdk/metric/processor/basic" selector "go.opentelemetry.io/otel/sdk/metric/selector/simple" + "go.opentelemetry.io/otel/sdk/resource" + semconv "go.opentelemetry.io/otel/semconv/v1.4.0" "k8s.io/klog/v2" - "net/http" + "time" ) -func GetPrometheusMetricHandler() http.HandlerFunc { +func SetupPrometheusMetrics(appId string) *prometheus.Exporter { config := prometheus.Config{} + r, _ := resource.New(context.Background(), + resource.WithHost(), + resource.WithAttributes(semconv.ServiceNameKey.String(appId))) + c := controller.New( processor.NewFactory( selector.NewWithHistogramDistribution( @@ -22,6 +29,8 @@ func GetPrometheusMetricHandler() http.HandlerFunc { sdk_metric.CumulativeExportKindSelector(), processor.WithMemory(true), ), + controller.WithResource(r), + controller.WithCollectPeriod(10*time.Second), //default - 10 sec ) exporter, err := prometheus.New(config, c) if err != nil { @@ -29,5 +38,5 @@ func GetPrometheusMetricHandler() http.HandlerFunc { return nil } global.SetMeterProvider(exporter.MeterProvider()) - return exporter.ServeHTTP + return exporter } diff --git a/pkg/injector/config.go b/pkg/injector/config.go index bf55bb4..c7e4d9e 100644 --- a/pkg/injector/config.go +++ b/pkg/injector/config.go @@ -1,9 +1,12 @@ package injector import ( + "flag" "github.com/kelseyhightower/envconfig" ) +var defaultConfig = NewConfigWithDefaults() + // Config represents configuration options for the Rusi Sidecar Injector webhook server. type Config struct { TLSCertFile string `envconfig:"TLS_CERT_FILE" required:"true"` @@ -12,6 +15,7 @@ type Config struct { SidecarImagePullPolicy string `envconfig:"SIDECAR_IMAGE_PULL_POLICY"` Namespace string `envconfig:"NAMESPACE" required:"true"` KubeClusterDomain string `envconfig:"KUBE_CLUSTER_DOMAIN"` + ValidateServiceAccount bool } // NewConfigWithDefaults returns a Config object with default values already @@ -20,17 +24,20 @@ type Config struct { func NewConfigWithDefaults() Config { return Config{ SidecarImagePullPolicy: "Always", + ValidateServiceAccount: true, } } -// GetConfig returns configuration derived from environment variables. -func GetConfig() (Config, error) { - // get config from environment variables - c := NewConfigWithDefaults() - err := envconfig.Process("", &c) - if err != nil { - return c, err +func BindConfigFlags(flagset *flag.FlagSet) { + if flagset == nil { + flagset = flag.CommandLine } - return c, nil + flagset.BoolVar(&defaultConfig.ValidateServiceAccount, "validate_service_account", defaultConfig.ValidateServiceAccount, "If true, injector will validate that rusi sidecars can only be created by a specified list of serviceAccounts") +} + +// GetConfig returns configuration derived from environment variables. +func GetConfig() (Config, error) { + err := envconfig.Process("", &defaultConfig) + return defaultConfig, err } diff --git a/pkg/injector/injector.go b/pkg/injector/injector.go index 05919d9..b0fe5ac 100644 --- a/pkg/injector/injector.go +++ b/pkg/injector/injector.go @@ -107,7 +107,7 @@ func (i *injector) handleRequest(w http.ResponseWriter, r *http.Request) { if err != nil { klog.Errorf("Can't decode body: %v", err) } else { - if !utils.StringSliceContains(ar.Request.UserInfo.UID, i.authUIDs) { + if i.config.ValidateServiceAccount && !utils.StringSliceContains(ar.Request.UserInfo.UID, i.authUIDs) { err = errors.New(fmt.Sprintf("service account '%s' not on the list of allowed controller accounts", ar.Request.UserInfo.Username)) klog.Error(err) } else if ar.Request.Kind.Kind != "Pod" { diff --git a/pkg/injector/pod_patch.go b/pkg/injector/pod_patch.go index efd4734..e1bfa02 100644 --- a/pkg/injector/pod_patch.go +++ b/pkg/injector/pod_patch.go @@ -52,7 +52,7 @@ const ( apiAddress = "rusi-api" apiPort = 80 kubernetesMountPath = "/var/run/secrets/kubernetes.io/serviceaccount" - defaultConfig = "default" + defaultConfigName = "default" defaultEnabledMetric = true defaultMetricsPort = 9090 defaultSidecarDebug = false @@ -219,7 +219,7 @@ func podContainsSidecarContainer(pod *corev1.Pod) bool { } func getConfig(annotations map[string]string) string { - return getStringAnnotationOrDefault(annotations, rusiConfigKey, defaultConfig) + return getStringAnnotationOrDefault(annotations, rusiConfigKey, defaultConfigName) } func getEnableDebug(annotations map[string]string) bool { diff --git a/pkg/middleware/metrics.go b/pkg/middleware/metrics.go index 2cae137..c6a412d 100644 --- a/pkg/middleware/metrics.go +++ b/pkg/middleware/metrics.go @@ -12,7 +12,7 @@ func SubscriberMetricsMiddleware() messaging.Middleware { return func(ctx context.Context, msg *messaging.MessageEnvelope) error { start := time.Now() err := next(ctx, msg) - metrics.DefaultMonitoring().RecordSubscriberProcessingTime(ctx, msg.Subject, err == nil, time.Since(start)) + metrics.DefaultPubSubMetrics().RecordSubscriberProcessingTime(ctx, msg.Subject, err == nil, time.Since(start)) return err } } @@ -22,7 +22,7 @@ func PublisherMetricsMiddleware() messaging.Middleware { return func(next messaging.Handler) messaging.Handler { return func(ctx context.Context, msg *messaging.MessageEnvelope) error { err := next(ctx, msg) - metrics.DefaultMonitoring().RecordPublishMessage(ctx, msg.Subject, err == nil) + metrics.DefaultPubSubMetrics().RecordPublishMessage(ctx, msg.Subject, err == nil) return err } } diff --git a/pkg/runtime/config.go b/pkg/runtime/config.go index c2d94a4..193fd35 100644 --- a/pkg/runtime/config.go +++ b/pkg/runtime/config.go @@ -11,7 +11,7 @@ import ( const ( defaultGRPCPort = 50003 defaultDiagnosticsPort = 8080 - defaultEnableMetrics = false + defaultEnableMetrics = true ) type ConfigBuilder struct {