controllers, auth, quota: make Dynamic Resource Allocation unconditional

This commit is contained in:
Troy Chiu committed 2026-09-15 21:26:15 +00:00
1 parent 6f2ce60141
commit 8d8ef384c2
9 files changed
+139 -228

No files matched your search

@@ -157,11 +157,6 @@ func TestFeatureGatedControllersShouldNotDefineAliases(t *testing.T) {
continue
}
// DO NOT ADD any new controllers here. one controller is an exception, because it was added before this test was introduced
if name == names.ResourceClaimController {
continue
}
areAllRequiredFeaturesAlpha := true
for _, feature := range requiredFeatureGates {
if !alphaFeatures.Has(string(feature)) {
@@ -34,8 +34,6 @@ func newDeviceTaintEvictionControllerDescriptor() *ControllerDescriptor {
name: names.DeviceTaintEvictionController,
constructor: newDeviceTaintEvictionController,
requiredFeatureGates: []featuregate.Feature{
// TODO update app.TestFeatureGatedControllersShouldNotDefineAliases when removing these feature gates.
features.DynamicResourceAllocation,
features.DRADeviceTaints,
},
}
@@ -69,9 +67,6 @@ func newResourceClaimControllerDescriptor() *ControllerDescriptor {
name: names.ResourceClaimController,
aliases: []string{"resource-claim-controller"},
constructor: newResourceClaimController,
requiredFeatureGates: []featuregate.Feature{
features.DynamicResourceAllocation, // TODO update app.TestFeatureGatedControllersShouldNotDefineAliases when removing this feature
},
}
}
+1 -6
View File
@@ -35,7 +35,6 @@ import (
utilfeature "k8s.io/apiserver/pkg/util/feature"
versionedinformers "k8s.io/client-go/informers"
certinformersv1 "k8s.io/client-go/informers/certificates/v1"
resourceinformers "k8s.io/client-go/informers/resource/v1"
"k8s.io/kubernetes/pkg/auth/authorizer/abac"
"k8s.io/kubernetes/pkg/auth/nodeidentifier"
"k8s.io/kubernetes/pkg/features"
@@ -102,10 +101,6 @@ func (config Config) New(ctx context.Context, serverID string) (authorizer.Autho
// Keep cases in sync with constant list in k8s.io/kubernetes/pkg/kubeapiserver/authorizer/modes/modes.go.
switch configuredAuthorizer.Type {
case authzconfig.AuthorizerType(modes.ModeNode):
var slices resourceinformers.ResourceSliceInformer
if utilfeature.DefaultFeatureGate.Enabled(features.DynamicResourceAllocation) {
slices = config.VersionedInformerFactory.Resource().V1().ResourceSlices()
}
var podCertificateRequestInformer certinformersv1.PodCertificateRequestInformer
if utilfeature.DefaultFeatureGate.Enabled(features.PodCertificateRequest) {
podCertificateRequestInformer = config.VersionedInformerFactory.Certificates().V1().PodCertificateRequests()
@@ -119,7 +114,7 @@ func (config Config) New(ctx context.Context, serverID string) (authorizer.Autho
config.VersionedInformerFactory.Core().V1().Pods(),
config.VersionedInformerFactory.Core().V1().PersistentVolumes(),
config.VersionedInformerFactory.Storage().V1().VolumeAttachments(),
slices, // Nil check in AddGraphEventHandlers can be removed when always creating this.
config.VersionedInformerFactory.Resource().V1().ResourceSlices(),
podCertificateRequestInformer,
)
r.nodeAuthorizer = node.NewAuthorizer(graph, nodeidentifier.NewDefaultNodeIdentifier(), bootstrappolicy.NodeRules())
+1 -1
View File
@@ -59,7 +59,7 @@ func NewEvaluators(f quota.ListerForResourceFunc, i informers.SharedInformerFact
if isEnabled(corev1.SchemeGroupVersion.WithResource("persistentvolumeclaims")) {
result = append(result, NewPersistentVolumeClaimEvaluator(f))
}
if isEnabled(resourcev1.SchemeGroupVersion.WithResource("resourceclaims")) && utilfeature.DefaultFeatureGate.Enabled(features.DynamicResourceAllocation) {
if isEnabled(resourcev1.SchemeGroupVersion.WithResource("resourceclaims")) {
var claimGetter resourceClaimPodOwnerGetter
var podLister corev1listers.PodLister
var deviceClassMapping *extendedresourcecache.ExtendedResourceCache
@@ -91,7 +91,6 @@ type Plugin struct {
inspectedFeatureGates bool
expansionRecoveryEnabled bool
dynamicResourceAllocationEnabled bool
allowInsecureKubeletCertificateSigningRequests bool
serviceAccountNodeAudienceRestriction bool
podCertificateRequestsEnabled bool
@@ -108,7 +107,6 @@ var (
// InspectFeatureGates allows setting bools without taking a dep on a global variable
func (p *Plugin) InspectFeatureGates(featureGates featuregate.FeatureGate) {
p.expansionRecoveryEnabled = featureGates.Enabled(features.RecoverVolumeExpansionFailure)
p.dynamicResourceAllocationEnabled = featureGates.Enabled(features.DynamicResourceAllocation)
p.allowInsecureKubeletCertificateSigningRequests = featureGates.Enabled(features.AllowInsecureKubeletCertificateSigningRequests)
p.serviceAccountNodeAudienceRestriction = featureGates.Enabled(features.ServiceAccountNodeAudienceRestriction)
p.podCertificateRequestsEnabled = featureGates.Enabled(features.PodCertificateRequest)
@@ -2779,116 +2779,64 @@ func TestAdmitResourceSlice(t *testing.T) {
}
tests := map[string]struct {
operation admission.Operation
options runtime.Object
obj, oldObj runtime.Object
featureEnabled bool
expectError string
operation admission.Operation
options runtime.Object
obj, oldObj runtime.Object
expectError string
}{
"create allowed, enabled": {
operation: admission.Create,
options: &metav1.CreateOptions{},
obj: sliceNode,
featureEnabled: true,
expectError: "",
"create allowed": {
operation: admission.Create,
options: &metav1.CreateOptions{},
obj: sliceNode,
expectError: "",
},
"create disallowed, enabled": {
operation: admission.Create,
options: &metav1.CreateOptions{},
obj: sliceOtherNode,
featureEnabled: true,
expectError: createErr,
"create disallowed": {
operation: admission.Create,
options: &metav1.CreateOptions{},
obj: sliceOtherNode,
expectError: createErr,
},
"create disallowed, no node name, enabled": {
operation: admission.Create,
options: &metav1.CreateOptions{},
obj: sliceNoNode,
featureEnabled: true,
expectError: createErr,
},
"create allowed, disabled": {
operation: admission.Create,
options: &metav1.CreateOptions{},
obj: sliceNode,
featureEnabled: false,
expectError: "",
},
"create disallowed, disabled": {
operation: admission.Create,
options: &metav1.CreateOptions{},
obj: sliceOtherNode,
featureEnabled: false,
expectError: createErr,
},
"create disallowed, no node name, disabled": {
operation: admission.Create,
options: &metav1.CreateOptions{},
obj: sliceNoNode,
featureEnabled: false,
expectError: createErr,
"create disallowed, no node name": {
operation: admission.Create,
options: &metav1.CreateOptions{},
obj: sliceNoNode,
expectError: createErr,
},
"update allowed, same node": {
operation: admission.Update,
options: &metav1.UpdateOptions{},
obj: sliceNode,
featureEnabled: true,
expectError: "",
operation: admission.Update,
options: &metav1.UpdateOptions{},
obj: sliceNode,
expectError: "",
},
"update allowed, other node": {
operation: admission.Update,
options: &metav1.UpdateOptions{},
obj: sliceOtherNode,
featureEnabled: true,
expectError: "",
operation: admission.Update,
options: &metav1.UpdateOptions{},
obj: sliceOtherNode,
expectError: "",
},
"update allowed, no node": {
operation: admission.Update,
options: &metav1.UpdateOptions{},
obj: sliceNoNode,
featureEnabled: true,
expectError: "",
operation: admission.Update,
options: &metav1.UpdateOptions{},
obj: sliceNoNode,
expectError: "",
},
"delete allowed, enabled": {
operation: admission.Delete,
options: &metav1.DeleteOptions{},
oldObj: sliceNode,
featureEnabled: true,
expectError: "",
"delete allowed": {
operation: admission.Delete,
options: &metav1.DeleteOptions{},
oldObj: sliceNode,
expectError: "",
},
"delete disallowed, enabled": {
operation: admission.Delete,
options: &metav1.DeleteOptions{},
oldObj: sliceOtherNode,
featureEnabled: true,
expectError: deleteErr,
"delete disallowed": {
operation: admission.Delete,
options: &metav1.DeleteOptions{},
oldObj: sliceOtherNode,
expectError: deleteErr,
},
"delete disallowed, no node name, enabled": {
operation: admission.Delete,
options: &metav1.DeleteOptions{},
oldObj: sliceNoNode,
featureEnabled: true,
expectError: deleteErr,
},
"delete allowed, disabled": {
operation: admission.Delete,
options: &metav1.DeleteOptions{},
oldObj: sliceNode,
featureEnabled: false,
expectError: "",
},
"delete disallowed, disabled": {
operation: admission.Delete,
options: &metav1.DeleteOptions{},
oldObj: sliceOtherNode,
featureEnabled: false,
expectError: deleteErr,
},
"delete disallowed, no node name, disabled": {
operation: admission.Delete,
options: &metav1.DeleteOptions{},
oldObj: sliceNoNode,
featureEnabled: false,
expectError: deleteErr,
"delete disallowed, no node name": {
operation: admission.Delete,
options: &metav1.DeleteOptions{},
oldObj: sliceNoNode,
expectError: deleteErr,
},
}
@@ -2897,10 +2845,6 @@ func TestAdmitResourceSlice(t *testing.T) {
attributes := admission.NewAttributesRecord(
test.obj, test.oldObj, schema.GroupVersionKind{},
"", "foo", apiResource, "", test.operation, test.options, false, mynode)
if !test.featureEnabled {
featuregatetesting.SetFeatureGateEmulationVersionDuringTest(t, feature.DefaultFeatureGate, version.MustParse("1.34"))
}
featuregatetesting.SetFeatureGateDuringTest(t, feature.DefaultFeatureGate, features.DynamicResourceAllocation, test.featureEnabled)
a := &admitTestCase{
name: name,
attributes: attributes,
@@ -85,16 +85,18 @@ func AddGraphEventHandlers(
podQueue: newRateLimitingQueue("node_authorizer_pods"),
pvQueue: newRateLimitingQueue("node_authorizer_persistentvolumes"),
attachmentQueue: newRateLimitingQueue("node_authorizer_volumeattachments"),
sliceQueue: newRateLimitingQueue("node_authorizer_resourceslices"),
podLister: pods.Lister(),
pvLister: pvs.Lister(),
attachmentLister: attachments.Lister(),
sliceLister: slices.Lister(),
}
queues := []workqueue.TypedRateLimitingInterface[types.NamespacedName]{
g.podQueue, g.pvQueue, g.attachmentQueue,
g.podQueue, g.pvQueue, g.attachmentQueue, g.sliceQueue,
}
workers := []func(){
g.runPodWorker, g.runPVWorker, g.runAttachmentWorker,
g.runPodWorker, g.runPVWorker, g.runAttachmentWorker, g.runSliceWorker,
}
podHandler, _ := pods.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
@@ -115,21 +117,14 @@ func AddGraphEventHandlers(
DeleteFunc: g.deleteVolumeAttachment,
})
synced := []cache.InformerSynced{
podHandler.HasSynced, pvsHandler.HasSynced, attachHandler.HasSynced,
}
sliceHandler, _ := slices.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: g.addResourceSlice,
UpdateFunc: nil, // Not needed, NodeName is immutable.
DeleteFunc: g.deleteResourceSlice,
})
if slices != nil {
g.sliceQueue = newRateLimitingQueue("node_authorizer_resourceslices")
g.sliceLister = slices.Lister()
queues = append(queues, g.sliceQueue)
workers = append(workers, g.runSliceWorker)
sliceHandler, _ := slices.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{
AddFunc: g.addResourceSlice,
UpdateFunc: nil, // Not needed, NodeName is immutable.
DeleteFunc: g.deleteResourceSlice,
})
synced = append(synced, sliceHandler.HasSynced)
synced := []cache.InformerSynced{
podHandler.HasSynced, pvsHandler.HasSynced, attachHandler.HasSynced, sliceHandler.HasSynced,
}
if pcrs != nil {
@@ -385,9 +380,6 @@ func (g *graphPopulator) runSliceWorker() {
}
func (g *graphPopulator) processSliceKey(key types.NamespacedName) error {
if g.sliceLister == nil {
return nil
}
slice, err := g.sliceLister.Get(key.Name)
if err != nil {
if errors.IsNotFound(err) {
@@ -200,77 +200,75 @@ func buildControllerRoles() ([]rbacv1.ClusterRole, []rbacv1.ClusterRoleBinding)
},
})
if utilfeature.DefaultFeatureGate.Enabled(features.DynamicResourceAllocation) {
rules := []rbacv1.PolicyRule{
rbacv1helpers.NewRule("get", "list", "watch").Groups(legacyGroup).Resources("pods").RuleOrDie(),
rbacv1helpers.NewRule("update").Groups(legacyGroup).Resources("pods/finalizers").RuleOrDie(),
rbacv1helpers.NewRule("get", "list", "watch", "create", "delete").Groups(resourceGroup).Resources("resourceclaims").RuleOrDie(),
rbacv1helpers.NewRule("update", "patch").Groups(resourceGroup).Resources("resourceclaims", "resourceclaims/status").RuleOrDie(),
rbacv1helpers.NewRule("update", "patch").Groups(legacyGroup).Resources("pods/status").RuleOrDie(),
eventsRule(),
}
if utilfeature.DefaultFeatureGate.Enabled(features.DRAWorkloadResourceClaims) {
rules = append(rules,
rbacv1helpers.NewRule("get", "list", "watch").Groups(schedulingGroup).Resources("podgroups").RuleOrDie(),
rbacv1helpers.NewRule("update", "patch").Groups(schedulingGroup).Resources("podgroups/status").RuleOrDie(),
)
}
if utilfeature.DefaultFeatureGate.Enabled(features.DRAResourceClaimGranularStatusAuthorization) {
rules = append(rules,
rbacv1helpers.NewRule("update", "patch").Groups(resourceGroup).Resources("resourceclaims/binding").RuleOrDie(),
)
}
addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "resource-claim-controller"},
Rules: rules,
})
if utilfeature.DefaultFeatureGate.Enabled(features.DRADeviceTaints) {
rules := []rbacv1.PolicyRule{
rbacv1helpers.NewRule("get", "list", "watch").Groups(legacyGroup).Resources("pods").RuleOrDie(),
rbacv1helpers.NewRule("update").Groups(legacyGroup).Resources("pods/finalizers").RuleOrDie(),
rbacv1helpers.NewRule("get", "list", "watch", "create", "delete").Groups(resourceGroup).Resources("resourceclaims").RuleOrDie(),
rbacv1helpers.NewRule("update", "patch").Groups(resourceGroup).Resources("resourceclaims", "resourceclaims/status").RuleOrDie(),
// Deletes pods to evict them.
rbacv1helpers.NewRule("get", "list", "watch", "delete").Groups(legacyGroup).Resources("pods").RuleOrDie(),
// Sets pod conditions.
rbacv1helpers.NewRule("update", "patch").Groups(legacyGroup).Resources("pods/status").RuleOrDie(),
// The rest is read-only.
rbacv1helpers.NewRule("get", "list", "watch").Groups(resourceGroup).Resources("resourceclaims").RuleOrDie(),
rbacv1helpers.NewRule("get", "list", "watch").Groups(resourceGroup).Resources("resourceslices").RuleOrDie(),
rbacv1helpers.NewRule("get", "list", "watch").Groups(resourceGroup).Resources("deviceclasses").RuleOrDie(),
eventsRule(),
}
if utilfeature.DefaultFeatureGate.Enabled(features.DRAWorkloadResourceClaims) {
if utilfeature.DefaultFeatureGate.Enabled(features.DRADeviceTaintRules) {
rules = append(rules,
rbacv1helpers.NewRule("get", "list", "watch").Groups(schedulingGroup).Resources("podgroups").RuleOrDie(),
rbacv1helpers.NewRule("update", "patch").Groups(schedulingGroup).Resources("podgroups/status").RuleOrDie(),
)
}
if utilfeature.DefaultFeatureGate.Enabled(features.DRAResourceClaimGranularStatusAuthorization) {
rules = append(rules,
rbacv1helpers.NewRule("update", "patch").Groups(resourceGroup).Resources("resourceclaims/binding").RuleOrDie(),
// Sets DeviceTaintRule conditions.
rbacv1helpers.NewRule("update", "patch").Groups(resourceGroup).Resources("devicetaintrules/status").RuleOrDie(),
// Read-only for spec.
rbacv1helpers.NewRule("get", "list", "watch").Groups(resourceGroup).Resources("devicetaintrules").RuleOrDie(),
)
}
addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "resource-claim-controller"},
// Same name as in k8s.io/kubernetes/cmd/kube-controller-manager/names.
ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "device-taint-eviction-controller"},
Rules: rules,
})
if utilfeature.DefaultFeatureGate.Enabled(features.DRADeviceTaints) {
rules := []rbacv1.PolicyRule{
// Deletes pods to evict them.
rbacv1helpers.NewRule("get", "list", "watch", "delete").Groups(legacyGroup).Resources("pods").RuleOrDie(),
// Sets pod conditions.
rbacv1helpers.NewRule("update", "patch").Groups(legacyGroup).Resources("pods/status").RuleOrDie(),
// The rest is read-only.
rbacv1helpers.NewRule("get", "list", "watch").Groups(resourceGroup).Resources("resourceclaims").RuleOrDie(),
}
if utilfeature.DefaultFeatureGate.Enabled(features.DRAResourcePoolStatus) {
addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
// Same name as in k8s.io/kubernetes/cmd/kube-controller-manager/names.
ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "resourcepoolstatusrequest-controller"},
Rules: []rbacv1.PolicyRule{
// Read and delete ResourcePoolStatusRequests (delete needed for TTL cleanup)
rbacv1helpers.NewRule("get", "list", "watch", "delete").Groups(resourceGroup).Resources("resourcepoolstatusrequests").RuleOrDie(),
// Update status after processing
rbacv1helpers.NewRule("update", "patch").Groups(resourceGroup).Resources("resourcepoolstatusrequests/status").RuleOrDie(),
// Read ResourceSlices to calculate pool status
rbacv1helpers.NewRule("get", "list", "watch").Groups(resourceGroup).Resources("resourceslices").RuleOrDie(),
rbacv1helpers.NewRule("get", "list", "watch").Groups(resourceGroup).Resources("deviceclasses").RuleOrDie(),
// Read ResourceClaims to calculate allocation counts
rbacv1helpers.NewRule("get", "list", "watch").Groups(resourceGroup).Resources("resourceclaims").RuleOrDie(),
// Read DeviceTaintRules to count tainted devices as unavailable
rbacv1helpers.NewRule("get", "list", "watch").Groups(resourceGroup).Resources("devicetaintrules").RuleOrDie(),
eventsRule(),
}
if utilfeature.DefaultFeatureGate.Enabled(features.DRADeviceTaintRules) {
rules = append(rules,
// Sets DeviceTaintRule conditions.
rbacv1helpers.NewRule("update", "patch").Groups(resourceGroup).Resources("devicetaintrules/status").RuleOrDie(),
// Read-only for spec.
rbacv1helpers.NewRule("get", "list", "watch").Groups(resourceGroup).Resources("devicetaintrules").RuleOrDie(),
)
}
addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
// Same name as in k8s.io/kubernetes/cmd/kube-controller-manager/names.
ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "device-taint-eviction-controller"},
Rules: rules,
})
}
if utilfeature.DefaultFeatureGate.Enabled(features.DRAResourcePoolStatus) {
addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
// Same name as in k8s.io/kubernetes/cmd/kube-controller-manager/names.
ObjectMeta: metav1.ObjectMeta{Name: saRolePrefix + "resourcepoolstatusrequest-controller"},
Rules: []rbacv1.PolicyRule{
// Read and delete ResourcePoolStatusRequests (delete needed for TTL cleanup)
rbacv1helpers.NewRule("get", "list", "watch", "delete").Groups(resourceGroup).Resources("resourcepoolstatusrequests").RuleOrDie(),
// Update status after processing
rbacv1helpers.NewRule("update", "patch").Groups(resourceGroup).Resources("resourcepoolstatusrequests/status").RuleOrDie(),
// Read ResourceSlices to calculate pool status
rbacv1helpers.NewRule("get", "list", "watch").Groups(resourceGroup).Resources("resourceslices").RuleOrDie(),
// Read ResourceClaims to calculate allocation counts
rbacv1helpers.NewRule("get", "list", "watch").Groups(resourceGroup).Resources("resourceclaims").RuleOrDie(),
// Read DeviceTaintRules to count tainted devices as unavailable
rbacv1helpers.NewRule("get", "list", "watch").Groups(resourceGroup).Resources("devicetaintrules").RuleOrDie(),
eventsRule(),
},
})
}
},
})
}
addControllerRole(&controllerRoles, &controllerRoleBindings, rbacv1.ClusterRole{
@@ -142,11 +142,10 @@ func viewRules() []rbacv1.PolicyRule {
rbacv1helpers.NewRule(Read...).Groups(policyGroup).Resources("poddisruptionbudgets", "poddisruptionbudgets/status").RuleOrDie(),
rbacv1helpers.NewRule(Read...).Groups(networkingGroup).Resources("networkpolicies", "ingresses", "ingresses/status").RuleOrDie(),
rbacv1helpers.NewRule(Read...).Groups(resourceGroup).Resources("resourceclaims", "resourceclaims/status", "resourceclaimtemplates").RuleOrDie(),
}
if utilfeature.DefaultFeatureGate.Enabled(features.DynamicResourceAllocation) {
rules = append(rules, rbacv1helpers.NewRule(Read...).Groups(resourceGroup).Resources("resourceclaims", "resourceclaims/status", "resourceclaimtemplates").RuleOrDie())
}
if utilfeature.DefaultFeatureGate.Enabled(features.GenericWorkload) {
rules = append(rules, rbacv1helpers.NewRule(Read...).Groups(schedulingGroup).Resources("workloads", "podgroups", "podgroups/status").RuleOrDie())
}
@@ -193,9 +192,8 @@ func editRules() []rbacv1.PolicyRule {
rbacv1helpers.NewRule(Write...).Groups(networkingGroup).Resources("networkpolicies", "ingresses").RuleOrDie(),
rbacv1helpers.NewRule(ReadWrite...).Groups(coordinationGroup).Resources("leases").RuleOrDie(),
}
if utilfeature.DefaultFeatureGate.Enabled(features.DynamicResourceAllocation) {
rules = append(rules, rbacv1helpers.NewRule(Write...).Groups(resourceGroup).Resources("resourceclaims", "resourceclaimtemplates").RuleOrDie())
rbacv1helpers.NewRule(Write...).Groups(resourceGroup).Resources("resourceclaims", "resourceclaimtemplates").RuleOrDie(),
}
if utilfeature.DefaultFeatureGate.Enabled(features.GenericWorkload) {
rules = append(rules, rbacv1helpers.NewRule(Write...).Groups(schedulingGroup).Resources("workloads", "podgroups").RuleOrDie())
@@ -289,10 +287,8 @@ func NodeRules() []rbacv1.PolicyRule {
nodePolicyRules = append(nodePolicyRules, rbacv1helpers.NewRule("get", "list", "watch").Groups("node.k8s.io").Resources("runtimeclasses").RuleOrDie())
// DRA Resource Claims
if utilfeature.DefaultFeatureGate.Enabled(features.DynamicResourceAllocation) {
nodePolicyRules = append(nodePolicyRules, rbacv1helpers.NewRule("get").Groups(resourceGroup).Resources("resourceclaims").RuleOrDie())
nodePolicyRules = append(nodePolicyRules, rbacv1helpers.NewRule("deletecollection").Groups(resourceGroup).Resources("resourceslices").RuleOrDie())
}
nodePolicyRules = append(nodePolicyRules, rbacv1helpers.NewRule("get").Groups(resourceGroup).Resources("resourceclaims").RuleOrDie())
nodePolicyRules = append(nodePolicyRules, rbacv1helpers.NewRule("deletecollection").Groups(resourceGroup).Resources("resourceslices").RuleOrDie())
// Kubelet needs access to ClusterTrustBundles to support the pemTrustAnchors volume type.
if utilfeature.DefaultFeatureGate.Enabled(features.ClusterTrustBundle) {
nodePolicyRules = append(nodePolicyRules, rbacv1helpers.NewRule("get", "list", "watch").Groups(certificatesGroup).Resources("clustertrustbundles").RuleOrDie())
@@ -658,27 +654,25 @@ func ClusterRoles() []rbacv1.ClusterRole {
rbacv1helpers.NewRule(Read...).Groups(storageGroup).Resources("csistoragecapacities").RuleOrDie(),
}
// Needed for dynamic resource allocation.
if utilfeature.DefaultFeatureGate.Enabled(features.DynamicResourceAllocation) {
kubeSchedulerRules = append(kubeSchedulerRules,
rbacv1helpers.NewRule(Read...).Groups(resourceGroup).Resources("deviceclasses").RuleOrDie(),
rbacv1helpers.NewRule(ReadUpdate...).Groups(resourceGroup).Resources("resourceclaims").RuleOrDie(),
rbacv1helpers.NewRule(ReadUpdate...).Groups(resourceGroup).Resources("resourceclaims/status").RuleOrDie(),
rbacv1helpers.NewRule("update").Groups(legacyGroup).Resources("pods/finalizers").RuleOrDie(),
rbacv1helpers.NewRule(Read...).Groups(resourceGroup).Resources("resourceslices").RuleOrDie(),
)
if utilfeature.DefaultFeatureGate.Enabled(features.DRAExtendedResource) {
kubeSchedulerRules = append(kubeSchedulerRules,
rbacv1helpers.NewRule(Read...).Groups(resourceGroup).Resources("deviceclasses").RuleOrDie(),
rbacv1helpers.NewRule(ReadUpdate...).Groups(resourceGroup).Resources("resourceclaims").RuleOrDie(),
rbacv1helpers.NewRule(ReadUpdate...).Groups(resourceGroup).Resources("resourceclaims/status").RuleOrDie(),
rbacv1helpers.NewRule("update").Groups(legacyGroup).Resources("pods/finalizers").RuleOrDie(),
rbacv1helpers.NewRule(Read...).Groups(resourceGroup).Resources("resourceslices").RuleOrDie(),
rbacv1helpers.NewRule("create", "delete").Groups(resourceGroup).Resources("resourceclaims").RuleOrDie(),
)
}
if utilfeature.DefaultFeatureGate.Enabled(features.DRADeviceTaintRules) {
kubeSchedulerRules = append(kubeSchedulerRules, rbacv1helpers.NewRule(Read...).Groups(resourceGroup).Resources("devicetaintrules").RuleOrDie())
}
if utilfeature.DefaultFeatureGate.Enabled(features.DRAResourceClaimGranularStatusAuthorization) {
kubeSchedulerRules = append(kubeSchedulerRules,
rbacv1helpers.NewRule("update", "patch").Groups(resourceGroup).Resources("resourceclaims/binding").RuleOrDie(),
)
if utilfeature.DefaultFeatureGate.Enabled(features.DRAExtendedResource) {
kubeSchedulerRules = append(kubeSchedulerRules,
rbacv1helpers.NewRule("create", "delete").Groups(resourceGroup).Resources("resourceclaims").RuleOrDie(),
)
}
if utilfeature.DefaultFeatureGate.Enabled(features.DRADeviceTaintRules) {
kubeSchedulerRules = append(kubeSchedulerRules, rbacv1helpers.NewRule(Read...).Groups(resourceGroup).Resources("devicetaintrules").RuleOrDie())
}
if utilfeature.DefaultFeatureGate.Enabled(features.DRAResourceClaimGranularStatusAuthorization) {
kubeSchedulerRules = append(kubeSchedulerRules,
rbacv1helpers.NewRule("update", "patch").Groups(resourceGroup).Resources("resourceclaims/binding").RuleOrDie(),
)
}
}
if utilfeature.DefaultFeatureGate.Enabled(features.GenericWorkload) {
kubeSchedulerRules = append(kubeSchedulerRules, rbacv1helpers.NewRule(Read...).Groups(schedulingGroup).Resources("podgroups").RuleOrDie())