...
|
...
|
@@ -1,7 +1,7 @@
|
1
|
|
-From 73dd46ef2f0ddd1ccf93b0d2d339a38e08b84c20 Mon Sep 17 00:00:00 2001
|
|
1
|
+From 2683eb21c7c52d3eacbeb190d0a27b2a2ebca708 Mon Sep 17 00:00:00 2001
|
2
|
2
|
From: DheerajSShetty <dheerajs@vmware.com>
|
3
|
|
-Date: Tue, 11 Sep 2018 12:05:49 -0700
|
4
|
|
-Subject: [PATCH] VKE patch for k8s 1.9.6 (8033c471)
|
|
3
|
+Date: Mon, 8 Oct 2018 17:02:50 -0700
|
|
4
|
+Subject: [PATCH] VKE patch for k8s 1.9.10 (48fc708e)
|
5
|
5
|
|
6
|
6
|
---
|
7
|
7
|
api/swagger-spec/apps_v1alpha1.json | Bin 135734 -> 136495 bytes
|
...
|
...
|
@@ -28,7 +28,7 @@ Subject: [PATCH] VKE patch for k8s 1.9.6 (8033c471)
|
28
|
28
|
pkg/cloudprovider/providers/cascade/auth.go | 145 ++++
|
29
|
29
|
pkg/cloudprovider/providers/cascade/cascade.go | 219 +++++
|
30
|
30
|
.../providers/cascade/cascade_disks.go | 226 +++++
|
31
|
|
- .../providers/cascade/cascade_instances.go | 91 ++
|
|
31
|
+ .../providers/cascade/cascade_instances.go | 124 +++
|
32
|
32
|
.../providers/cascade/cascade_instances_test.go | 43 +
|
33
|
33
|
.../providers/cascade/cascade_loadbalancer.go | 284 ++++++
|
34
|
34
|
pkg/cloudprovider/providers/cascade/client.go | 399 +++++++++
|
...
|
...
|
@@ -49,15 +49,15 @@ Subject: [PATCH] VKE patch for k8s 1.9.6 (8033c471)
|
49
|
49
|
pkg/volume/cascade_disk/cascade_util.go | 201 +++++
|
50
|
50
|
.../admission/persistentvolume/label/admission.go | 54 ++
|
51
|
51
|
plugin/pkg/admission/vke/BUILD | 61 ++
|
52
|
|
- plugin/pkg/admission/vke/admission.go | 587 +++++++++++++
|
53
|
|
- plugin/pkg/admission/vke/admission_test.go | 952 +++++++++++++++++++++
|
|
52
|
+ plugin/pkg/admission/vke/admission.go | 618 +++++++++++++
|
|
53
|
+ plugin/pkg/admission/vke/admission_test.go | 960 +++++++++++++++++++++
|
54
|
54
|
plugin/pkg/auth/authorizer/vke/BUILD | 40 +
|
55
|
55
|
plugin/pkg/auth/authorizer/vke/OWNERS | 3 +
|
56
|
56
|
plugin/pkg/auth/authorizer/vke/vke_authorizer.go | 123 +++
|
57
|
57
|
.../pkg/auth/authorizer/vke/vke_authorizer_test.go | 230 +++++
|
58
|
58
|
staging/src/k8s.io/api/core/v1/generated.pb.go | Bin 1241955 -> 1248240 bytes
|
59
|
59
|
staging/src/k8s.io/api/core/v1/types.go | 26 +-
|
60
|
|
- 53 files changed, 5473 insertions(+), 8 deletions(-)
|
|
60
|
+ 53 files changed, 5545 insertions(+), 8 deletions(-)
|
61
|
61
|
|
62
|
62
|
diff --git a/api/swagger-spec/apps_v1alpha1.json b/api/swagger-spec/apps_v1alpha1.json
|
63
|
63
|
index aa3fbdc..0189f38 100644
|
...
|
...
|
@@ -559,7 +559,7 @@ index b6b570b..1d9db5e 100644
|
559
|
559
|
//
|
560
|
560
|
// The contents of the target ConfigMap's Data field will be presented in a
|
561
|
561
|
diff --git a/pkg/apis/core/validation/validation.go b/pkg/apis/core/validation/validation.go
|
562
|
|
-index f6ab55f..2fa447d 100644
|
|
562
|
+index 5dd08c0..eb66cc9 100644
|
563
|
563
|
--- a/pkg/apis/core/validation/validation.go
|
564
|
564
|
+++ b/pkg/apis/core/validation/validation.go
|
565
|
565
|
@@ -681,6 +681,14 @@ func validateVolumeSource(source *core.VolumeSource, fldPath *field.Path, volNam
|
...
|
...
|
@@ -1558,17 +1558,21 @@ index 0000000..4df1ab9
|
1558
|
1558
|
+}
|
1559
|
1559
|
diff --git a/pkg/cloudprovider/providers/cascade/cascade_instances.go b/pkg/cloudprovider/providers/cascade/cascade_instances.go
|
1560
|
1560
|
new file mode 100644
|
1561
|
|
-index 0000000..0172151
|
|
1561
|
+index 0000000..4494542
|
1562
|
1562
|
--- /dev/null
|
1563
|
1563
|
+++ b/pkg/cloudprovider/providers/cascade/cascade_instances.go
|
1564
|
|
-@@ -0,0 +1,91 @@
|
|
1564
|
+@@ -0,0 +1,124 @@
|
1565
|
1565
|
+package cascade
|
1566
|
1566
|
+
|
1567
|
1567
|
+import (
|
1568
|
|
-+ "k8s.io/api/core/v1"
|
1569
|
|
-+ k8stypes "k8s.io/apimachinery/pkg/types"
|
1570
|
1568
|
+ "errors"
|
|
1569
|
++ "github.com/golang/glog"
|
|
1570
|
++ "os"
|
1571
|
1571
|
+ "strings"
|
|
1572
|
++
|
|
1573
|
++ "k8s.io/api/core/v1"
|
|
1574
|
++ k8stypes "k8s.io/apimachinery/pkg/types"
|
|
1575
|
++ "k8s.io/kubernetes/pkg/cloudprovider"
|
1572
|
1576
|
+)
|
1573
|
1577
|
+
|
1574
|
1578
|
+// NodeAddresses is an implementation of Instances.NodeAddresses. In the future, private IP address, external IP, etc.
|
...
|
...
|
@@ -1613,12 +1617,11 @@ index 0000000..0172151
|
1613
|
1613
|
+}
|
1614
|
1614
|
+
|
1615
|
1615
|
+// ExternalID returns the cloud provider ID of the specified instance (deprecated).
|
1616
|
|
-+// Note: We do not call Cascade Controller here to check if the instance is alive or not because that requires the
|
1617
|
|
-+// worker nodes to also login to Cascade Controller. That check is used by Kubernetes to proactively remove nodes that
|
1618
|
|
-+// the cloud provider believes is no longer available. Even otherwise, Kubernetes will remove those nodes eventually.
|
1619
|
|
-+// So we are not losing much by not doing that check.
|
|
1616
|
++// Note: We call Cascade Controller here to check if the instance is alive or not. That check is used by Kubernetes
|
|
1617
|
++// to proactively remove nodes that the cloud provider believes is no longer available. Even otherwise, Kubernetes
|
|
1618
|
++// will remove those nodes eventually.
|
1620
|
1619
|
+func (cc *CascadeCloud) ExternalID(nodeName k8stypes.NodeName) (string, error) {
|
1621
|
|
-+ return getInstanceIDFromNodeName(nodeName)
|
|
1620
|
++ return getInstanceIDAndLivelinessFromNodeName(cc, nodeName)
|
1622
|
1621
|
+}
|
1623
|
1622
|
+
|
1624
|
1623
|
+// InstanceExistsByProviderID returns true if the instance with the given provider id still exists and is running.
|
...
|
...
|
@@ -1643,6 +1646,36 @@ index 0000000..0172151
|
1643
|
1643
|
+ return nodeParts[1], nil
|
1644
|
1644
|
+}
|
1645
|
1645
|
+
|
|
1646
|
++// This gets the Cascade VM ID and its liveliness from the Kubernetes node name.
|
|
1647
|
++func getInstanceIDAndLivelinessFromNodeName(cc *CascadeCloud, nodeName k8stypes.NodeName) (string, error) {
|
|
1648
|
++ instanceID, err := getInstanceIDFromNodeName(nodeName)
|
|
1649
|
++ if err != nil {
|
|
1650
|
++ return "", err
|
|
1651
|
++ }
|
|
1652
|
++ // Get local hostname. We need to do this check to make sure we call VKE controller only from master nodes
|
|
1653
|
++ // because worker nodes cannot login to VKE controller.
|
|
1654
|
++ hostname, err := os.Hostname()
|
|
1655
|
++ if err != nil {
|
|
1656
|
++ glog.Errorf("Cascade Cloud Provider: get hostname failed. Error[%v]", err)
|
|
1657
|
++ return "", err
|
|
1658
|
++ }
|
|
1659
|
++ // Note: Kubelet running on the worker node do not need to call VKE.
|
|
1660
|
++ if strings.HasPrefix(hostname, MasterPrefix) {
|
|
1661
|
++ _, err := cc.apiClient.GetVM(instanceID)
|
|
1662
|
++ if err != nil {
|
|
1663
|
++ switch err.(type) {
|
|
1664
|
++ case APIError:
|
|
1665
|
++ if err.(APIError).ErrorCode == VMNotFoundError {
|
|
1666
|
++ // If instance no longer exists, we will return instance not found error
|
|
1667
|
++ glog.Warningf("Cascade Cloud Provider: VM %s does not exist", instanceID)
|
|
1668
|
++ return "", cloudprovider.InstanceNotFound
|
|
1669
|
++ }
|
|
1670
|
++ }
|
|
1671
|
++ }
|
|
1672
|
++ }
|
|
1673
|
++ return instanceID, nil
|
|
1674
|
++}
|
|
1675
|
++
|
1646
|
1676
|
+// InstanceTypeByProviderID returns the cloudprovider instance type of the node with the specified unique providerID
|
1647
|
1677
|
+// This method will not be called from the node that is requesting this ID. i.e. metadata service
|
1648
|
1678
|
+// and other local methods cannot be used here
|
...
|
...
|
@@ -4354,10 +4387,10 @@ index 0000000..7d66036
|
4354
|
4354
|
\ No newline at end of file
|
4355
|
4355
|
diff --git a/plugin/pkg/admission/vke/admission.go b/plugin/pkg/admission/vke/admission.go
|
4356
|
4356
|
new file mode 100644
|
4357
|
|
-index 0000000..a5403d0
|
|
4357
|
+index 0000000..a9ec9df
|
4358
|
4358
|
--- /dev/null
|
4359
|
4359
|
+++ b/plugin/pkg/admission/vke/admission.go
|
4360
|
|
-@@ -0,0 +1,587 @@
|
|
4360
|
+@@ -0,0 +1,618 @@
|
4361
|
4361
|
+package vke
|
4362
|
4362
|
+
|
4363
|
4363
|
+import (
|
...
|
...
|
@@ -4385,8 +4418,9 @@ index 0000000..a5403d0
|
4385
|
4385
|
+ // PluginName indicates name of admission plugin.
|
4386
|
4386
|
+ PluginName = "VMwareAdmissionController"
|
4387
|
4387
|
+
|
4388
|
|
-+ systemUnsecuredUser = "system:unsecured"
|
4389
|
4388
|
+ systemNodesGroup = "system:nodes"
|
|
4389
|
++ systemMastersGroup = "system:masters"
|
|
4390
|
++ systemWorkerGroup = "system:worker"
|
4390
|
4391
|
+ privilegedNamespace = "vke-system"
|
4391
|
4392
|
+ privilegedServiceAccount = "system:serviceaccount:" + privilegedNamespace + ":"
|
4392
|
4393
|
+ reservedPrefix = "vke"
|
...
|
...
|
@@ -4438,12 +4472,12 @@ index 0000000..a5403d0
|
4438
|
4438
|
+ return nil
|
4439
|
4439
|
+ }
|
4440
|
4440
|
+
|
4441
|
|
-+ if isSystemUnsecuredUser(a) {
|
4442
|
|
-+ return validateSystemUnsecuredUser(vac, a)
|
|
4441
|
++ if isCertificateFromMaster(a) {
|
|
4442
|
++ return validateCertificateFromMaster(vac, a)
|
4443
|
4443
|
+ }
|
4444
|
4444
|
+
|
4445
|
|
-+ if isCertificateFromNode(a) {
|
4446
|
|
-+ return validateCertificateFromNode(a)
|
|
4445
|
++ if isCertificateFromWorker(a) {
|
|
4446
|
++ return validateCertificateFromWorker(a)
|
4447
|
4447
|
+ }
|
4448
|
4448
|
+
|
4449
|
4449
|
+ if isPrivilegedServiceAccount(a) {
|
...
|
...
|
@@ -4597,17 +4631,19 @@ index 0000000..a5403d0
|
4597
|
4597
|
+ return false
|
4598
|
4598
|
+}
|
4599
|
4599
|
+
|
4600
|
|
-+func isSystemUnsecuredUser(a admission.Attributes) bool {
|
4601
|
|
-+ return a.GetUserInfo().GetName() == systemUnsecuredUser
|
|
4600
|
++func isCertificateFromMaster(a admission.Attributes) bool {
|
|
4601
|
++ groups := a.GetUserInfo().GetGroups()
|
|
4602
|
++ for _, group := range groups {
|
|
4603
|
++ if group == systemMastersGroup {
|
|
4604
|
++ return true
|
|
4605
|
++ }
|
|
4606
|
++ }
|
|
4607
|
++ return false
|
4602
|
4608
|
+}
|
4603
|
4609
|
+
|
4604
|
|
-+func validateSystemUnsecuredUser(vac *vmwareAdmissionController, a admission.Attributes) (err error) {
|
4605
|
|
-+ // Currently the insecure port 8080 is exposed to only localhost inside the Kubernetes master VMs. So it can be used
|
4606
|
|
-+ // only by kube-controller-manager, kube-scheduler and cloud-init script which creates our pods and other resources.
|
4607
|
|
-+ // When a call comes on insecure port 8080, Kubernetes assigns them system:unsecured user name. We need to allow
|
4608
|
|
-+ // this so that our master components can be started successfully and kube-controller-manager and kube-scheduler can
|
4609
|
|
-+ // work as expected.
|
4610
|
|
-+ // But this needs to be allowed only inside our privileged namespace. If the request comes to any other namespace,
|
|
4610
|
++func validateCertificateFromMaster(vac *vmwareAdmissionController, a admission.Attributes) (err error) {
|
|
4611
|
++ // kube-controller-manager, kube-scheduler and cloud-init script which creates our pods and other resources can use
|
|
4612
|
++ // the master certificate to create pods in privileged namespace. If the request comes to any other namespace,
|
4611
|
4613
|
+ // we need to make it go through our pod validation. This is needed because a user can create a deployment or
|
4612
|
4614
|
+ // replica set which has a privileged pod. Since our admission controller does not look at deployments or replica
|
4613
|
4615
|
+ // sets, we will allow it. The actual pod inside the deployment or replica set will be created by the
|
...
|
...
|
@@ -4621,26 +4657,47 @@ index 0000000..a5403d0
|
4621
|
4621
|
+ return nil
|
4622
|
4622
|
+}
|
4623
|
4623
|
+
|
4624
|
|
-+func isCertificateFromNode(a admission.Attributes) bool {
|
4625
|
|
-+ // If the request came from a user with group = systemNodesGroup, then we assume that the request comes from a node
|
4626
|
|
-+ // which uses a certificate for authentication.
|
|
4624
|
++func isCertificateFromWorker(a admission.Attributes) bool {
|
4627
|
4625
|
+ groups := a.GetUserInfo().GetGroups()
|
4628
|
4626
|
+ for _, group := range groups {
|
4629
|
|
-+ if group == systemNodesGroup {
|
|
4627
|
++ if group == systemWorkerGroup {
|
4630
|
4628
|
+ return true
|
4631
|
4629
|
+ }
|
4632
|
4630
|
+ }
|
4633
|
4631
|
+ return false
|
4634
|
4632
|
+}
|
4635
|
4633
|
+
|
4636
|
|
-+func validateCertificateFromNode(a admission.Attributes) error {
|
4637
|
|
-+ // Block exec operations into pods for nodes. This is needed to block someone from using Kubelet's certificate to
|
|
4634
|
++func isCreatingPodsThroughControllerManager(resource string) bool {
|
|
4635
|
++ // If the resource is one of the following, it means the controller manager will create a pod for them and not the
|
|
4636
|
++ // user directly. So, we need to identify these cases and block them in certain scenarios.
|
|
4637
|
++ if resource == "deployments" ||
|
|
4638
|
++ resource == "replicasets" ||
|
|
4639
|
++ resource == "replicationcontrollers" ||
|
|
4640
|
++ resource == "statefulsets" ||
|
|
4641
|
++ resource == "daemonsets" ||
|
|
4642
|
++ resource == "jobs" ||
|
|
4643
|
++ resource == "cronjobs" {
|
|
4644
|
++ return true
|
|
4645
|
++ }
|
|
4646
|
++ return false
|
|
4647
|
++}
|
|
4648
|
++
|
|
4649
|
++func validateCertificateFromWorker(a admission.Attributes) error {
|
|
4650
|
++ // Block exec operations into pods for workers. This is needed to block someone from using Kubelet's certificate to
|
4638
|
4651
|
+ // exec into privileged pods running on the master. Other operations with the node certificate like modifying master
|
4639
|
4652
|
+ // node, creating pods on master node, etc. are blocked by the node restriction admission controller.
|
4640
|
|
-+ if a.GetResource().GroupResource() == api.Resource("pods") && a.GetOperation() == admission.Connect {
|
|
4653
|
++ resource := a.GetResource().GroupResource()
|
|
4654
|
++ if resource == api.Resource("pods") && a.GetOperation() == admission.Connect {
|
4641
|
4655
|
+ return admission.NewForbidden(a,
|
4642
|
4656
|
+ fmt.Errorf("%s validation failed: cannot modify pods in namespace %s", PluginName, a.GetNamespace()))
|
4643
|
4657
|
+ }
|
|
4658
|
++
|
|
4659
|
++ // Block creation of pods indirectly by going through the controller manager.
|
|
4660
|
++ if isCreatingPodsThroughControllerManager(resource.Resource) {
|
|
4661
|
++ return admission.NewForbidden(a,
|
|
4662
|
++ fmt.Errorf("%s validation failed: cannot modify %s in namespace %s", PluginName, resource.Resource, a.GetNamespace()))
|
|
4663
|
++ }
|
|
4664
|
++
|
4644
|
4665
|
+ return nil
|
4645
|
4666
|
+}
|
4646
|
4667
|
+
|
...
|
...
|
@@ -4674,7 +4731,8 @@ index 0000000..a5403d0
|
4674
|
4674
|
+ // we block it. This is needed so that we can block exec access into privileged pods running on the master. Also,
|
4675
|
4675
|
+ // privileged service account does not need to perform these operations. So, just to be extra cautious we also block
|
4676
|
4676
|
+ // off create and update pods.
|
4677
|
|
-+ if a.GetResource().GroupResource() == api.Resource("pods") {
|
|
4677
|
++ resource := a.GetResource().GroupResource()
|
|
4678
|
++ if resource == api.Resource("pods") {
|
4678
|
4679
|
+ // Allow Delete operation on pods
|
4679
|
4680
|
+ if a.GetOperation() == admission.Delete {
|
4680
|
4681
|
+ return nil
|
...
|
...
|
@@ -4690,9 +4748,9 @@ index 0000000..a5403d0
|
4690
|
4690
|
+ }
|
4691
|
4691
|
+ }
|
4692
|
4692
|
+
|
4693
|
|
-+ // If the privileged service account tries to update taints on a node, we block. We need to do this so that a user
|
4694
|
|
-+ // cannot use a privileged service account to untaint the node and run pods on a master.
|
4695
|
|
-+ if a.GetResource().GroupResource() == api.Resource("nodes") {
|
|
4693
|
++ // If the privileged service account tries to update taints on the master node, we block. We need to do this so that
|
|
4694
|
++ // a user cannot use a privileged service account to untaint the node and run pods on a master.
|
|
4695
|
++ if resource == api.Resource("nodes") {
|
4696
|
4696
|
+ if a.GetOperation() == admission.Update && strings.HasPrefix(a.GetName(), masterNodePrefix) {
|
4697
|
4697
|
+ node, ok := a.GetObject().(*api.Node)
|
4698
|
4698
|
+ if !ok {
|
...
|
...
|
@@ -4712,6 +4770,12 @@ index 0000000..a5403d0
|
4712
|
4712
|
+ }
|
4713
|
4713
|
+ }
|
4714
|
4714
|
+
|
|
4715
|
++ // Block creation of pods indirectly by going through the controller manager.
|
|
4716
|
++ if isCreatingPodsThroughControllerManager(resource.Resource) {
|
|
4717
|
++ return admission.NewForbidden(a,
|
|
4718
|
++ fmt.Errorf("%s validation failed: cannot modify %s in namespace %s", PluginName, resource.Resource, a.GetNamespace()))
|
|
4719
|
++ }
|
|
4720
|
++
|
4715
|
4721
|
+ return nil
|
4716
|
4722
|
+}
|
4717
|
4723
|
+
|
...
|
...
|
@@ -4947,10 +5011,10 @@ index 0000000..a5403d0
|
4947
|
4947
|
+}
|
4948
|
4948
|
diff --git a/plugin/pkg/admission/vke/admission_test.go b/plugin/pkg/admission/vke/admission_test.go
|
4949
|
4949
|
new file mode 100644
|
4950
|
|
-index 0000000..c597663
|
|
4950
|
+index 0000000..684fad4
|
4951
|
4951
|
--- /dev/null
|
4952
|
4952
|
+++ b/plugin/pkg/admission/vke/admission_test.go
|
4953
|
|
-@@ -0,0 +1,952 @@
|
|
4953
|
+@@ -0,0 +1,960 @@
|
4954
|
4954
|
+package vke
|
4955
|
4955
|
+
|
4956
|
4956
|
+import (
|
...
|
...
|
@@ -5311,16 +5375,10 @@ index 0000000..c597663
|
5311
|
5311
|
+ userInfo: newTestUserBuilder().withGroup(testServiceAccountsGroup).build(),
|
5312
|
5312
|
+ shouldPassValidate: true,
|
5313
|
5313
|
+ },
|
5314
|
|
-+ "allowed: systemUnsecuredUser creates pod in vke-system namespace": {
|
|
5314
|
++ "allowed: systemMasters group creates pod in vke-system namespace": {
|
5315
|
5315
|
+ operation: kadmission.Create,
|
5316
|
5316
|
+ pod: newTestPodBuilder().withNamespace(privilegedNamespace).build(),
|
5317
|
|
-+ userInfo: newTestUserBuilder().withName(systemUnsecuredUser).build(),
|
5318
|
|
-+ shouldPassValidate: true,
|
5319
|
|
-+ },
|
5320
|
|
-+ "allowed: kubelet group creates pod in vke-system namespace": {
|
5321
|
|
-+ operation: kadmission.Create,
|
5322
|
|
-+ pod: newTestPodBuilder().withNamespace(privilegedNamespace).build(),
|
5323
|
|
-+ userInfo: newTestUserBuilder().withGroup(systemNodesGroup).withName("system:node:worker").build(),
|
|
5317
|
++ userInfo: newTestUserBuilder().withGroup(systemMastersGroup).build(),
|
5324
|
5318
|
+ shouldPassValidate: true,
|
5325
|
5319
|
+ },
|
5326
|
5320
|
+ "denied: regular lightwave group does not grant privileged access": {
|
...
|
...
|
@@ -5335,10 +5393,10 @@ index 0000000..c597663
|
5335
|
5335
|
+ userInfo: newTestUserBuilder().withGroup("test1\\group1").withGroup(testServiceAccountsGroup).build(),
|
5336
|
5336
|
+ shouldPassValidate: true,
|
5337
|
5337
|
+ },
|
5338
|
|
-+ "denied: kubelet exec into pod": {
|
|
5338
|
++ "denied: worker kubelet exec into pod": {
|
5339
|
5339
|
+ operation: kadmission.Connect,
|
5340
|
5340
|
+ pod: newTestPodBuilder().build(),
|
5341
|
|
-+ userInfo: newTestUserBuilder().withGroup("system:nodes").build(),
|
|
5341
|
++ userInfo: newTestUserBuilder().withGroup("system:worker").build(),
|
5342
|
5342
|
+ shouldPassValidate: false,
|
5343
|
5343
|
+ },
|
5344
|
5344
|
+ }
|
...
|
...
|
@@ -5475,12 +5533,12 @@ index 0000000..c597663
|
5475
|
5475
|
+ userInfo: newTestUserBuilder().build(),
|
5476
|
5476
|
+ shouldPassValidate: false,
|
5477
|
5477
|
+ },
|
5478
|
|
-+ "allowed: systemUnsecuredUser update clusterroles with vke: prefix": {
|
|
5478
|
++ "allowed: systemMasters group update clusterroles with vke: prefix": {
|
5479
|
5479
|
+ operation: kadmission.Update,
|
5480
|
5480
|
+ resource: "clusterroles",
|
5481
|
5481
|
+ name: "vke:clusterrole",
|
5482
|
5482
|
+ namespace: "",
|
5483
|
|
-+ userInfo: newTestUserBuilder().withName(systemUnsecuredUser).build(),
|
|
5483
|
++ userInfo: newTestUserBuilder().withGroup(systemMastersGroup).build(),
|
5484
|
5484
|
+ shouldPassValidate: true,
|
5485
|
5485
|
+ },
|
5486
|
5486
|
+ "allowed: regular lightwave user create clusterrolebindings": {
|
...
|
...
|
@@ -5507,12 +5565,12 @@ index 0000000..c597663
|
5507
|
5507
|
+ userInfo: newTestUserBuilder().build(),
|
5508
|
5508
|
+ shouldPassValidate: false,
|
5509
|
5509
|
+ },
|
5510
|
|
-+ "allowed: systemUnsecuredUser update clusterrolebindings with vke: prefix": {
|
|
5510
|
++ "allowed: systemMastersGroup update clusterrolebindings with vke: prefix": {
|
5511
|
5511
|
+ operation: kadmission.Update,
|
5512
|
5512
|
+ resource: "clusterrolebindings",
|
5513
|
5513
|
+ name: "vke:clusterrolebinding",
|
5514
|
5514
|
+ namespace: "",
|
5515
|
|
-+ userInfo: newTestUserBuilder().withName(systemUnsecuredUser).build(),
|
|
5515
|
++ userInfo: newTestUserBuilder().withGroup(systemMastersGroup).build(),
|
5516
|
5516
|
+ shouldPassValidate: true,
|
5517
|
5517
|
+ },
|
5518
|
5518
|
+ "allowed: regular lightwave user update worker nodes": {
|
...
|
...
|
@@ -5601,11 +5659,11 @@ index 0000000..c597663
|
5601
|
5601
|
+ userInfo: newTestUserBuilder().build(),
|
5602
|
5602
|
+ shouldPassValidate: false,
|
5603
|
5603
|
+ },
|
5604
|
|
-+ "allowed: systemUnsecuredUser update nodes": {
|
|
5604
|
++ "allowed: systemMasters group update nodes": {
|
5605
|
5605
|
+ operation: kadmission.Update,
|
5606
|
5606
|
+ resource: "nodes",
|
5607
|
5607
|
+ namespace: "",
|
5608
|
|
-+ userInfo: newTestUserBuilder().withName(systemUnsecuredUser).build(),
|
|
5608
|
++ userInfo: newTestUserBuilder().withGroup(systemMastersGroup).build(),
|
5609
|
5609
|
+ shouldPassValidate: true,
|
5610
|
5610
|
+ },
|
5611
|
5611
|
+ "allowed: kubelet update node": {
|
...
|
...
|
@@ -5635,6 +5693,20 @@ index 0000000..c597663
|
5635
|
5635
|
+ userInfo: newTestUserBuilder().withName(privilegedServiceAccount + "default").build(),
|
5636
|
5636
|
+ shouldPassValidate: false,
|
5637
|
5637
|
+ },
|
|
5638
|
++ "denied: privileged service account create a deployment": {
|
|
5639
|
++ operation: kadmission.Create,
|
|
5640
|
++ resource: "deployments",
|
|
5641
|
++ namespace: "vke-system",
|
|
5642
|
++ userInfo: newTestUserBuilder().withName(privilegedServiceAccount + "default").build(),
|
|
5643
|
++ shouldPassValidate: false,
|
|
5644
|
++ },
|
|
5645
|
++ "denied: worker kubelet create a deployment": {
|
|
5646
|
++ operation: kadmission.Create,
|
|
5647
|
++ resource: "deployments",
|
|
5648
|
++ namespace: "vke-system",
|
|
5649
|
++ userInfo: newTestUserBuilder().withGroup(systemWorkerGroup).build(),
|
|
5650
|
++ shouldPassValidate: false,
|
|
5651
|
++ },
|
5638
|
5652
|
+ }
|
5639
|
5653
|
+ for k, v := range tests {
|
5640
|
5654
|
+ testResourceValidation(k, v.operation, v.resource, v.subresource, v.name, v.namespace, v.userInfo, v.object,
|