diff --git a/kubernetes/wait.go b/kubernetes/wait.go index 615a054..76f01cd 100644 --- a/kubernetes/wait.go +++ b/kubernetes/wait.go @@ -5,6 +5,10 @@ package kubernetes import ( "context" + "fmt" + "io" + "log/slog" + "strings" "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/dynamic" @@ -37,7 +41,10 @@ func WatcherForConfig(cfg *rest.Config) (watcher.StatusWatcher, error) { } // WaitForReadyRuntime waits for all of the runtime objects to reach a ready state. -func WaitForReadyRuntime(ctx context.Context, sw watcher.StatusWatcher, robjs []runtime.Object) error { +func WaitForReadyRuntime(ctx context.Context, sw watcher.StatusWatcher, robjs []runtime.Object, logger *slog.Logger) error { + if logger == nil { + logger = slog.New(slog.NewTextHandler(io.Discard, &slog.HandlerOptions{})) + } objs := []object.ObjMetadata{} for _, robj := range robjs { obj, err := object.RuntimeToObjMeta(robj) @@ -46,11 +53,14 @@ func WaitForReadyRuntime(ctx context.Context, sw watcher.StatusWatcher, robjs [] } objs = append(objs, obj) } - return WaitForReady(ctx, sw, objs) + return WaitForReady(ctx, sw, objs, logger) } // WaitForReady waits for all of the objects to reach a ready state. -func WaitForReady(ctx context.Context, sw watcher.StatusWatcher, objs []object.ObjMetadata) error { +func WaitForReady(ctx context.Context, sw watcher.StatusWatcher, objs []object.ObjMetadata, logger *slog.Logger) error { + if logger == nil { + logger = slog.New(slog.NewTextHandler(io.Discard, &slog.HandlerOptions{})) + } cancelCtx, cancel := context.WithCancel(ctx) defer cancel() @@ -73,17 +83,31 @@ func WaitForReady(ctx context.Context, sw watcher.StatusWatcher, objs []object.O }), ) <-done + + for _, id := range objs { + rs := statusCollector.ResourceStatuses[id] + switch rs.Status { + // TODO (@austinabro321) once callers have proper sloggers change logging here to use the slog style + case status.CurrentStatus: + logger.Debug(fmt.Sprintf("%s: %s ready", rs.Identifier.Name, strings.ToLower(rs.Identifier.GroupKind.Kind))) + case status.NotFoundStatus: + logger.Error(fmt.Sprintf("%s: %s not found", rs.Identifier.Name, strings.ToLower(rs.Identifier.GroupKind.Kind))) + default: + logger.Error(fmt.Sprintf("%s: %s not ready", rs.Identifier.Name, strings.ToLower(rs.Identifier.GroupKind.Kind))) + } + } + if statusCollector.Error != nil { return statusCollector.Error } - // Only check parent context error, otherwise we would error when desired status is acheived. + // Only check parent context error, otherwise we would error when desired status is achieved. if ctx.Err() != nil { return ctx.Err() } return nil } -// ImmediateWatcher should only be used for testing and returns the set status immediatly. +// ImmediateWatcher should only be used for testing and returns the set status immediately. type ImmediateWatcher struct { status status.Status } diff --git a/kubernetes/wait_test.go b/kubernetes/wait_test.go index dece27b..c5392a2 100644 --- a/kubernetes/wait_test.go +++ b/kubernetes/wait_test.go @@ -4,7 +4,9 @@ package kubernetes import ( + "bytes" "context" + "log/slog" "testing" "github.com/stretchr/testify/require" @@ -15,6 +17,8 @@ import ( ) func TestWaitForReady(t *testing.T) { + var buf bytes.Buffer + logger := slog.New(slog.NewTextHandler(&buf, &slog.HandlerOptions{Level: slog.LevelDebug})) sw := NewImmediateWatcher(status.CurrentStatus) objs := []object.ObjMetadata{ { @@ -26,11 +30,15 @@ func TestWaitForReady(t *testing.T) { Name: "bar", }, } - err := WaitForReady(context.Background(), sw, objs) + err := WaitForReady(context.Background(), sw, objs, logger) require.NoError(t, err) + logOutput := buf.String() + require.Contains(t, logOutput, "bar: deployment ready") } func TestWaitForReadyCanceled(t *testing.T) { + var buf bytes.Buffer + logger := slog.New(slog.NewTextHandler(&buf, &slog.HandlerOptions{Level: slog.LevelDebug})) ctx, cancel := context.WithCancel(context.Background()) cancel() sw := watcher.BlindStatusWatcher{} @@ -44,6 +52,8 @@ func TestWaitForReadyCanceled(t *testing.T) { Name: "bar", }, } - err := WaitForReady(ctx, sw, objs) + err := WaitForReady(ctx, sw, objs, logger) require.EqualError(t, err, "context canceled") + logOutput := buf.String() + require.Contains(t, logOutput, "bar: deployment not ready") }