mirror of
https://github.com/kubernetes/kubernetes.git
synced 2026-11-06 05:17:08 +00:00
controllers, auth, quota: make Dynamic Resource Allocation unconditional
This commit is contained in:
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
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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())
|
||||
|
||||
Reference in new issue
Block a user