Skip to content

Commit 08391b3

Browse files
authored
Merge pull request kubernetes#123549 from carlory/kep-3751-finalizer
A new controller adds/removes finalizer to VAC for protection
2 parents 175a5b9 + a9de9a3 commit 08391b3

File tree

9 files changed

+1052
-0
lines changed

9 files changed

+1052
-0
lines changed

cmd/kube-controller-manager/app/controllermanager.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,7 @@ func NewControllerDescriptors() map[string]*ControllerDescriptor {
567567
register(newClusterRoleAggregrationControllerDescriptor())
568568
register(newPersistentVolumeClaimProtectionControllerDescriptor())
569569
register(newPersistentVolumeProtectionControllerDescriptor())
570+
register(newVolumeAttributesClassProtectionControllerDescriptor())
570571
register(newTTLAfterFinishedControllerDescriptor())
571572
register(newRootCACertificatePublisherControllerDescriptor())
572573
register(newEphemeralVolumeControllerDescriptor())

cmd/kube-controller-manager/app/controllermanager_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ func TestControllerNamesDeclaration(t *testing.T) {
8686
names.ClusterRoleAggregationController,
8787
names.PersistentVolumeClaimProtectionController,
8888
names.PersistentVolumeProtectionController,
89+
names.VolumeAttributesClassProtectionController,
8990
names.TTLAfterFinishedController,
9091
names.RootCACertificatePublisherController,
9192
names.EphemeralVolumeController,

cmd/kube-controller-manager/app/core.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ import (
6464
persistentvolumecontroller "k8s.io/kubernetes/pkg/controller/volume/persistentvolume"
6565
"k8s.io/kubernetes/pkg/controller/volume/pvcprotection"
6666
"k8s.io/kubernetes/pkg/controller/volume/pvprotection"
67+
"k8s.io/kubernetes/pkg/controller/volume/vacprotection"
6768
"k8s.io/kubernetes/pkg/features"
6869
quotainstall "k8s.io/kubernetes/pkg/quota/v1/install"
6970
"k8s.io/kubernetes/pkg/volume/csimigration"
@@ -684,6 +685,31 @@ func startPersistentVolumeProtectionController(ctx context.Context, controllerCo
684685
return nil, true, nil
685686
}
686687

688+
func newVolumeAttributesClassProtectionControllerDescriptor() *ControllerDescriptor {
689+
return &ControllerDescriptor{
690+
name: names.VolumeAttributesClassProtectionController,
691+
initFunc: startVolumeAttributesClassProtectionController,
692+
requiredFeatureGates: []featuregate.Feature{
693+
features.VolumeAttributesClass,
694+
},
695+
}
696+
}
697+
698+
func startVolumeAttributesClassProtectionController(ctx context.Context, controllerContext ControllerContext, controllerName string) (controller.Interface, bool, error) {
699+
vacProtectionController, err := vacprotection.NewVACProtectionController(
700+
klog.FromContext(ctx),
701+
controllerContext.ClientBuilder.ClientOrDie("volumeattributesclass-protection-controller"),
702+
controllerContext.InformerFactory.Core().V1().PersistentVolumeClaims(),
703+
controllerContext.InformerFactory.Core().V1().PersistentVolumes(),
704+
controllerContext.InformerFactory.Storage().V1beta1().VolumeAttributesClasses(),
705+
)
706+
if err != nil {
707+
return nil, true, fmt.Errorf("failed to start the vac protection controller: %w", err)
708+
}
709+
go vacProtectionController.Run(ctx, 1)
710+
return nil, true, nil
711+
}
712+
687713
func newTTLAfterFinishedControllerDescriptor() *ControllerDescriptor {
688714
return &ControllerDescriptor{
689715
name: names.TTLAfterFinishedController,

cmd/kube-controller-manager/names/controller_names.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,7 @@ const (
8282
ResourceClaimController = "resourceclaim-controller"
8383
LegacyServiceAccountTokenCleanerController = "legacy-serviceaccount-token-cleaner-controller"
8484
ValidatingAdmissionPolicyStatusController = "validatingadmissionpolicy-status-controller"
85+
VolumeAttributesClassProtectionController = "volumeattributesclass-protection-controller"
8586
ServiceCIDRController = "service-cidr-controller"
8687
StorageVersionMigratorController = "storage-version-migrator-controller"
8788
)
Lines changed: 216 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,216 @@
1+
/*
2+
Copyright 2024 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package protectionutil
18+
19+
import (
20+
v1 "k8s.io/api/core/v1"
21+
storagev1beta1 "k8s.io/api/storage/v1beta1"
22+
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
23+
"k8s.io/apimachinery/pkg/types"
24+
)
25+
26+
// PodWrapper wraps a Pod inside.
27+
type PodWrapper struct{ v1.Pod }
28+
29+
// MakePod creates a Pod wrapper.
30+
func MakePod() *PodWrapper {
31+
return &PodWrapper{v1.Pod{}}
32+
}
33+
34+
// Obj returns the inner Pod.
35+
func (p *PodWrapper) Obj() *v1.Pod {
36+
return &p.Pod
37+
}
38+
39+
// Name sets `s` as the name of the inner pod.
40+
func (p *PodWrapper) Name(s string) *PodWrapper {
41+
p.SetName(s)
42+
return p
43+
}
44+
45+
// UID sets `s` as the UID of the inner pod.
46+
func (p *PodWrapper) UID(s string) *PodWrapper {
47+
p.SetUID(types.UID(s))
48+
return p
49+
}
50+
51+
// SchedulerName sets `s` as the scheduler name of the inner pod.
52+
func (p *PodWrapper) SchedulerName(s string) *PodWrapper {
53+
p.Spec.SchedulerName = s
54+
return p
55+
}
56+
57+
// Namespace sets `s` as the namespace of the inner pod.
58+
func (p *PodWrapper) Namespace(s string) *PodWrapper {
59+
p.SetNamespace(s)
60+
return p
61+
}
62+
63+
// Terminating sets the inner pod's deletionTimestamp to current timestamp.
64+
func (p *PodWrapper) Terminating() *PodWrapper {
65+
now := metav1.Now()
66+
p.DeletionTimestamp = &now
67+
return p
68+
}
69+
70+
// PVC creates a Volume with a PVC and injects into the inner pod.
71+
func (p *PodWrapper) PVC(name string) *PodWrapper {
72+
p.Spec.Volumes = append(p.Spec.Volumes, v1.Volume{
73+
Name: name,
74+
VolumeSource: v1.VolumeSource{
75+
PersistentVolumeClaim: &v1.PersistentVolumeClaimVolumeSource{ClaimName: name},
76+
},
77+
})
78+
return p
79+
}
80+
81+
// Annotation sets a {k,v} pair to the inner pod annotation.
82+
func (p *PodWrapper) Annotation(key, value string) *PodWrapper {
83+
metav1.SetMetaDataAnnotation(&p.ObjectMeta, key, value)
84+
return p
85+
}
86+
87+
// Annotations sets all {k,v} pair provided by `annotations` to the inner pod annotations.
88+
func (p *PodWrapper) Annotations(annotations map[string]string) *PodWrapper {
89+
for k, v := range annotations {
90+
p.Annotation(k, v)
91+
}
92+
return p
93+
}
94+
95+
// PersistentVolumeClaimWrapper wraps a PersistentVolumeClaim inside.
96+
type PersistentVolumeClaimWrapper struct{ v1.PersistentVolumeClaim }
97+
98+
// MakePersistentVolumeClaim creates a PersistentVolumeClaim wrapper.
99+
func MakePersistentVolumeClaim() *PersistentVolumeClaimWrapper {
100+
return &PersistentVolumeClaimWrapper{}
101+
}
102+
103+
// Obj returns the inner PersistentVolumeClaim.
104+
func (p *PersistentVolumeClaimWrapper) Obj() *v1.PersistentVolumeClaim {
105+
return &p.PersistentVolumeClaim
106+
}
107+
108+
// Name sets `s` as the name of the inner PersistentVolumeClaim.
109+
func (p *PersistentVolumeClaimWrapper) Name(s string) *PersistentVolumeClaimWrapper {
110+
p.SetName(s)
111+
return p
112+
}
113+
114+
// Namespace sets `s` as the namespace of the inner PersistentVolumeClaim.
115+
func (p *PersistentVolumeClaimWrapper) Namespace(s string) *PersistentVolumeClaimWrapper {
116+
p.SetNamespace(s)
117+
return p
118+
}
119+
120+
// Annotation sets a {k,v} pair to the inner PersistentVolumeClaim.
121+
func (p *PersistentVolumeClaimWrapper) Annotation(key, value string) *PersistentVolumeClaimWrapper {
122+
metav1.SetMetaDataAnnotation(&p.ObjectMeta, key, value)
123+
return p
124+
}
125+
126+
// VolumeName sets `name` as the volume name of the inner
127+
// PersistentVolumeClaim.
128+
func (p *PersistentVolumeClaimWrapper) VolumeName(name string) *PersistentVolumeClaimWrapper {
129+
p.PersistentVolumeClaim.Spec.VolumeName = name
130+
return p
131+
}
132+
133+
func (p *PersistentVolumeClaimWrapper) Finalizer(s string) *PersistentVolumeClaimWrapper {
134+
p.Finalizers = append(p.Finalizers, s)
135+
return p
136+
}
137+
138+
// VolumeAttributesClassName sets `s` as the VolumeAttributesClassName of the inner PersistentVolumeClaim.
139+
func (p *PersistentVolumeClaimWrapper) VolumeAttributesClassName(s string) *PersistentVolumeClaimWrapper {
140+
p.Spec.VolumeAttributesClassName = &s
141+
return p
142+
}
143+
144+
// CurrentVolumeAttributesClassName sets `s` as the CurrentVolumeAttributesClassName of the inner PersistentVolumeClaim.
145+
func (p *PersistentVolumeClaimWrapper) CurrentVolumeAttributesClassName(s string) *PersistentVolumeClaimWrapper {
146+
p.Status.CurrentVolumeAttributesClassName = &s
147+
return p
148+
}
149+
150+
// TargetVolumeAttributesClassName sets `s` as the TargetVolumeAttributesClassName of the inner PersistentVolumeClaim.
151+
// It also sets the status to Pending.
152+
func (p *PersistentVolumeClaimWrapper) TargetVolumeAttributesClassName(s string) *PersistentVolumeClaimWrapper {
153+
p.Status.ModifyVolumeStatus = &v1.ModifyVolumeStatus{
154+
TargetVolumeAttributesClassName: s,
155+
Status: v1.PersistentVolumeClaimModifyVolumePending,
156+
}
157+
return p
158+
}
159+
160+
// PersistentVolumeWrapper wraps a PersistentVolume inside.
161+
type PersistentVolumeWrapper struct{ v1.PersistentVolume }
162+
163+
// MakePersistentVolume creates a PersistentVolume wrapper.
164+
func MakePersistentVolume() *PersistentVolumeWrapper {
165+
return &PersistentVolumeWrapper{}
166+
}
167+
168+
// Obj returns the inner PersistentVolume.
169+
func (p *PersistentVolumeWrapper) Obj() *v1.PersistentVolume {
170+
return &p.PersistentVolume
171+
}
172+
173+
// Name sets `s` as the name of the inner PersistentVolume.
174+
func (p *PersistentVolumeWrapper) Name(s string) *PersistentVolumeWrapper {
175+
p.SetName(s)
176+
return p
177+
}
178+
179+
// VolumeAttributesClassName sets `s` as the VolumeAttributesClassName of the inner PersistentVolume.
180+
func (p *PersistentVolumeWrapper) VolumeAttributesClassName(s string) *PersistentVolumeWrapper {
181+
p.Spec.VolumeAttributesClassName = &s
182+
return p
183+
}
184+
185+
// VolumeAttributesClassWrapper wraps a VolumeAttributesClass inside.
186+
type VolumeAttributesClassWrapper struct {
187+
storagev1beta1.VolumeAttributesClass
188+
}
189+
190+
// MakeVolumeAttributesClass creates a VolumeAttributesClass wrapper.
191+
func MakeVolumeAttributesClass() *VolumeAttributesClassWrapper {
192+
return &VolumeAttributesClassWrapper{}
193+
}
194+
195+
// Obj returns the inner VolumeAttributesClass.
196+
func (v *VolumeAttributesClassWrapper) Obj() *storagev1beta1.VolumeAttributesClass {
197+
return &v.VolumeAttributesClass
198+
}
199+
200+
// Name sets `s` as the name of the inner VolumeAttributesClass.
201+
func (v *VolumeAttributesClassWrapper) Name(s string) *VolumeAttributesClassWrapper {
202+
v.SetName(s)
203+
return v
204+
}
205+
206+
// Terminating sets the inner VolumeAttributesClass' deletionTimestamp to non-nil.
207+
func (v *VolumeAttributesClassWrapper) Terminating() *VolumeAttributesClassWrapper {
208+
v.DeletionTimestamp = &metav1.Time{}
209+
return v
210+
}
211+
212+
// Finalizer appends `s` to the finalizers of the inner VolumeAttributesClass.
213+
func (v *VolumeAttributesClassWrapper) Finalizer(s string) *VolumeAttributesClassWrapper {
214+
v.Finalizers = append(v.Finalizers, s)
215+
return v
216+
}

0 commit comments

Comments
 (0)