@@ -65,6 +65,7 @@ type testContext struct {
65
65
66
66
client dynamic.Interface
67
67
clientset kubernetes.Interface
68
+ verb string
68
69
gvr schema.GroupVersionResource
69
70
resource metav1.APIResource
70
71
resources map [schema.GroupVersionResource ]metav1.APIResource
@@ -100,6 +101,10 @@ var (
100
101
gvr ("" , "v1" , "pods/attach" ): {"create" : testPodConnectSubresource },
101
102
gvr ("" , "v1" , "pods/exec" ): {"create" : testPodConnectSubresource },
102
103
gvr ("" , "v1" , "pods/portforward" ): {"create" : testPodConnectSubresource },
104
+
105
+ gvr ("" , "v1" , "nodes/proxy" ): {"*" : testSubresourceProxy },
106
+ gvr ("" , "v1" , "pods/proxy" ): {"*" : testSubresourceProxy },
107
+ gvr ("" , "v1" , "services/proxy" ): {"*" : testSubresourceProxy },
103
108
}
104
109
105
110
// excludedResources lists resources / verb combinations that are not yet tested. this set should trend to zero.
@@ -121,12 +126,9 @@ var (
121
126
gvr ("admissionregistration.k8s.io" , "v1beta1" , "validatingwebhookconfigurations" ): sets .NewString ("*" ),
122
127
123
128
// TODO: implement custom subresource tests (requires special states or requests)
124
- gvr ("" , "v1" , "bindings" ): sets .NewString ("create" ),
125
- gvr ("" , "v1" , "nodes/proxy" ): sets .NewString ("*" ),
126
- gvr ("" , "v1" , "pods/binding" ): sets .NewString ("create" ),
127
- gvr ("" , "v1" , "pods/eviction" ): sets .NewString ("create" ),
128
- gvr ("" , "v1" , "pods/proxy" ): sets .NewString ("*" ),
129
- gvr ("" , "v1" , "services/proxy" ): sets .NewString ("*" ),
129
+ gvr ("" , "v1" , "bindings" ): sets .NewString ("create" ),
130
+ gvr ("" , "v1" , "pods/binding" ): sets .NewString ("create" ),
131
+ gvr ("" , "v1" , "pods/eviction" ): sets .NewString ("create" ),
130
132
}
131
133
132
134
parentResources = map [schema.GroupVersionResource ]schema.GroupVersionResource {
@@ -398,6 +400,7 @@ func TestWebhookV1beta1(t *testing.T) {
398
400
admissionHolder : holder ,
399
401
client : dynamicClient ,
400
402
clientset : master .Client ,
403
+ verb : verb ,
401
404
gvr : gvr ,
402
405
resource : resource ,
403
406
resources : resourcesByGVR ,
@@ -775,6 +778,54 @@ func testPodConnectSubresource(c *testContext) {
775
778
}
776
779
}
777
780
781
+ // testSubresourceProxy verifies proxy subresources
782
+ func testSubresourceProxy (c * testContext ) {
783
+ parentGVR := getParentGVR (c .gvr )
784
+ parentResource := c .resources [parentGVR ]
785
+ obj , err := createOrGetResource (c .client , parentGVR , parentResource )
786
+ if err != nil {
787
+ c .t .Error (err )
788
+ return
789
+ }
790
+
791
+ gvrWithoutSubresources := c .gvr
792
+ gvrWithoutSubresources .Resource = strings .Split (gvrWithoutSubresources .Resource , "/" )[0 ]
793
+ subresources := strings .Split (c .gvr .Resource , "/" )[1 :]
794
+
795
+ verbToHTTPMethods := map [string ][]string {
796
+ "create" : {"POST" , "GET" , "HEAD" , "OPTIONS" }, // also test read-only verbs map to Connect admission
797
+ "update" : {"PUT" },
798
+ "patch" : {"PATCH" },
799
+ "delete" : {"DELETE" },
800
+ }
801
+ httpMethodsToTest , ok := verbToHTTPMethods [c .verb ]
802
+ if ! ok {
803
+ c .t .Errorf ("unknown verb %v" , c .verb )
804
+ return
805
+ }
806
+
807
+ for _ , httpMethod := range httpMethodsToTest {
808
+ c .t .Logf ("testing %v" , httpMethod )
809
+ request := c .clientset .CoreV1 ().RESTClient ().Verb (httpMethod )
810
+
811
+ // add the namespace if required
812
+ if len (obj .GetNamespace ()) > 0 {
813
+ request = request .Namespace (obj .GetNamespace ())
814
+ }
815
+
816
+ // set expectations
817
+ c .admissionHolder .expect (c .gvr , gvk (c .resource .Group , c .resource .Version , c .resource .Kind ), v1beta1 .Connect , obj .GetName (), obj .GetNamespace (), true , false )
818
+ // run the request. we don't actually care if the request is successful, just that admission gets called as expected
819
+ err = request .Resource (gvrWithoutSubresources .Resource ).Name (obj .GetName ()).SubResource (subresources ... ).Do ().Error ()
820
+ if err != nil {
821
+ c .t .Logf ("debug: result of subresource proxy (error expected): %v" , err )
822
+ }
823
+ // verify the result
824
+ c .admissionHolder .verify (c .t )
825
+ }
826
+
827
+ }
828
+
778
829
//
779
830
// utility methods
780
831
//
@@ -848,6 +899,9 @@ func getTestFunc(gvr schema.GroupVersionResource, verb string) testFunc {
848
899
if f , found := customTestFuncs [gvr ][verb ]; found {
849
900
return f
850
901
}
902
+ if f , found := customTestFuncs [gvr ]["*" ]; found {
903
+ return f
904
+ }
851
905
if strings .Contains (gvr .Resource , "/" ) {
852
906
if f , found := defaultSubresourceFuncs [verb ]; found {
853
907
return f
0 commit comments