From 85867e56257b47b95eff3b555e7fc250ba478f06 Mon Sep 17 00:00:00 2001 From: Xing Yang Date: Fri, 1 Mar 2019 19:14:23 -0800 Subject: [PATCH] Modify node admission and node authorizer --- plugin/pkg/admission/noderestriction/BUILD | 4 +- .../admission/noderestriction/admission.go | 26 ++++---- .../noderestriction/admission_test.go | 66 +++++++------------ plugin/pkg/auth/authorizer/node/BUILD | 1 - .../auth/authorizer/node/node_authorizer.go | 33 +++++----- .../authorizer/node/node_authorizer_test.go | 54 +++++++-------- .../rbac/bootstrappolicy/controller_policy.go | 2 +- .../authorizer/rbac/bootstrappolicy/policy.go | 6 +- .../testdata/cluster-roles.yaml | 26 ++++++++ .../testdata/controller-roles.yaml | 8 +++ 10 files changed, 120 insertions(+), 106 deletions(-) diff --git a/plugin/pkg/admission/noderestriction/BUILD b/plugin/pkg/admission/noderestriction/BUILD index 6a632ef272..bcc03b465d 100644 --- a/plugin/pkg/admission/noderestriction/BUILD +++ b/plugin/pkg/admission/noderestriction/BUILD @@ -16,6 +16,7 @@ go_library( "//pkg/apis/coordination:go_default_library", "//pkg/apis/core:go_default_library", "//pkg/apis/policy:go_default_library", + "//pkg/apis/storage:go_default_library", "//pkg/auth/nodeidentifier:go_default_library", "//pkg/features:go_default_library", "//pkg/kubelet/apis:go_default_library", @@ -30,7 +31,6 @@ go_library( "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library", "//staging/src/k8s.io/client-go/informers:go_default_library", "//staging/src/k8s.io/client-go/listers/core/v1:go_default_library", - "//staging/src/k8s.io/csi-api/pkg/apis/csi/v1alpha1:go_default_library", "//vendor/k8s.io/klog:go_default_library", ], ) @@ -44,6 +44,7 @@ go_test( "//pkg/apis/coordination:go_default_library", "//pkg/apis/core:go_default_library", "//pkg/apis/policy:go_default_library", + "//pkg/apis/storage:go_default_library", "//pkg/auth/nodeidentifier:go_default_library", "//pkg/features:go_default_library", "//pkg/kubelet/apis:go_default_library", @@ -57,7 +58,6 @@ go_test( "//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library", "//staging/src/k8s.io/client-go/listers/core/v1:go_default_library", "//staging/src/k8s.io/client-go/tools/cache:go_default_library", - "//staging/src/k8s.io/csi-api/pkg/apis/csi/v1alpha1:go_default_library", "//vendor/k8s.io/utils/pointer:go_default_library", ], ) diff --git a/plugin/pkg/admission/noderestriction/admission.go b/plugin/pkg/admission/noderestriction/admission.go index 305fdddad6..b83273e52b 100644 --- a/plugin/pkg/admission/noderestriction/admission.go +++ b/plugin/pkg/admission/noderestriction/admission.go @@ -32,13 +32,13 @@ import ( utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/client-go/informers" corev1lister "k8s.io/client-go/listers/core/v1" - csiv1alpha1 "k8s.io/csi-api/pkg/apis/csi/v1alpha1" "k8s.io/klog" podutil "k8s.io/kubernetes/pkg/api/pod" authenticationapi "k8s.io/kubernetes/pkg/apis/authentication" coordapi "k8s.io/kubernetes/pkg/apis/coordination" api "k8s.io/kubernetes/pkg/apis/core" "k8s.io/kubernetes/pkg/apis/policy" + storage "k8s.io/kubernetes/pkg/apis/storage" "k8s.io/kubernetes/pkg/auth/nodeidentifier" "k8s.io/kubernetes/pkg/features" kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis" @@ -94,12 +94,12 @@ func (p *nodePlugin) ValidateInitialization() error { } var ( - podResource = api.Resource("pods") - nodeResource = api.Resource("nodes") - pvcResource = api.Resource("persistentvolumeclaims") - svcacctResource = api.Resource("serviceaccounts") - leaseResource = coordapi.Resource("leases") - csiNodeInfoResource = csiv1alpha1.Resource("csinodeinfos") + podResource = api.Resource("pods") + nodeResource = api.Resource("nodes") + pvcResource = api.Resource("persistentvolumeclaims") + svcacctResource = api.Resource("serviceaccounts") + leaseResource = coordapi.Resource("leases") + csiNodeResource = storage.Resource("csinodes") ) func (c *nodePlugin) Admit(a admission.Attributes, o admission.ObjectInterfaces) error { @@ -151,9 +151,9 @@ func (c *nodePlugin) Admit(a admission.Attributes, o admission.ObjectInterfaces) } return admission.NewForbidden(a, fmt.Errorf("disabled by feature gate %s", features.NodeLease)) - case csiNodeInfoResource: + case csiNodeResource: if c.features.Enabled(features.KubeletPluginsWatcher) && c.features.Enabled(features.CSINodeInfo) { - return c.admitCSINodeInfo(nodeName, a) + return c.admitCSINode(nodeName, a) } return admission.NewForbidden(a, fmt.Errorf("disabled by feature gates %s and %s", features.KubeletPluginsWatcher, features.CSINodeInfo)) @@ -530,8 +530,8 @@ func (r *nodePlugin) admitLease(nodeName string, a admission.Attributes) error { return nil } -func (c *nodePlugin) admitCSINodeInfo(nodeName string, a admission.Attributes) error { - // the request must come from a node with the same name as the CSINodeInfo object +func (c *nodePlugin) admitCSINode(nodeName string, a admission.Attributes) error { + // the request must come from a node with the same name as the CSINode object if a.GetOperation() == admission.Create { // a.GetName() won't return the name on create, so we drill down to the proposed object accessor, err := meta.Accessor(a.GetObject()) @@ -539,11 +539,11 @@ func (c *nodePlugin) admitCSINodeInfo(nodeName string, a admission.Attributes) e return admission.NewForbidden(a, fmt.Errorf("unable to access the object name")) } if accessor.GetName() != nodeName { - return admission.NewForbidden(a, fmt.Errorf("can only access CSINodeInfo with the same name as the requesting node")) + return admission.NewForbidden(a, fmt.Errorf("can only access CSINode with the same name as the requesting node")) } } else { if a.GetName() != nodeName { - return admission.NewForbidden(a, fmt.Errorf("can only access CSINodeInfo with the same name as the requesting node")) + return admission.NewForbidden(a, fmt.Errorf("can only access CSINode with the same name as the requesting node")) } } diff --git a/plugin/pkg/admission/noderestriction/admission_test.go b/plugin/pkg/admission/noderestriction/admission_test.go index a81d9fa7dd..b7d998f6ee 100644 --- a/plugin/pkg/admission/noderestriction/admission_test.go +++ b/plugin/pkg/admission/noderestriction/admission_test.go @@ -33,11 +33,11 @@ import ( utilfeature "k8s.io/apiserver/pkg/util/feature" corev1lister "k8s.io/client-go/listers/core/v1" "k8s.io/client-go/tools/cache" - csiv1alpha1 "k8s.io/csi-api/pkg/apis/csi/v1alpha1" authenticationapi "k8s.io/kubernetes/pkg/apis/authentication" "k8s.io/kubernetes/pkg/apis/coordination" api "k8s.io/kubernetes/pkg/apis/core" "k8s.io/kubernetes/pkg/apis/policy" + storage "k8s.io/kubernetes/pkg/apis/storage" "k8s.io/kubernetes/pkg/auth/nodeidentifier" "k8s.io/kubernetes/pkg/features" kubeletapis "k8s.io/kubernetes/pkg/kubelet/apis" @@ -306,14 +306,14 @@ func Test_nodePlugin_Admit(t *testing.T) { }, } - csiNodeInfoResource = csiv1alpha1.Resource("csinodeinfos").WithVersion("v1alpha1") - csiNodeInfoKind = schema.GroupVersionKind{Group: "csi.storage.k8s.io", Version: "v1alpha1", Kind: "CSINodeInfo"} - nodeInfo = &csiv1alpha1.CSINodeInfo{ + csiNodeResource = storage.Resource("csinodes").WithVersion("v1beta1") + csiNodeKind = schema.GroupVersionKind{Group: "storage.k8s.io", Version: "v1beta1", Kind: "CSINode"} + nodeInfo = &storage.CSINode{ ObjectMeta: metav1.ObjectMeta{ Name: "mynode", }, - Spec: csiv1alpha1.CSINodeInfoSpec{ - Drivers: []csiv1alpha1.CSIDriverInfoSpec{ + Spec: storage.CSINodeSpec{ + Drivers: []storage.CSINodeDriver{ { Name: "com.example.csi/mydriver", NodeID: "com.example.csi/mynode", @@ -321,22 +321,13 @@ func Test_nodePlugin_Admit(t *testing.T) { }, }, }, - Status: csiv1alpha1.CSINodeInfoStatus{ - Drivers: []csiv1alpha1.CSIDriverInfoStatus{ - { - Name: "com.example.csi/mydriver", - Available: true, - VolumePluginMechanism: csiv1alpha1.VolumePluginMechanismInTree, - }, - }, - }, } - nodeInfoWrongName = &csiv1alpha1.CSINodeInfo{ + nodeInfoWrongName = &storage.CSINode{ ObjectMeta: metav1.ObjectMeta{ Name: "foo", }, - Spec: csiv1alpha1.CSINodeInfoSpec{ - Drivers: []csiv1alpha1.CSIDriverInfoSpec{ + Spec: storage.CSINodeSpec{ + Drivers: []storage.CSINodeDriver{ { Name: "com.example.csi/mydriver", NodeID: "com.example.csi/foo", @@ -344,15 +335,6 @@ func Test_nodePlugin_Admit(t *testing.T) { }, }, }, - Status: csiv1alpha1.CSINodeInfoStatus{ - Drivers: []csiv1alpha1.CSIDriverInfoStatus{ - { - Name: "com.example.csi/mydriver", - Available: true, - VolumePluginMechanism: csiv1alpha1.VolumePluginMechanismInTree, - }, - }, - }, } noExistingPodsIndex = cache.NewIndexer(cache.MetaNamespaceKeyFunc, nil) @@ -1183,46 +1165,46 @@ func Test_nodePlugin_Admit(t *testing.T) { features: leaseEnabledFeature, err: "", }, - // CSINodeInfo + // CSINode { - name: "disallowed create CSINodeInfo - feature disabled", - attributes: admission.NewAttributesRecord(nodeInfo, nil, csiNodeInfoKind, nodeInfo.Namespace, nodeInfo.Name, csiNodeInfoResource, "", admission.Create, false, mynode), + name: "disallowed create CSINode - feature disabled", + attributes: admission.NewAttributesRecord(nodeInfo, nil, csiNodeKind, nodeInfo.Namespace, nodeInfo.Name, csiNodeResource, "", admission.Create, false, mynode), features: csiNodeInfoDisabledFeature, err: fmt.Sprintf("forbidden: disabled by feature gates %s and %s", features.KubeletPluginsWatcher, features.CSINodeInfo), }, { - name: "disallowed create another node's CSINodeInfo - feature enabled", - attributes: admission.NewAttributesRecord(nodeInfoWrongName, nil, csiNodeInfoKind, nodeInfoWrongName.Namespace, nodeInfoWrongName.Name, csiNodeInfoResource, "", admission.Create, false, mynode), + name: "disallowed create another node's CSINode - feature enabled", + attributes: admission.NewAttributesRecord(nodeInfoWrongName, nil, csiNodeKind, nodeInfoWrongName.Namespace, nodeInfoWrongName.Name, csiNodeResource, "", admission.Create, false, mynode), features: csiNodeInfoEnabledFeature, err: "forbidden: ", }, { - name: "disallowed update another node's CSINodeInfo - feature enabled", - attributes: admission.NewAttributesRecord(nodeInfoWrongName, nodeInfoWrongName, csiNodeInfoKind, nodeInfoWrongName.Namespace, nodeInfoWrongName.Name, csiNodeInfoResource, "", admission.Update, false, mynode), + name: "disallowed update another node's CSINode - feature enabled", + attributes: admission.NewAttributesRecord(nodeInfoWrongName, nodeInfoWrongName, csiNodeKind, nodeInfoWrongName.Namespace, nodeInfoWrongName.Name, csiNodeResource, "", admission.Update, false, mynode), features: csiNodeInfoEnabledFeature, err: "forbidden: ", }, { - name: "disallowed delete another node's CSINodeInfo - feature enabled", - attributes: admission.NewAttributesRecord(nil, nil, csiNodeInfoKind, nodeInfoWrongName.Namespace, nodeInfoWrongName.Name, csiNodeInfoResource, "", admission.Delete, false, mynode), + name: "disallowed delete another node's CSINode - feature enabled", + attributes: admission.NewAttributesRecord(nil, nil, csiNodeKind, nodeInfoWrongName.Namespace, nodeInfoWrongName.Name, csiNodeResource, "", admission.Delete, false, mynode), features: csiNodeInfoEnabledFeature, err: "forbidden: ", }, { - name: "allowed create node CSINodeInfo - feature enabled", - attributes: admission.NewAttributesRecord(nodeInfo, nil, csiNodeInfoKind, nodeInfo.Namespace, nodeInfo.Name, csiNodeInfoResource, "", admission.Create, false, mynode), + name: "allowed create node CSINode - feature enabled", + attributes: admission.NewAttributesRecord(nodeInfo, nil, csiNodeKind, nodeInfo.Namespace, nodeInfo.Name, csiNodeResource, "", admission.Create, false, mynode), features: csiNodeInfoEnabledFeature, err: "", }, { - name: "allowed update node CSINodeInfo - feature enabled", - attributes: admission.NewAttributesRecord(nodeInfo, nodeInfo, csiNodeInfoKind, nodeInfo.Namespace, nodeInfo.Name, csiNodeInfoResource, "", admission.Update, false, mynode), + name: "allowed update node CSINode - feature enabled", + attributes: admission.NewAttributesRecord(nodeInfo, nodeInfo, csiNodeKind, nodeInfo.Namespace, nodeInfo.Name, csiNodeResource, "", admission.Update, false, mynode), features: csiNodeInfoEnabledFeature, err: "", }, { - name: "allowed delete node CSINodeInfo - feature enabled", - attributes: admission.NewAttributesRecord(nil, nil, csiNodeInfoKind, nodeInfo.Namespace, nodeInfo.Name, csiNodeInfoResource, "", admission.Delete, false, mynode), + name: "allowed delete node CSINode - feature enabled", + attributes: admission.NewAttributesRecord(nil, nil, csiNodeKind, nodeInfo.Namespace, nodeInfo.Name, csiNodeResource, "", admission.Delete, false, mynode), features: csiNodeInfoEnabledFeature, err: "", }, diff --git a/plugin/pkg/auth/authorizer/node/BUILD b/plugin/pkg/auth/authorizer/node/BUILD index 4e171b31a4..39ae2624b6 100644 --- a/plugin/pkg/auth/authorizer/node/BUILD +++ b/plugin/pkg/auth/authorizer/node/BUILD @@ -56,7 +56,6 @@ go_library( "//staging/src/k8s.io/client-go/informers/core/v1:go_default_library", "//staging/src/k8s.io/client-go/informers/storage/v1:go_default_library", "//staging/src/k8s.io/client-go/tools/cache:go_default_library", - "//staging/src/k8s.io/csi-api/pkg/apis/csi/v1alpha1:go_default_library", "//third_party/forked/gonum/graph:go_default_library", "//third_party/forked/gonum/graph/simple:go_default_library", "//third_party/forked/gonum/graph/traverse:go_default_library", diff --git a/plugin/pkg/auth/authorizer/node/node_authorizer.go b/plugin/pkg/auth/authorizer/node/node_authorizer.go index 1e541ee22a..b0f49c12fa 100644 --- a/plugin/pkg/auth/authorizer/node/node_authorizer.go +++ b/plugin/pkg/auth/authorizer/node/node_authorizer.go @@ -25,7 +25,6 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/apiserver/pkg/authorization/authorizer" utilfeature "k8s.io/apiserver/pkg/util/feature" - csiv1alpha1 "k8s.io/csi-api/pkg/apis/csi/v1alpha1" coordapi "k8s.io/kubernetes/pkg/apis/coordination" api "k8s.io/kubernetes/pkg/apis/core" storageapi "k8s.io/kubernetes/pkg/apis/storage" @@ -68,14 +67,14 @@ func NewAuthorizer(graph *Graph, identifier nodeidentifier.NodeIdentifier, rules } var ( - configMapResource = api.Resource("configmaps") - secretResource = api.Resource("secrets") - pvcResource = api.Resource("persistentvolumeclaims") - pvResource = api.Resource("persistentvolumes") - vaResource = storageapi.Resource("volumeattachments") - svcAcctResource = api.Resource("serviceaccounts") - leaseResource = coordapi.Resource("leases") - csiNodeInfoResource = csiv1alpha1.Resource("csinodeinfos") + configMapResource = api.Resource("configmaps") + secretResource = api.Resource("secrets") + pvcResource = api.Resource("persistentvolumeclaims") + pvResource = api.Resource("persistentvolumes") + vaResource = storageapi.Resource("volumeattachments") + svcAcctResource = api.Resource("serviceaccounts") + leaseResource = coordapi.Resource("leases") + csiNodeResource = storageapi.Resource("csinodes") ) func (r *NodeAuthorizer) Authorize(attrs authorizer.Attributes) (authorizer.Decision, string, error) { @@ -122,9 +121,9 @@ func (r *NodeAuthorizer) Authorize(attrs authorizer.Attributes) (authorizer.Deci return r.authorizeLease(nodeName, attrs) } return authorizer.DecisionNoOpinion, fmt.Sprintf("disabled by feature gate %s", features.NodeLease), nil - case csiNodeInfoResource: + case csiNodeResource: if r.features.Enabled(features.KubeletPluginsWatcher) && r.features.Enabled(features.CSINodeInfo) { - return r.authorizeCSINodeInfo(nodeName, attrs) + return r.authorizeCSINode(nodeName, attrs) } return authorizer.DecisionNoOpinion, fmt.Sprintf("disabled by feature gates %s and %s", features.KubeletPluginsWatcher, features.CSINodeInfo), nil } @@ -260,8 +259,8 @@ func (r *NodeAuthorizer) authorizeLease(nodeName string, attrs authorizer.Attrib return authorizer.DecisionAllow, "", nil } -// authorizeCSINodeInfo authorizes node requests to CSINodeInfo csi.storage.k8s.io/csinodeinfos -func (r *NodeAuthorizer) authorizeCSINodeInfo(nodeName string, attrs authorizer.Attributes) (authorizer.Decision, string, error) { +// authorizeCSINode authorizes node requests to CSINode storage.k8s.io/csinodes +func (r *NodeAuthorizer) authorizeCSINode(nodeName string, attrs authorizer.Attributes) (authorizer.Decision, string, error) { // allowed verbs: get, create, update, patch, delete verb := attrs.GetVerb() if verb != "get" && @@ -270,20 +269,20 @@ func (r *NodeAuthorizer) authorizeCSINodeInfo(nodeName string, attrs authorizer. verb != "patch" && verb != "delete" { klog.V(2).Infof("NODE DENY: %s %#v", nodeName, attrs) - return authorizer.DecisionNoOpinion, "can only get, create, update, patch, or delete a CSINodeInfo", nil + return authorizer.DecisionNoOpinion, "can only get, create, update, patch, or delete a CSINode", nil } if len(attrs.GetSubresource()) > 0 { klog.V(2).Infof("NODE DENY: %s %#v", nodeName, attrs) - return authorizer.DecisionNoOpinion, "cannot authorize CSINodeInfo subresources", nil + return authorizer.DecisionNoOpinion, "cannot authorize CSINode subresources", nil } - // the request must come from a node with the same name as the CSINodeInfo + // the request must come from a node with the same name as the CSINode // note we skip this check for create, since the authorizer doesn't know the name on create // the noderestriction admission plugin is capable of performing this check at create time if verb != "create" && attrs.GetName() != nodeName { klog.V(2).Infof("NODE DENY: %s %#v", nodeName, attrs) - return authorizer.DecisionNoOpinion, "can only access CSINodeInfo with the same name as the requesting node", nil + return authorizer.DecisionNoOpinion, "can only access CSINode with the same name as the requesting node", nil } return authorizer.DecisionAllow, "", nil diff --git a/plugin/pkg/auth/authorizer/node/node_authorizer_test.go b/plugin/pkg/auth/authorizer/node/node_authorizer_test.go index e7b318026d..afe1bdaf02 100644 --- a/plugin/pkg/auth/authorizer/node/node_authorizer_test.go +++ b/plugin/pkg/auth/authorizer/node/node_authorizer_test.go @@ -352,82 +352,82 @@ func TestAuthorizer(t *testing.T) { features: leaseEnabledFeature, expect: authorizer.DecisionAllow, }, - // CSINodeInfo + // CSINode { - name: "disallowed CSINodeInfo - feature disabled", - attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "csinodeinfos", APIGroup: "csi.storage.k8s.io", Name: "node0"}, + name: "disallowed CSINode - feature disabled", + attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "csinodes", APIGroup: "storage.k8s.io", Name: "node0"}, features: csiNodeInfoDisabledFeature, expect: authorizer.DecisionNoOpinion, }, { - name: "disallowed CSINodeInfo with subresource - feature enabled", - attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "csinodeinfos", Subresource: "csiDrivers", APIGroup: "csi.storage.k8s.io", Name: "node0"}, + name: "disallowed CSINode with subresource - feature enabled", + attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "csinodes", Subresource: "csiDrivers", APIGroup: "storage.k8s.io", Name: "node0"}, features: csiNodeInfoEnabledFeature, expect: authorizer.DecisionNoOpinion, }, { - name: "disallowed get another node's CSINodeInfo - feature enabled", - attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "csinodeinfos", APIGroup: "csi.storage.k8s.io", Name: "node1"}, + name: "disallowed get another node's CSINode - feature enabled", + attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "csinodes", APIGroup: "storage.k8s.io", Name: "node1"}, features: csiNodeInfoEnabledFeature, expect: authorizer.DecisionNoOpinion, }, { - name: "disallowed update another node's CSINodeInfo - feature enabled", - attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "update", Resource: "csinodeinfos", APIGroup: "csi.storage.k8s.io", Name: "node1"}, + name: "disallowed update another node's CSINode - feature enabled", + attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "update", Resource: "csinodes", APIGroup: "storage.k8s.io", Name: "node1"}, features: csiNodeInfoEnabledFeature, expect: authorizer.DecisionNoOpinion, }, { - name: "disallowed patch another node's CSINodeInfo - feature enabled", - attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "patch", Resource: "csinodeinfos", APIGroup: "csi.storage.k8s.io", Name: "node1"}, + name: "disallowed patch another node's CSINode - feature enabled", + attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "patch", Resource: "csinodes", APIGroup: "storage.k8s.io", Name: "node1"}, features: csiNodeInfoEnabledFeature, expect: authorizer.DecisionNoOpinion, }, { - name: "disallowed delete another node's CSINodeInfo - feature enabled", - attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "delete", Resource: "csinodeinfos", APIGroup: "csi.storage.k8s.io", Name: "node1"}, + name: "disallowed delete another node's CSINode - feature enabled", + attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "delete", Resource: "csinodes", APIGroup: "storage.k8s.io", Name: "node1"}, features: csiNodeInfoEnabledFeature, expect: authorizer.DecisionNoOpinion, }, { - name: "disallowed list CSINodeInfos - feature enabled", - attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "list", Resource: "csinodeinfos", APIGroup: "csi.storage.k8s.io"}, + name: "disallowed list CSINodes - feature enabled", + attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "list", Resource: "csinodes", APIGroup: "storage.k8s.io"}, features: csiNodeInfoEnabledFeature, expect: authorizer.DecisionNoOpinion, }, { - name: "disallowed watch CSINodeInfos - feature enabled", - attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "watch", Resource: "csinodeinfos", APIGroup: "csi.storage.k8s.io"}, + name: "disallowed watch CSINodes - feature enabled", + attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "watch", Resource: "csinodes", APIGroup: "storage.k8s.io"}, features: csiNodeInfoEnabledFeature, expect: authorizer.DecisionNoOpinion, }, { - name: "allowed get CSINodeInfo - feature enabled", - attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "csinodeinfos", APIGroup: "csi.storage.k8s.io", Name: "node0"}, + name: "allowed get CSINode - feature enabled", + attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "csinodes", APIGroup: "storage.k8s.io", Name: "node0"}, features: csiNodeInfoEnabledFeature, expect: authorizer.DecisionAllow, }, { - name: "allowed create CSINodeInfo - feature enabled", - attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "create", Resource: "csinodeinfos", APIGroup: "csi.storage.k8s.io", Name: "node0"}, + name: "allowed create CSINode - feature enabled", + attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "create", Resource: "csinodes", APIGroup: "storage.k8s.io", Name: "node0"}, features: csiNodeInfoEnabledFeature, expect: authorizer.DecisionAllow, }, { - name: "allowed update CSINodeInfo - feature enabled", - attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "update", Resource: "csinodeinfos", APIGroup: "csi.storage.k8s.io", Name: "node0"}, + name: "allowed update CSINode - feature enabled", + attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "update", Resource: "csinodes", APIGroup: "storage.k8s.io", Name: "node0"}, features: csiNodeInfoEnabledFeature, expect: authorizer.DecisionAllow, }, { - name: "allowed patch CSINodeInfo - feature enabled", - attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "patch", Resource: "csinodeinfos", APIGroup: "csi.storage.k8s.io", Name: "node0"}, + name: "allowed patch CSINode - feature enabled", + attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "patch", Resource: "csinodes", APIGroup: "storage.k8s.io", Name: "node0"}, features: csiNodeInfoEnabledFeature, expect: authorizer.DecisionAllow, }, { - name: "allowed delete CSINodeInfo - feature enabled", - attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "delete", Resource: "csinodeinfos", APIGroup: "csi.storage.k8s.io", Name: "node0"}, + name: "allowed delete CSINode - feature enabled", + attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "delete", Resource: "csinodes", APIGroup: "storage.k8s.io", Name: "node0"}, features: csiNodeInfoEnabledFeature, expect: authorizer.DecisionAllow, }, diff --git a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/controller_policy.go b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/controller_policy.go index 71485bc986..c409ae8fd9 100644 --- a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/controller_policy.go +++ b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/controller_policy.go @@ -74,7 +74,7 @@ func buildControllerRoles() ([]rbacv1.ClusterRole, []rbacv1.ClusterRoleBinding) if utilfeature.DefaultFeatureGate.Enabled(features.CSIPersistentVolume) { role.Rules = append(role.Rules, rbacv1helpers.NewRule("get", "create", "delete", "list", "watch").Groups(storageGroup).Resources("volumeattachments").RuleOrDie()) if utilfeature.DefaultFeatureGate.Enabled(features.CSIDriverRegistry) { - role.Rules = append(role.Rules, rbacv1helpers.NewRule("get", "watch", "list").Groups("csi.storage.k8s.io").Resources("csidrivers").RuleOrDie()) + role.Rules = append(role.Rules, rbacv1helpers.NewRule("get", "watch", "list").Groups("storage.k8s.io").Resources("csidrivers").RuleOrDie()) } } diff --git a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/policy.go b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/policy.go index dff7498909..812f4b5ee5 100644 --- a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/policy.go +++ b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/policy.go @@ -160,13 +160,13 @@ func NodeRules() []rbacv1.PolicyRule { volAttachRule := rbacv1helpers.NewRule("get").Groups(storageGroup).Resources("volumeattachments").RuleOrDie() nodePolicyRules = append(nodePolicyRules, volAttachRule) if utilfeature.DefaultFeatureGate.Enabled(features.CSIDriverRegistry) { - csiDriverRule := rbacv1helpers.NewRule("get", "watch", "list").Groups("csi.storage.k8s.io").Resources("csidrivers").RuleOrDie() + csiDriverRule := rbacv1helpers.NewRule("get", "watch", "list").Groups("storage.k8s.io").Resources("csidrivers").RuleOrDie() nodePolicyRules = append(nodePolicyRules, csiDriverRule) } } if utilfeature.DefaultFeatureGate.Enabled(features.KubeletPluginsWatcher) && utilfeature.DefaultFeatureGate.Enabled(features.CSINodeInfo) { - csiNodeInfoRule := rbacv1helpers.NewRule("get", "create", "update", "patch", "delete").Groups("csi.storage.k8s.io").Resources("csinodeinfos").RuleOrDie() + csiNodeInfoRule := rbacv1helpers.NewRule("get", "create", "update", "patch", "delete").Groups("storage.k8s.io").Resources("csinodes").RuleOrDie() nodePolicyRules = append(nodePolicyRules, csiNodeInfoRule) } @@ -514,7 +514,7 @@ func ClusterRoles() []rbacv1.ClusterRole { rbacv1helpers.NewRule("get", "list", "watch").Groups(legacyGroup).Resources("nodes").RuleOrDie(), } if utilfeature.DefaultFeatureGate.Enabled(features.CSINodeInfo) { - externalProvisionerRules = append(externalProvisionerRules, rbacv1helpers.NewRule("get", "watch", "list").Groups("csi.storage.k8s.io").Resources("csinodeinfos").RuleOrDie()) + externalProvisionerRules = append(externalProvisionerRules, rbacv1helpers.NewRule("get", "watch", "list").Groups("storage.k8s.io").Resources("csinodes").RuleOrDie()) } roles = append(roles, rbacv1.ClusterRole{ // a role for the csi external provisioner diff --git a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/testdata/cluster-roles.yaml b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/testdata/cluster-roles.yaml index 6e45a9efff..5603831871 100644 --- a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/testdata/cluster-roles.yaml +++ b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/testdata/cluster-roles.yaml @@ -532,6 +532,14 @@ items: - get - list - watch + - apiGroups: + - storage.k8s.io + resources: + - csinodes + verbs: + - get + - list + - watch - apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: @@ -985,6 +993,24 @@ items: - volumeattachments verbs: - get + - apiGroups: + - storage.k8s.io + resources: + - csidrivers + verbs: + - get + - list + - watch + - apiGroups: + - storage.k8s.io + resources: + - csinodes + verbs: + - create + - delete + - get + - patch + - update - apiGroups: - coordination.k8s.io resources: diff --git a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/testdata/controller-roles.yaml b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/testdata/controller-roles.yaml index 3344def7c2..2c64f63a96 100644 --- a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/testdata/controller-roles.yaml +++ b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/testdata/controller-roles.yaml @@ -58,6 +58,14 @@ items: - get - list - watch + - apiGroups: + - storage.k8s.io + resources: + - csidrivers + verbs: + - get + - list + - watch - apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: