Skip to content

Commit ae666b1

Browse files
authored
Merge pull request #274 from stephanhorsthemke/prune-whitelist
Prune whitelist
2 parents 5be555d + df05e26 commit ae666b1

File tree

7 files changed

+76
-30
lines changed

7 files changed

+76
-30
lines changed

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ require (
1515
github.com/google/go-cmp v0.5.8
1616
github.com/prometheus/client_golang v1.12.2
1717
golang.org/x/crypto v0.0.0-20220315160706-3147a52a75dd
18-
golang.org/x/tools v0.1.12
18+
golang.org/x/tools v0.3.0
1919
k8s.io/api v0.25.0
2020
k8s.io/apimachinery v0.25.4
2121
k8s.io/cli-runtime v0.25.0
@@ -93,7 +93,7 @@ require (
9393
github.com/xanzy/ssh-agent v0.2.1 // indirect
9494
github.com/xlab/treeprint v1.1.0 // indirect
9595
go.starlark.net v0.0.0-20200306205701-8dd3e2ee1dd5 // indirect
96-
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 // indirect
96+
golang.org/x/mod v0.7.0 // indirect
9797
golang.org/x/net v0.2.0 // indirect
9898
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect
9999
golang.org/x/sys v0.2.0 // indirect

go.sum

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -451,8 +451,8 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
451451
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
452452
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
453453
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
454-
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
455-
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
454+
golang.org/x/mod v0.7.0 h1:LapD9S96VoQRhi/GrNTqeBJFrUjs5UHCAtTlgwA5oZA=
455+
golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
456456
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
457457
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
458458
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -654,8 +654,8 @@ golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
654654
golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
655655
golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
656656
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
657-
golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
658-
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
657+
golang.org/x/tools v0.3.0 h1:SrNbZl6ECOS1qFzgTdQfWXZM9XBkiA6tkFrH9YSTPHM=
658+
golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k=
659659
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
660660
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
661661
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

pkg/patterns/declarative/pkg/applier/direct.go

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import (
66
"os"
77
"strings"
88

9+
"k8s.io/kubectl/pkg/util/prune"
10+
911
"k8s.io/apimachinery/pkg/api/meta"
1012
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1113
utilerrors "k8s.io/apimachinery/pkg/util/errors"
@@ -76,8 +78,15 @@ func (d *DirectApplier) Apply(ctx context.Context, opt ApplierOptions) error {
7678
b := d.inner.NewBuilder(opt)
7779
f := d.inner.NewFactory(opt)
7880

81+
// TODO can we just reuse this
82+
dynamicClient, err := f.DynamicClient()
83+
if err != nil {
84+
return err
85+
}
86+
7987
if opt.Validate {
80-
// This potentially causes redundant work, but validation isn't the common path
88+
// validation likely makes redundant apiserver requests and is less optimized than the non-validation case,
89+
// but validation isn't the common path
8190

8291
dynamicClient, err := f.DynamicClient()
8392
if err != nil {
@@ -123,21 +132,41 @@ func (d *DirectApplier) Apply(ctx context.Context, opt ApplierOptions) error {
123132
IOStreams: ioStreams,
124133
FieldManager: "kubectl-client-side-apply",
125134
ValidationDirective: metav1.FieldValidationStrict,
135+
Mapper: opt.RESTMapper,
136+
DynamicClient: dynamicClient,
126137
}
138+
// TODO this will add the print part at all times.
139+
applyOpts.PostProcessorFn = applyOpts.PrintAndPrunePostProcessor()
127140

141+
whiteListResources := []string{}
128142
for i, arg := range opt.ExtraArgs {
129143
switch arg {
130144
case "--force":
145+
// TODO Does this do anything? It seems like opt (aka ApplierOptions) is not used anymore
131146
opt.Force = true
132147
case "--prune":
133148
applyOpts.Prune = true
134149
case "--selector":
135150
applyOpts.Selector = opt.ExtraArgs[i+1]
151+
case "--prune-whitelist":
152+
whiteListResources = append(whiteListResources, opt.ExtraArgs[i+1])
136153
default:
137154
continue
138155
}
139156
}
140157

158+
if len(whiteListResources) > 0 {
159+
rm, err := f.ToRESTMapper()
160+
if err != nil {
161+
return err
162+
}
163+
r, err := prune.ParseResources(rm, whiteListResources)
164+
if err != nil {
165+
return err
166+
}
167+
applyOpts.PruneResources = append(applyOpts.PruneResources, r...)
168+
}
169+
141170
applyOpts.ForceConflicts = opt.Force
142171
applyOpts.Namespace = opt.Namespace
143172
applyOpts.SetObjects(infos)
@@ -147,7 +176,8 @@ func (d *DirectApplier) Apply(ctx context.Context, opt ApplierOptions) error {
147176
return applyOpts.PrintFlags.ToPrinter()
148177
}
149178
applyOpts.DeleteOptions = &cmdDelete.DeleteOptions{
150-
IOStreams: ioStreams,
179+
IOStreams: ioStreams,
180+
CascadingStrategy: opt.CascadingStrategy,
151181
}
152182

153183
if err := d.inner.Run(applyOpts); err != nil {

pkg/patterns/declarative/pkg/applier/direct_test.go

Lines changed: 27 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -152,26 +152,33 @@ metadata:
152152
return nil
153153
},
154154
},
155-
// {
156-
// name: "manifest with prune and prune-whitelist",
157-
// namespace: "",
158-
// manifest: `---
159-
//apiVersion: v1
160-
//kind: ServiceAccount
161-
//metadata:
162-
// name: foo-operator
163-
// namespace: kube-system`,
164-
// args: []string{"--prune", "--prune-whitelist=hello-world"},
165-
// expectApplyOptions: &apply.ApplyOptions{
166-
// Prune: true,
167-
// },
168-
// expectCheckFunc: func(opt *apply.ApplyOptions) error {
169-
// if opt.Prune != true {
170-
// return fmt.Errorf("prune is not set")
171-
// }
172-
// return nil
173-
// },
174-
// },
155+
{
156+
name: "manifest with prune, prune-whitelist and selector",
157+
namespace: "",
158+
manifest: `---
159+
apiVersion: v1
160+
kind: ServiceAccount
161+
metadata:
162+
name: foo-operator
163+
namespace: kube-system`,
164+
args: []string{"--prune", "--selector", "label=true", "--prune-whitelist", "core/v1/Namespace", "--prune-whitelist", "core/v1/Service"},
165+
// TODO is this used somewhere?
166+
expectApplyOptions: &apply.ApplyOptions{
167+
Prune: true,
168+
},
169+
expectCheckFunc: func(opt *apply.ApplyOptions) error {
170+
if opt.Prune != true {
171+
return fmt.Errorf("prune is not set")
172+
}
173+
if len(opt.PruneResources) != 2 {
174+
return fmt.Errorf("prune resources are not set correctly, found %s", opt.PruneResources)
175+
}
176+
if opt.Selector != "label=true" {
177+
return fmt.Errorf("selector is not set as expected, found %s", opt.Selector)
178+
}
179+
return nil
180+
},
181+
},
175182
}
176183

177184
for _, test := range tests {

pkg/patterns/declarative/pkg/applier/exec.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ func (c *ExecKubectl) Apply(ctx context.Context, opt ApplierOptions) error {
135135
if opt.Force {
136136
args = append(args, "--force")
137137
}
138+
138139
args = append(args, opt.ExtraArgs...)
139140
args = append(args, "-f", "-")
140141

pkg/patterns/declarative/pkg/applier/type.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55

66
"k8s.io/apimachinery/pkg/api/meta"
7+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
78
"k8s.io/client-go/rest"
89
)
910

@@ -19,6 +20,11 @@ type ApplierOptions struct {
1920
Namespace string
2021
Validate bool
2122

23+
CascadingStrategy metav1.DeletionPropagation
24+
25+
PruneWhitelist []string
26+
Prune bool
27+
2228
// Force is set if we should "force" the apply.
2329
// For server-side-apply, this corresponds to setting the force option, which ensures we take ownership
2430
// even when another field manager owns a field.

pkg/patterns/declarative/reconciler.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -302,18 +302,20 @@ func (r *Reconciler) reconcileExists(ctx context.Context, name types.NamespacedN
302302
}
303303
}
304304

305-
applyOpt := applier.ApplierOptions{
305+
applierOpt := applier.ApplierOptions{
306306
RESTConfig: r.config,
307307
RESTMapper: r.restMapper,
308308
Namespace: ns,
309309
Manifest: manifestStr,
310310
Validate: r.options.validate,
311311
ExtraArgs: extraArgs,
312312
Force: true,
313+
// TODO Make this configurable
314+
CascadingStrategy: "Foreground",
313315
}
314316

315317
applier := r.options.applier
316-
if err := applier.Apply(ctx, applyOpt); err != nil {
318+
if err := applier.Apply(ctx, applierOpt); err != nil {
317319
log.Error(err, "applying manifest")
318320
return objects, fmt.Errorf("error applying manifest: %v", err)
319321
}

0 commit comments

Comments
 (0)