Skip to content

Commit 601325a

Browse files
committed
Added K8s warnings capture for select operations. Resolves #647
Signed-off-by: Chris White <chriswhite199@gmail.com>
1 parent 76f2cd3 commit 601325a

File tree

16 files changed

+458
-4
lines changed

16 files changed

+458
-4
lines changed

pkg/engine/clusters/cluster.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,26 @@ package clusters
33
import (
44
"sync"
55

6+
"github.com/kyverno/chainsaw/pkg/model"
67
restutils "github.com/kyverno/chainsaw/pkg/utils/rest"
78
"k8s.io/client-go/rest"
89
"k8s.io/client-go/tools/clientcmd"
910
)
1011

1112
type Cluster interface {
1213
Config() (*rest.Config, error)
14+
model.WarningsHolder
1315
}
1416

1517
type fromConfig struct {
1618
config *rest.Config
19+
*model.WithWarnings
1720
}
1821

1922
func NewClusterFromConfig(config *rest.Config) Cluster {
2023
return &fromConfig{
21-
config: config,
24+
config: config,
25+
WithWarnings: model.NewWithWarnings(),
2226
}
2327
}
2428

@@ -28,6 +32,7 @@ func (c *fromConfig) Config() (*rest.Config, error) {
2832

2933
type fromKubeconfig struct {
3034
resolver func() (*rest.Config, error)
35+
*model.WithWarnings
3136
}
3237

3338
func NewClusterFromKubeconfig(kubeconfig string, context string) Cluster {
@@ -37,7 +42,8 @@ func NewClusterFromKubeconfig(kubeconfig string, context string) Cluster {
3742
})
3843
})
3944
return &fromKubeconfig{
40-
resolver: resolver,
45+
resolver: resolver,
46+
WithWarnings: model.NewWithWarnings(),
4147
}
4248
}
4349

pkg/engine/clusters/cluster_test.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package clusters
33
import (
44
"testing"
55

6+
"github.com/kyverno/chainsaw/pkg/model"
67
"github.com/stretchr/testify/assert"
78
"k8s.io/client-go/rest"
89
)
@@ -15,13 +16,15 @@ func TestNewClusterFromConfig(t *testing.T) {
1516
}{{
1617
name: "nil",
1718
want: &fromConfig{
18-
config: nil,
19+
config: nil,
20+
WithWarnings: model.NewWithWarnings(),
1921
},
2022
}, {
2123
name: "nil",
2224
config: &rest.Config{},
2325
want: &fromConfig{
24-
config: &rest.Config{},
26+
config: &rest.Config{},
27+
WithWarnings: model.NewWithWarnings(),
2528
},
2629
}}
2730
for _, tt := range tests {

pkg/engine/clusters/registry.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ func defaultClientFactory(cluster Cluster) (*rest.Config, client.Client, error)
2525
if err != nil {
2626
return nil, nil, err
2727
}
28+
config.WarningHandler = cluster
2829
client, err := simple.New(config)
2930
if err != nil {
3031
return nil, nil, err

pkg/engine/operations/apply/operation.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@ func (o *operation) tryApplyResource(ctx context.Context, tc apis.Bindings, obj
100100
var actual unstructured.Unstructured
101101
actual.SetGroupVersionKind(obj.GetObjectKind().GroupVersionKind())
102102
err := o.client.Get(ctx, client.Key(&obj), &actual)
103+
operations.ResetWarnings(ctx)
103104
if err == nil {
104105
return o.updateResource(ctx, tc, &actual, obj)
105106
}
@@ -135,6 +136,7 @@ func (o *operation) handleCheck(ctx context.Context, tc apis.Bindings, obj unstr
135136
} else {
136137
tc = bindings.RegisterBinding(tc, "error", err.Error())
137138
}
139+
tc = operations.RegisterWarningsInBindings(ctx, tc)
138140
defer func(tc apis.Bindings) {
139141
if _err == nil {
140142
outputs, err := outputs.Process(ctx, o.compilers, tc, obj.UnstructuredContent(), o.outputs...)

pkg/engine/operations/create/operation.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ func (o *operation) tryCreateResource(ctx context.Context, bindings apis.Binding
104104
return nil, errors.New("the resource already exists in the cluster")
105105
}
106106
if kerrors.IsNotFound(err) {
107+
operations.ResetWarnings(ctx)
107108
return o.createResource(ctx, bindings, obj)
108109
}
109110
return nil, err
@@ -123,6 +124,7 @@ func (o *operation) handleCheck(ctx context.Context, bindings apis.Bindings, obj
123124
} else {
124125
bindings = apibindings.RegisterBinding(bindings, "error", err.Error())
125126
}
127+
bindings = operations.RegisterWarningsInBindings(ctx, bindings)
126128
defer func(bindings apis.Bindings) {
127129
if _err == nil {
128130
outputs, err := outputs.Process(ctx, o.compilers, bindings, obj.UnstructuredContent(), o.outputs...)

pkg/engine/operations/delete/operation.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ func (o *operation) getResourcesToDelete(ctx context.Context, obj unstructured.U
9797
func (o *operation) deleteResources(ctx context.Context, bindings apis.Bindings, resources ...unstructured.Unstructured) error {
9898
var errs []error
9999
var deleted []unstructured.Unstructured
100+
operations.ResetWarnings(ctx)
100101
for _, resource := range resources {
101102
err := o.deleteResource(ctx, resource)
102103
// if the resource was successfully deleted, record it to track actual deletion
@@ -148,6 +149,7 @@ func (o *operation) handleCheck(ctx context.Context, bindings apis.Bindings, res
148149
} else {
149150
bindings = apibindings.RegisterBinding(bindings, "error", err.Error())
150151
}
152+
bindings = operations.RegisterWarningsInBindings(ctx, bindings)
151153
if matched, err := checks.Expect(ctx, o.compilers, resource, bindings, o.expect...); matched {
152154
return err
153155
}

pkg/engine/operations/patch/operation.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ func (o *operation) tryPatchResource(ctx context.Context, bindings apis.Bindings
9898
if err != nil {
9999
return nil, err
100100
}
101+
operations.ResetWarnings(ctx)
101102
return o.updateResource(ctx, bindings, &actual, obj)
102103
}
103104

@@ -119,6 +120,7 @@ func (o *operation) handleCheck(ctx context.Context, bindings apis.Bindings, obj
119120
} else {
120121
bindings = apibindings.RegisterBinding(bindings, "error", err.Error())
121122
}
123+
bindings = operations.RegisterWarningsInBindings(ctx, bindings)
122124
defer func(bindings apis.Bindings) {
123125
if _err == nil {
124126
outputs, err := outputs.Process(ctx, o.compilers, bindings, obj.UnstructuredContent(), o.outputs...)

pkg/engine/operations/update/operation.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ func (o *operation) tryUpdateResource(ctx context.Context, bindings apis.Binding
102102
}
103103
return nil, err
104104
}
105+
operations.ResetWarnings(ctx)
105106
obj.SetResourceVersion(actual.GetResourceVersion())
106107
return o.updateResource(ctx, bindings, obj)
107108
}
@@ -117,6 +118,7 @@ func (o *operation) handleCheck(ctx context.Context, bindings apis.Bindings, obj
117118
} else {
118119
bindings = apibindings.RegisterBinding(bindings, "error", err.Error())
119120
}
121+
bindings = operations.RegisterWarningsInBindings(ctx, bindings)
120122
defer func(bindings apis.Bindings) {
121123
if _err == nil {
122124
outputs, err := outputs.Process(ctx, o.compilers, bindings, obj.UnstructuredContent(), o.outputs...)

pkg/engine/operations/warnings.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package operations
2+
3+
import (
4+
"context"
5+
6+
"github.com/kyverno/chainsaw/pkg/apis"
7+
"github.com/kyverno/chainsaw/pkg/engine/bindings"
8+
enginecontext "github.com/kyverno/chainsaw/pkg/runner/context"
9+
)
10+
11+
func RegisterWarningsInBindings(ctx context.Context, tc apis.Bindings) apis.Bindings {
12+
ctxTc := enginecontext.TestContextFromCtx(ctx)
13+
if ctxTc != nil && ctxTc.CurrentCluster() != nil {
14+
warnings := ctxTc.CurrentCluster().GetWarnings()
15+
tc = bindings.RegisterBinding(tc, "warnings", warnings)
16+
}
17+
18+
return tc
19+
}
20+
21+
func ResetWarnings(ctx context.Context) {
22+
ctxTc := enginecontext.TestContextFromCtx(ctx)
23+
if ctxTc != nil && ctxTc.CurrentCluster() != nil {
24+
ctxTc.CurrentCluster().ResetWarnings()
25+
}
26+
}

pkg/model/warning.go

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package model
2+
3+
type WithWarnings struct {
4+
warnings []map[string]any
5+
}
6+
7+
func NewWithWarnings() *WithWarnings {
8+
return &WithWarnings{warnings: make([]map[string]any, 0)}
9+
}
10+
11+
type WarningsHolder interface {
12+
GetWarnings() []map[string]any
13+
ResetWarnings()
14+
HandleWarningHeader(code int, agent string, text string)
15+
}
16+
17+
func (w *WithWarnings) GetWarnings() []map[string]any {
18+
return w.warnings
19+
}
20+
21+
func (w *WithWarnings) ResetWarnings() {
22+
w.warnings = make([]map[string]any, 0)
23+
}
24+
25+
func (w *WithWarnings) HandleWarningHeader(code int, agent string, text string) {
26+
w.warnings = append(w.warnings, map[string]any{"code": code, "agent": agent, "text": text})
27+
}

0 commit comments

Comments
 (0)