Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove direct zap dependecy in operator and kube-agent-updater #50960

Merged
merged 3 commits into from
Jan 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,6 @@ require (
go.opentelemetry.io/otel/sdk v1.33.0
go.opentelemetry.io/otel/trace v1.33.0
go.opentelemetry.io/proto/otlp v1.5.0
go.uber.org/zap v1.27.0
golang.org/x/crypto v0.32.0
golang.org/x/exp v0.0.0-20250106191152-7588d65b2ba8
golang.org/x/mod v0.22.0
Expand Down Expand Up @@ -347,7 +346,6 @@ require (
github.com/go-gorp/gorp/v3 v3.1.0 // indirect
github.com/go-jose/go-jose/v4 v4.0.4 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-logr/zapr v1.3.0 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-openapi/analysis v0.23.0 // indirect
github.com/go-openapi/errors v0.22.0 // indirect
Expand Down Expand Up @@ -543,6 +541,7 @@ require (
go.uber.org/atomic v1.11.0 // indirect
go.uber.org/mock v0.4.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
golang.org/x/tools v0.29.0 // indirect
golang.org/x/xerrors v0.0.0-20240716161551-93cc26a95ae9 // indirect
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,14 @@ package main
import (
"flag"
"fmt"
"log/slog"
"net/url"
"os"
"strings"
"time"

"github.com/distribution/reference"
"github.com/go-logr/logr"
"github.com/gravitational/trace"
appsv1 "k8s.io/api/apps/v1"
v1 "k8s.io/api/core/v1"
Expand All @@ -37,7 +39,6 @@ import (
"sigs.k8s.io/controller-runtime/pkg/cache"
kclient "sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/healthz"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"

kubeversionupdater "github.com/gravitational/teleport/integrations/kube-agent-updater"
Expand All @@ -46,6 +47,7 @@ import (
podmaintenance "github.com/gravitational/teleport/integrations/kube-agent-updater/pkg/maintenance"
"github.com/gravitational/teleport/lib/automaticupgrades/maintenance"
"github.com/gravitational/teleport/lib/automaticupgrades/version"
logutils "github.com/gravitational/teleport/lib/utils/log"
)

var (
Expand All @@ -57,9 +59,25 @@ func init() {
utilruntime.Must(v1.AddToScheme(scheme))
}

var extraFields = []string{logutils.LevelField, logutils.ComponentField, logutils.TimestampField}

func main() {
ctx := ctrl.SetupSignalHandler()

// Setup early logger, using INFO level by default.
slogLogger, slogLeveler, err := logutils.Initialize(logutils.Config{
Severity: slog.LevelInfo.String(),
Format: "json",
ExtraFields: extraFields,
})
if err != nil {
fmt.Fprintf(os.Stderr, "failed to initialize logs: %v\n", err)
os.Exit(1)
}

logger := logr.FromSlogHandler(slogLogger.Handler())
ctrl.SetLogger(logger)

var agentName string
var agentNamespace string
var metricsAddr string
Expand All @@ -72,6 +90,7 @@ func main() {
var insecureNoResolve bool
var disableLeaderElection bool
var credSource string
var logLevel string

flag.StringVar(&agentName, "agent-name", "", "The name of the agent that should be updated. This is mandatory.")
flag.StringVar(&agentNamespace, "agent-namespace", "", "The namespace of the agent that should be updated. This is mandatory.")
Expand All @@ -89,14 +108,16 @@ func main() {
img.DockerCredentialSource, img.GoogleCredentialSource, img.AmazonCredentialSource, img.NoCredentialSource,
),
)

opts := zap.Options{
Development: false,
}
opts.BindFlags(flag.CommandLine)
flag.StringVar(&logLevel, "log-level", "INFO", "Log level (DEBUG, INFO, WARN, ERROR).")
flag.Parse()

ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts)))
// Now that we parsed the flags, we can tune the log level.
var lvl slog.Level
if err := (&lvl).UnmarshalText([]byte(logLevel)); err != nil {
ctrl.Log.Error(err, "Failed to parse log level", "level", logLevel)
os.Exit(1)
}
slogLeveler.Set(lvl)

if agentName == "" {
ctrl.Log.Error(trace.BadParameter("--agent-name empty"), "agent-name must be provided")
Expand Down
11 changes: 8 additions & 3 deletions integrations/lib/embeddedtbot/bot.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import (

// EmbeddedBot is an embedded tBot instance to renew the operator certificates.
type EmbeddedBot struct {
log *slog.Logger
cfg *config.BotConfig

credential *config.UnstableClientCredentialOutput
Expand All @@ -48,7 +49,10 @@ type EmbeddedBot struct {
}

// New creates a new EmbeddedBot from a BotConfig.
func New(botConfig *BotConfig) (*EmbeddedBot, error) {
func New(botConfig *BotConfig, log *slog.Logger) (*EmbeddedBot, error) {
if log == nil {
return nil, trace.BadParameter("missing log")
}
credential := &config.UnstableClientCredentialOutput{}

cfg := (*config.BotConfig)(botConfig)
Expand All @@ -63,6 +67,7 @@ func New(botConfig *BotConfig) (*EmbeddedBot, error) {
bot := &EmbeddedBot{
cfg: cfg,
credential: credential,
log: log,
}

return bot, nil
Expand All @@ -74,7 +79,7 @@ func New(botConfig *BotConfig) (*EmbeddedBot, error) {
// It allows us to fail fast and validate if something is broken before starting the manager.
func (b *EmbeddedBot) Preflight(ctx context.Context) (*proto.PingResponse, error) {
b.cfg.Oneshot = true
bot := tbot.New(b.cfg, slog.Default())
bot := tbot.New(b.cfg, b.log)
err := bot.Run(ctx)
if err != nil {
return nil, trace.Wrap(err)
Expand All @@ -96,7 +101,7 @@ func (b *EmbeddedBot) start(ctx context.Context) {
b.mutex.Lock()
defer b.mutex.Unlock()
b.cfg.Oneshot = false
bot := tbot.New(b.cfg, slog.Default())
bot := tbot.New(b.cfg, b.log)

botCtx, cancel := context.WithCancel(ctx)
b.cancelCtx = cancel
Expand Down
5 changes: 3 additions & 2 deletions integrations/lib/embeddedtbot/bot_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,12 @@ func TestBotJoinAuth(t *testing.T) {
// Configure and start Teleport server
clusterName := "root.example.com"
ctx := context.Background()
logger := utils.NewSlogLoggerForTests()
teleportServer := helpers.NewInstance(t, helpers.InstanceConfig{
ClusterName: clusterName,
HostID: uuid.New().String(),
NodeName: helpers.Loopback,
Logger: utils.NewSlogLoggerForTests(),
Logger: logger,
})

rcConf := servicecfg.MakeDefaultConfig()
Expand Down Expand Up @@ -128,7 +129,7 @@ func TestBotJoinAuth(t *testing.T) {
Oneshot: true,
Debug: true,
}
bot, err := New(botConfig)
bot, err := New(botConfig, logger)
require.NoError(t, err)
pong, err := bot.Preflight(ctx)
require.NoError(t, err)
Expand Down
2 changes: 2 additions & 0 deletions integrations/operator/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ type operatorConfig struct {
leaderElectionID string
syncPeriod time.Duration
namespace string
logLevel string
}

// BindFlags binds operatorConfig fields to CLI flags.
Expand All @@ -50,6 +51,7 @@ func (c *operatorConfig) BindFlags(fs *flag.FlagSet) {
fs.StringVar(&c.leaderElectionID, "leader-election-id", "431e83f4.teleport.dev", "Leader Election Id to use.")
fs.StringVar(&c.namespace, "namespace", "", "The namespace containing the Teleport CRs.")
fs.DurationVar(&c.syncPeriod, "sync-period", defaultSyncPeriod, "Operator sync period (format: https://pkg.go.dev/time#ParseDuration)")
fs.StringVar(&c.logLevel, "log-level", "INFO", "Log level (DEBUG, INFO, WARN, ERROR).")
}

// CheckAndSetDefaults checks the operatorConfig and populates unspecified
Expand Down
15 changes: 11 additions & 4 deletions integrations/operator/controllers/resources/testlib/env.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,10 @@ import (
"testing"
"time"

"github.com/go-logr/logr"
"github.com/google/uuid"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.uber.org/zap/zapcore"
core "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
Expand All @@ -42,7 +42,6 @@ import (
kclient "sigs.k8s.io/controller-runtime/pkg/client"
ctrlconfig "sigs.k8s.io/controller-runtime/pkg/config"
"sigs.k8s.io/controller-runtime/pkg/envtest"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
"sigs.k8s.io/controller-runtime/pkg/manager"
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"

Expand All @@ -58,6 +57,7 @@ import (
"github.com/gravitational/teleport/integrations/operator/controllers/resources"
"github.com/gravitational/teleport/lib/modules"
"github.com/gravitational/teleport/lib/service/servicecfg"
"github.com/gravitational/teleport/lib/utils"
)

// scheme is our own test-specific scheme to avoid using the global
Expand Down Expand Up @@ -185,6 +185,7 @@ type TestSetup struct {
OperatorCancel context.CancelFunc
OperatorName string
stepByStepReconciliation bool
log *slog.Logger
}

// StartKubernetesOperator creates and start a new operator
Expand All @@ -206,8 +207,14 @@ func (s *TestSetup) StartKubernetesOperator(t *testing.T) {
})
require.NoError(t, err)

setupLog := ctrl.Log.WithName("setup")
ctrl.SetLogger(zap.New(zap.UseDevMode(true), zap.Level(zapcore.DebugLevel)))
slogLogger := s.log
if slogLogger == nil {
slogLogger = utils.NewSlogLoggerForTests()
}

logger := logr.FromSlogHandler(slogLogger.Handler())
ctrl.SetLogger(logger)
setupLog := logger.WithName("setup")

pong, err := s.TeleportClient.Ping(context.Background())
require.NoError(t, err)
Expand Down
42 changes: 32 additions & 10 deletions integrations/operator/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,51 +21,73 @@ package main

import (
"flag"
"fmt"
"log/slog"
"os"
"time"

"github.com/go-logr/logr"
// Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.)
// to ensure that exec-entrypoint and run can make use of them.
_ "k8s.io/client-go/plugin/pkg/client/auth"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/cache"
ctrlclient "sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/healthz"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"

"github.com/gravitational/teleport"
"github.com/gravitational/teleport/integrations/lib/embeddedtbot"
"github.com/gravitational/teleport/integrations/operator/controllers"
"github.com/gravitational/teleport/integrations/operator/controllers/resources"
logutils "github.com/gravitational/teleport/lib/utils/log"
)

var (
scheme = controllers.Scheme
setupLog = ctrl.Log.WithName("setup")
scheme = controllers.Scheme
)

var extraFields = []string{logutils.LevelField, logutils.ComponentField, logutils.TimestampField}

func main() {
ctx := ctrl.SetupSignalHandler()

// Setup early logger, using INFO level by default.
slogLogger, slogLeveler, err := logutils.Initialize(logutils.Config{
Severity: slog.LevelInfo.String(),
Format: "json",
ExtraFields: extraFields,
})
if err != nil {
fmt.Fprintf(os.Stderr, "failed to initialize logs: %v\n", err)
os.Exit(1)
}

logger := logr.FromSlogHandler(slogLogger.Handler())
ctrl.SetLogger(logger)
setupLog := logger.WithName("setup")

config := &operatorConfig{}
config.BindFlags(flag.CommandLine)
opts := zap.Options{
Development: true,
}
opts.BindFlags(flag.CommandLine)
botConfig := &embeddedtbot.BotConfig{}
botConfig.BindFlags(flag.CommandLine)
flag.Parse()

ctrl.SetLogger(zap.New(zap.UseFlagOptions(&opts)))
// Now that we parsed the flags, we can tune the log level.
var logLevel slog.Level
if err := (&logLevel).UnmarshalText([]byte(config.logLevel)); err != nil {
setupLog.Error(err, "Failed to parse log level", "level", config.logLevel)
os.Exit(1)
}
slogLeveler.Set(logLevel)

err := config.CheckAndSetDefaults()
err = config.CheckAndSetDefaults()
if err != nil {
setupLog.Error(err, "invalid configuration")
os.Exit(1)
}

bot, err := embeddedtbot.New(botConfig)
bot, err := embeddedtbot.New(botConfig, slogLogger.With(teleport.ComponentLabel, "embedded-tbot"))
if err != nil {
setupLog.Error(err, "unable to build tbot")
os.Exit(1)
Expand Down
4 changes: 3 additions & 1 deletion integrations/terraform/provider/credentials.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"context"
"encoding/base64"
"fmt"
"log/slog"
"strings"
"text/template"
"time"
Expand Down Expand Up @@ -524,7 +525,8 @@ See https://goteleport.com/docs/reference/join-methods for more details.`)
CertificateTTL: time.Hour,
RenewalInterval: 20 * time.Minute,
}
bot, err := embeddedtbot.New(botConfig)
// slog default logger has been configured during the provider init.
bot, err := embeddedtbot.New(botConfig, slog.Default())
if err != nil {
return nil, trace.Wrap(err, "Failed to create bot configuration, this is a provider bug, please open a GitHub issue.")
}
Expand Down
Loading