jiebi/CodeConvo huggingface dataset:
assert.Equal(t, http.StatusOK, resp.StatusCode) } <ins> func TestTrimURLPath(t *testing.T) { tests := []struct { path, expected string }{ {"", ""}, {"//", ""}, {"/pods", "pods"}, {"pods", "pods"}, {"pods/", "pods"}, {"good/", "good"}, {"pods/probes", "pods"}, {"metrics", "metrics"}, {"metrics/resource", "metrics/resource"}, {"metrics/hello", "metrics/hello"}, } for _, test := range tests { assert.Equal(t, test.expected, trimURLPath(test.path), fmt.Sprintf("path is: %s", test.path)) } } </ins>
pod:           getPod("foo", "", "", "10Mi", "100Mi"), expectedValue: "104857600", }, <ins> { fs: &v1.ResourceFieldSelector{ Resource: "limits.cpu", }, cName:         "init-foo", pod:           getPod("foo", "", "9", "", ""), expectedValue: "9", }, { fs: &v1.ResourceFieldSelector{ Resource: "requests.cpu", }, cName:         "init-foo", pod:           getPod("foo", "", "", "", ""), expectedValue: "0", }, { fs: &v1.ResourceFieldSelector{ Resource: "requests.cpu", }, cName:         "init-foo", pod:           getPod("foo", "8", "", "", ""), expectedValue: "8", }, { fs: &v1.ResourceFieldSelector{ Resource: "requests.cpu", }, cName:         "init-foo", pod:           getPod("foo", "100m", "", "", ""), expectedValue: "1", }, { fs: &v1.ResourceFieldSelector{ Resource: "requests.cpu", Divisor:  resource.MustParse("100m"), }, cName:         "init-foo", pod:           getPod("foo", "1200m", "", "", ""), expectedValue: "12", }, { fs: &v1.ResourceFieldSelector{ Resource: "requests.memory", }, cName:         "init-foo", pod:           getPod("foo", "", "", "100Mi", ""), expectedValue: "104857600", }, { fs: &v1.ResourceFieldSelector{ Resource: "requests.memory", Divisor:  resource.MustParse("1Mi"), }, cName:         "init-foo", pod:           getPod("foo", "", "", "100Mi", "1Gi"), expectedValue: "100", }, { fs: &v1.ResourceFieldSelector{ Resource: "limits.memory", }, cName:         "init-foo", pod:           getPod("foo", "", "", "10Mi", "100Mi"), expectedValue: "104857600", }, </ins> } as := assert.New(t) for idx, tc := range cases {
// BusyBoxImage is the image URI of BusyBox. BusyBoxImage = imageutils.GetE2EImage(imageutils.BusyBox) <ins> // AgnHostImage is the image URI of AgnHost AgnHostImage = imageutils.GetE2EImage(imageutils.Agnhost) </ins> // For parsing Kubectl version for version-skewed testing. gitVersionRegexp = regexp.MustCompile("GitVersion:"(v.+?)"")
} } <del> // PingCommand is the type to hold ping command. type PingCommand string const ( // IPv4PingCommand is a ping command for IPv4. IPv4PingCommand PingCommand = "ping" // IPv6PingCommand is a ping command for IPv6. IPv6PingCommand PingCommand = "ping6" ) </del> // CheckConnectivityToHost launches a pod to test connectivity to the specified // host. An error will be returned if the host is not reachable from the pod. // // An empty nodeName will use the schedule to choose where the pod is executed. <del> func CheckConnectivityToHost(f *Framework, nodeName, podName, host string, pingCmd PingCommand, timeout int) error { </del> <ins> func CheckConnectivityToHost(f *Framework, nodeName, podName, host string, port, timeout int) error { </ins> contName := fmt.Sprintf("%s-container", podName) command := []string{ <del> string(pingCmd), "-c", "3", // send 3 pings "-W", "2", // wait at most 2 seconds for a reply </del> <ins> "nc", "-vz", </ins> "-w", strconv.Itoa(timeout), host, <ins> strconv.Itoa(port), </ins> } pod := &v1.Pod{
}) ginkgo.It("should provide Internet connection for containers [Feature:Networking-IPv4]", func() { <del> ginkgo.By("Running container which tries to ping 8.8.8.8") </del> <ins> ginkgo.By("Running container which tries to connect to 8.8.8.8") </ins> framework.ExpectNoError( <del> framework.CheckConnectivityToHost(f, "", "ping-test", "8.8.8.8", framework.IPv4PingCommand, 30)) </del> <ins> framework.CheckConnectivityToHost(f, "", "connectivity-test", "8.8.8.8", 53, 30)) </ins> }) ginkgo.It("should provide Internet connection for containers [Feature:Networking-IPv6][Experimental]", func() { <del> ginkgo.By("Running container which tries to ping 2001:4860:4860::8888") </del> <ins> ginkgo.By("Running container which tries to connect to 2001:4860:4860::8888") </ins> framework.ExpectNoError( <del> framework.CheckConnectivityToHost(f, "", "ping-test", "2001:4860:4860::8888", framework.IPv6PingCommand, 30)) </del> <ins> framework.CheckConnectivityToHost(f, "", "connectivity-test", "2001:4860:4860::8888", 53, 30)) </ins> }) // First test because it has no dependencies on variables created later on.
fs.BoolVar(&o.CleanupAndExit, "cleanup-iptables", o.CleanupAndExit, "If true cleanup iptables and ipvs rules and exit.") fs.MarkDeprecated("cleanup-iptables", "This flag is replaced by --cleanup.") fs.BoolVar(&o.CleanupAndExit, "cleanup", o.CleanupAndExit, "If true cleanup iptables and ipvs rules and exit.") <del> fs.BoolVar(&o.CleanupIPVS, "cleanup-ipvs", o.CleanupIPVS, "If true make kube-proxy cleanup ipvs rules before running.  Default is true") </del> <ins> fs.BoolVar(&o.CleanupIPVS, "cleanup-ipvs", o.CleanupIPVS, "If true and --cleanup is specified, kube-proxy will also flush IPVS rules, in addition to normal cleanup.") </ins> // All flags below here are deprecated and will eventually be removed.
// NewProxyServer returns a new ProxyServer. func NewProxyServer(o *Options) (*ProxyServer, error) { <del> return newProxyServer(o.config, o.CleanupAndExit, o.CleanupIPVS, o.scheme, o.master) </del> <ins> return newProxyServer(o.config, o.CleanupAndExit, o.scheme, o.master) </ins> } func newProxyServer( config *proxyconfigapi.KubeProxyConfiguration, cleanupAndExit bool, <del> cleanupIPVS bool, </del> scheme *runtime.Scheme, master string) (*ProxyServer, error) {
proxier = proxierIPTables serviceEventHandler = proxierIPTables endpointsEventHandler = proxierIPTables <del> // No turning back. Remove artifacts that might still exist from the userspace Proxier. klog.V(0).Info("Tearing down inactive rules.") // TODO this has side effects that should only happen when Run() is invoked. userspace.CleanupLeftovers(iptInterface) // IPVS Proxier will generate some iptables rules, need to clean them before switching to other proxy mode. // Besides, ipvs proxier will create some ipvs rules as well.  Because there is no way to tell if a given // ipvs rule is created by IPVS proxier or not.  Users should explicitly specify `--clean-ipvs=true` to flush // all ipvs rules when kube-proxy start up.  Users do this operation should be with caution. if canUseIPVS { ipvs.CleanupLeftovers(ipvsInterface, iptInterface, ipsetInterface, cleanupIPVS) } </del> } else if proxyMode == proxyModeIPVS { klog.V(0).Info("Using ipvs Proxier.") proxierIPVS, err := ipvs.NewProxier(
proxier = proxierIPVS serviceEventHandler = proxierIPVS endpointsEventHandler = proxierIPVS <del> klog.V(0).Info("Tearing down inactive rules.") // TODO this has side effects that should only happen when Run() is invoked. userspace.CleanupLeftovers(iptInterface) iptables.CleanupLeftovers(iptInterface) </del> } else { klog.V(0).Info("Using userspace Proxier.") // This is a proxy.LoadBalancer which NewProxier needs but has methods we don't need for
} serviceEventHandler = proxierUserspace proxier = proxierUserspace <del> // Remove artifacts from the iptables and ipvs Proxier, if not on Windows. klog.V(0).Info("Tearing down inactive rules.") // TODO this has side effects that should only happen when Run() is invoked. iptables.CleanupLeftovers(iptInterface) // IPVS Proxier will generate some iptables rules, need to clean them before switching to other proxy mode. // Besides, ipvs proxier will create some ipvs rules as well.  Because there is no way to tell if a given // ipvs rule is created by IPVS proxier or not.  Users should explicitly specify `--clean-ipvs=true` to flush // all ipvs rules when kube-proxy start up.  Users do this operation should be with caution. if canUseIPVS { ipvs.CleanupLeftovers(ipvsInterface, iptInterface, ipsetInterface, cleanupIPVS) } </del> } iptInterface.AddReloadFunc(proxier.Sync)
"testing" ) <del> func TestLoopbackHostPort(t *testing.T) { </del> <ins> func TestLoopbackHostPortIPv4(t *testing.T) { _, ipv6only, err := isIPv6LoopbackSupported() if err != nil { t.Fatalf("fail to enumerate network interface, %s", err) } if ipv6only { t.Fatalf("no ipv4 loopback interface") } </ins> host, port, err := LoopbackHostPort("1.2.3.4:443") if err != nil { t.Fatalf("unexpected error: %v", err)
if port != "443" { t.Fatalf("expected 443 as port, got %q", port) } <ins> } func TestLoopbackHostPortIPv6(t *testing.T) { ipv6, _, err := isIPv6LoopbackSupported() if err != nil { t.Fatalf("fail to enumerate network interface, %s", err) } if !ipv6 { t.Fatalf("no ipv6 loopback interface") } </ins> <del> host, port, err = LoopbackHostPort("[ff06:0:0:0:0:0:0:c3]:443") </del> <ins> host, port, err := LoopbackHostPort("[ff06:0:0:0:0:0:0:c3]:443") </ins> if err != nil { t.Fatalf("unexpected error: %v", err) }
if ip := net.ParseIP(host); ip == nil || !ip.IsLoopback() || ip.To4() != nil { t.Fatalf("expected IPv6 host to be loopback, got %q", host) } if port != "443" { t.Fatalf("expected 443 as port, got %q", port) } } <ins> func isIPv6LoopbackSupported() (ipv6 bool, ipv6only bool, err error) { addrs, err := net.InterfaceAddrs() if err != nil { return false, false, err } ipv4 := false for _, address := range addrs { ipnet, ok := address.(*net.IPNet) if !ok || !ipnet.IP.IsLoopback() { continue } if ipnet.IP.To4() == nil { ipv6 = true continue } ipv4 = true } ipv6only = ipv6 && !ipv4 return ipv6, ipv6only, nil } </ins>
// Proxier implements ProxyProvider var _ proxy.ProxyProvider = &Proxier{} <ins> // ParseExcludedCIDRs parses the input strings and returns net.IPNet // The validation has been done earlier so the error condition will never happen under normal conditions func ParseExcludedCIDRs(excludeCIDRStrs []string) []*net.IPNet { var cidrExclusions []*net.IPNet for _, excludedCIDR := range excludeCIDRStrs { _, n, err := net.ParseCIDR(excludedCIDR) if err == nil { cidrExclusions = append(cidrExclusions, n) } } return cidrExclusions } </ins> // NewProxier returns a new Proxier given an iptables and ipvs Interface instance. // Because of the iptables and ipvs logic, it is assumed that there is only a single Proxier active on a machine. // An error will be returned if it fails to update or acquire the initial lock.
endpointsChanges:      proxy.NewEndpointChangeTracker(hostname, nil, &isIPv6, recorder), syncPeriod:            syncPeriod, minSyncPeriod:         minSyncPeriod, <del> excludeCIDRs:          excludeCIDRs, </del> <ins> excludeCIDRs:          ParseExcludedCIDRs(excludeCIDRStrs), </ins> iptables:              ipt, masqueradeAll:         masqueradeAll, masqueradeMark:        masqueradeMark,
func (proxier *Proxier) isIPInExcludeCIDRs(ip net.IP) bool { // make sure it does not fall within an excluded CIDR range. for _, excludedCIDR := range proxier.excludeCIDRs { <del> // Any validation of this CIDR already should have occurred. _, n, _ := net.ParseCIDR(excludedCIDR) if n.Contains(ip) { </del> <ins> if excludedCIDR.Contains(ip) { </ins> return true } }
return nil } <del> func NewFakeProxier(ipt utiliptables.Interface, ipvs utilipvs.Interface, ipset utilipset.Interface, nodeIPs []net.IP, excludeCIDRs []string) *Proxier { </del> <ins> func NewFakeProxier(ipt utiliptables.Interface, ipvs utilipvs.Interface, ipset utilipset.Interface, nodeIPs []net.IP, excludeCIDRs []*net.IPNet) *Proxier { </ins> fcmd := fakeexec.FakeCmd{ CombinedOutputScript: []fakeexec.FakeCombinedOutputAction{ func() ([]byte, error) { return []byte("dummy device have been created"), nil },
ipt := iptablestest.NewFake() ipvs := ipvstest.NewFake() ipset := ipsettest.NewFake(testIPSetVersion) <del> fp := NewFakeProxier(ipt, ipvs, ipset, nil, []string{"3.3.3.0/24", "4.4.4.0/24"}) </del> <ins> fp := NewFakeProxier(ipt, ipvs, ipset, nil, ParseExcludedCIDRs([]string{"3.3.3.0/24", "4.4.4.0/24"})) </ins> // All ipvs services that were processed in the latest sync loop. activeServices := map[string]bool{"ipvs0": true, "ipvs1": true}
ipvs := ipvstest.NewFake() ipset := ipsettest.NewFake(testIPSetVersion) gtm := NewGracefulTerminationManager(ipvs) <del> fp := NewFakeProxier(ipt, ipvs, ipset, nil, []string{"4.4.4.4/32"}) </del> <ins> fp := NewFakeProxier(ipt, ipvs, ipset, nil, ParseExcludedCIDRs([]string{"4.4.4.4/32"})) </ins> fp.gracefuldeleteManager = gtm vs := &utilipvs.VirtualServer{
ipt := iptablestest.NewFake() ipvs := ipvstest.NewFake() ipset := ipsettest.NewFake(testIPSetVersion) <del> fp := NewFakeProxier(ipt, ipvs, ipset, nil, []string{"3000::/64", "4000::/64"}) </del> <ins> fp := NewFakeProxier(ipt, ipvs, ipset, nil, ParseExcludedCIDRs([]string{"3000::/64", "4000::/64"})) </ins> fp.nodeIP = net.ParseIP("::1") // All ipvs services that were processed in the latest sync loop.
} for _, rs := range rss { if rsToDelete.RealServer.Equal(rs) { <del> // Delete RS with no connections // For UDP, ActiveConn is always 0 // For TCP, InactiveConn are connections not in ESTABLISHED state if rs.ActiveConn+rs.InactiveConn != 0 { </del> <ins> // For UDP traffic, no graceful termination, we immediately delete the RS //     (existing connections will be deleted on the next packet because sysctlExpireNoDestConn=1) // For other protocols, don't delete until all connections have expired) if rsToDelete.VirtualServer.Protocol != "udp" && rs.ActiveConn+rs.InactiveConn != 0 { </ins> klog.Infof("Not deleting, RS %v: %v ActiveConn, %v InactiveConn", rsToDelete.String(), rs.ActiveConn, rs.InactiveConn) return false, nil }
IFS=" " read -ra KUBE_TEST_SERVER_TARGETS <<< "$(kube::golang::server_test_targets)" readonly KUBE_TEST_SERVER_TARGETS readonly KUBE_TEST_SERVER_BINARIES=("${KUBE_TEST_SERVER_TARGETS[@]##*/}") <del> readonly KUBE_TEST_SERVER_PLATFORMS=("${KUBE_SERVER_PLATFORMS[@]}") </del> <ins> readonly KUBE_TEST_SERVER_PLATFORMS=("${KUBE_SERVER_PLATFORMS[@]:+"${KUBE_SERVER_PLATFORMS[@]}"}") </ins> # Gigabytes necessary for parallel platform builds. # As of January 2018, RAM usage is exceeding 30G
e2elog.Logf("kube-apiserver version: %s", serverVersion.GitVersion) } <ins> // Obtain the default IP family of the cluster // Some e2e test are designed to work on IPv4 only, this global variable // allows to adapt those tests to work on both IPv4 and IPv6 // TODO(dual-stack): dual stack clusters should pass full e2e testing at least with the primary IP family // the dual stack clusters can be ipv4-ipv6 or ipv6-ipv4, order matters, // and services use the primary IP family by default // If we´ll need to provide additional context for dual-stack, we can detect it // because pods have two addresses (one per family) framework.TestContext.IPFamily = getDefaultClusterIPFamily(c) e2elog.Logf("Cluster IP family: %s", framework.TestContext.IPFamily) </ins> // Reference common test to make the import valid. commontest.CurrentSuite = commontest.E2E
e2elog.Logf("Output of clusterapi-tester:n%v", logs) } } <ins> // getDefaultClusterIPFamily obtains the default IP family of the cluster // using the Cluster IP address of the kubernetes service created in the default namespace // This unequivocally identifies the default IP family because services are single family func getDefaultClusterIPFamily(c clientset.Interface) string { // Get the ClusterIP of the kubernetes service created in the default namespace svc, err := c.CoreV1().Services(metav1.NamespaceDefault).Get("kubernetes", metav1.GetOptions{}) if err != nil { e2elog.Failf("Failed to get kubernetes service ClusterIP: %v", err) } if utilnet.IsIPv6String(svc.Spec.ClusterIP) { return "ipv6" } return "ipv4" } </ins>
"time" "github.com/onsi/ginkgo" <del> "k8s.io/api/core/v1" </del> <ins> v1 "k8s.io/api/core/v1" </ins> metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/util/intstr"
var netexecImageName = imageutils.GetE2EImage(imageutils.Agnhost) <ins> // TranslateIPv4ToIPv6 maps an IPv4 address into a valid IPv6 address // adding the well known prefix "0::ffff:" https://tools.ietf.org/html/rfc2765 // if the ip is IPv4 and the cluster IPFamily is IPv6, otherwise returns the same ip func TranslateIPv4ToIPv6(ip string) string { if TestContext.IPFamily == "ipv6" && !k8utilnet.IsIPv6String(ip) { ip = "0::ffff:" + ip } return ip } </ins> // NewNetworkingTestConfig creates and sets up a new test config helper. func NewNetworkingTestConfig(f *Framework) *NetworkingTestConfig { config := &NetworkingTestConfig{f: f, Namespace: f.Namespace.Name, HostNetwork: true}
// create pod which using hostport on the specified node according to the nodeSelector func createHostPortPodOnNode(f *framework.Framework, podName, ns, hostIP string, port int32, protocol v1.Protocol, nodeSelector map[string]string, expectScheduled bool) { <ins> hostIP = framework.TranslateIPv4ToIPv6(hostIP) </ins> createPausePod(f, pausePodConfig{ Name: podName, Ports: []v1.ContainerPort{
if service.Spec.ClusterIP != "" { allErrs = append(allErrs, field.Forbidden(specPath.Child("clusterIP"), "must be empty for ExternalName services")) } <del> if len(service.Spec.ExternalName) > 0 { allErrs = append(allErrs, ValidateDNS1123Subdomain(service.Spec.ExternalName, specPath.Child("externalName"))...) </del> <ins> // The value (a CNAME) may have a trailing dot to denote it as fully qualified cname := strings.TrimSuffix(service.Spec.ExternalName, ".") if len(cname) > 0 { allErrs = append(allErrs, ValidateDNS1123Subdomain(cname, specPath.Child("externalName"))...) </ins> } else { allErrs = append(allErrs, field.Required(specPath.Child("externalName"), "")) }
numErrs: 0, }, { <ins> name: "valid ExternalName (trailing dot)", tweakSvc: func(s *core.Service) { s.Spec.Type = core.ServiceTypeExternalName s.Spec.ClusterIP = "" s.Spec.ExternalName = "foo.bar.example.com." }, numErrs: 0, }, { </ins> name: "invalid ExternalName clusterIP (valid IP)", tweakSvc: func(s *core.Service) { s.Spec.Type = core.ServiceTypeExternalName
// this is a blocking call and should only return when the pod and its containers are killed. err := c.killPodFunc(pod, status, nil) if err != nil { <del> return fmt.Errorf("preemption: pod %s failed to evict %v", format.Pod(pod), err) </del> <ins> klog.Warningf("preemption: pod %s failed to evict %v", format.Pod(pod), err) // In future syncPod loops, the kubelet will retry the pod deletion steps that it was stuck on. continue </ins> } klog.Infof("preemption: pod %s evicted successfully", format.Pod(pod)) }
) type fakePodKiller struct { <del> killedPods []*v1.Pod </del> <ins> killedPods          []*v1.Pod errDuringPodKilling bool </ins> } <del> func newFakePodKiller() *fakePodKiller { return &fakePodKiller{killedPods: []*v1.Pod{}} </del> <ins> func newFakePodKiller(errPodKilling bool) *fakePodKiller { return &fakePodKiller{killedPods: []*v1.Pod{}, errDuringPodKilling: errPodKilling} </ins> } func (f *fakePodKiller) clear() {
} func (f *fakePodKiller) killPodNow(pod *v1.Pod, status v1.PodStatus, gracePeriodOverride *int64) error { <ins> if f.errDuringPodKilling { f.killedPods = []*v1.Pod{} return fmt.Errorf("problem killing pod %v", pod) } </ins> f.killedPods = append(f.killedPods, pod) return nil }
} } <ins> func TestEvictPodsToFreeRequestsWithError(t *testing.T) { defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ExperimentalCriticalPodAnnotation, true)() type testRun struct { testName              string inputPods             []*v1.Pod insufficientResources admissionRequirementList expectErr             bool expectedOutput        []*v1.Pod } podProvider := newFakePodProvider() podKiller := newFakePodKiller(true) criticalPodAdmissionHandler := getTestCriticalPodAdmissionHandler(podProvider, podKiller) allPods := getTestPods() runs := []testRun{ { testName: "multiple pods eviction error", inputPods: []*v1.Pod{ allPods[critical], allPods[bestEffort], allPods[burstable], allPods[highRequestBurstable], allPods[guaranteed], allPods[highRequestGuaranteed]}, insufficientResources: getAdmissionRequirementList(0, 550, 0), expectErr:             false, expectedOutput:        nil, }, } for _, r := range runs { podProvider.setPods(r.inputPods) outErr := criticalPodAdmissionHandler.evictPodsToFreeRequests(allPods[critical], r.insufficientResources) outputPods := podKiller.getKilledPods() if !r.expectErr && outErr != nil { t.Errorf("evictPodsToFreeRequests returned an unexpected error during the %s test.  Err: %v", r.testName, outErr) } else if r.expectErr && outErr == nil { t.Errorf("evictPodsToFreeRequests expected an error but returned a successful output=%v during the %s test.", outputPods, r.testName) } else if !podListEqual(r.expectedOutput, outputPods) { t.Errorf("evictPodsToFreeRequests expected %v but got %v during the %s test.", r.expectedOutput, outputPods, r.testName) } podKiller.clear() } } </ins> func TestEvictPodsToFreeRequests(t *testing.T) { defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ExperimentalCriticalPodAnnotation, true)() type testRun struct {
expectedOutput        []*v1.Pod } podProvider := newFakePodProvider() <del> podKiller := newFakePodKiller() </del> <ins> podKiller := newFakePodKiller(false) </ins> criticalPodAdmissionHandler := getTestCriticalPodAdmissionHandler(podProvider, podKiller) allPods := getTestPods() runs := []testRun{
}, }, { <del> // a role for the csi external attacher ObjectMeta: metav1.ObjectMeta{Name: "system:csi-external-attacher"}, Rules: []rbacv1.PolicyRule{ rbacv1helpers.NewRule("get", "list", "watch", "update", "patch").Groups(legacyGroup).Resources("persistentvolumes").RuleOrDie(), rbacv1helpers.NewRule("get", "list", "watch").Groups(legacyGroup).Resources("nodes").RuleOrDie(), rbacv1helpers.NewRule("get", "list", "watch", "update", "patch").Groups(storageGroup).Resources("volumeattachments").RuleOrDie(), rbacv1helpers.NewRule("get", "list", "watch", "create", "update", "patch").Groups(legacyGroup).Resources("events").RuleOrDie(), }, }, { </del> // a role making the csrapprover controller approve a node client CSR ObjectMeta: metav1.ObjectMeta{Name: "system:certificates.k8s.io:certificatesigningrequests:nodeclient"}, Rules: []rbacv1.PolicyRule{
Rules:      kubeSchedulerRules, }) <del> externalProvisionerRules := []rbacv1.PolicyRule{ rbacv1helpers.NewRule("create", "delete", "get", "list", "watch").Groups(legacyGroup).Resources("persistentvolumes").RuleOrDie(), rbacv1helpers.NewRule("get", "list", "watch", "update", "patch").Groups(legacyGroup).Resources("persistentvolumeclaims").RuleOrDie(), rbacv1helpers.NewRule("list", "watch").Groups(storageGroup).Resources("storageclasses").RuleOrDie(), rbacv1helpers.NewRule("get", "list", "watch", "create", "update", "patch").Groups(legacyGroup).Resources("events").RuleOrDie(), 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("storage.k8s.io").Resources("csinodes").RuleOrDie()) } roles = append(roles, rbacv1.ClusterRole{ // a role for the csi external provisioner ObjectMeta: metav1.ObjectMeta{Name: "system:csi-external-provisioner"}, Rules:      externalProvisionerRules, }) </del> addClusterRoleLabel(roles) return roles }