@@ -14,17 +14,14 @@ See the License for the specific language governing permissions and
14
14
limitations under the License.
15
15
*/
16
16
17
- package e2enode
17
+ package node
18
18
19
19
import (
20
20
"context"
21
- "crypto/tls"
22
21
"fmt"
23
- "net/http"
24
22
25
23
"github.com/onsi/ginkgo/v2"
26
24
"github.com/onsi/gomega"
27
- authenticationv1 "k8s.io/api/authentication/v1"
28
25
authorizationv1 "k8s.io/api/authorization/v1"
29
26
v1 "k8s.io/api/core/v1"
30
27
rbacv1 "k8s.io/api/rbac/v1"
@@ -34,34 +31,39 @@ import (
34
31
"k8s.io/kubernetes/test/e2e/feature"
35
32
"k8s.io/kubernetes/test/e2e/framework"
36
33
e2eauth "k8s.io/kubernetes/test/e2e/framework/auth"
34
+ e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
35
+ e2eoutput "k8s.io/kubernetes/test/e2e/framework/pod/output"
36
+ admissionapi "k8s.io/pod-security-admission/api"
37
37
)
38
38
39
- var _ = SIGDescribe ("Kubelet Authz" , feature .KubeletFineGrainedAuthz , func () {
39
+ var _ = SIGDescribe (feature .KubeletFineGrainedAuthz , func () {
40
40
f := framework .NewDefaultFramework ("kubelet-authz-test" )
41
+ f .NamespacePodSecurityLevel = admissionapi .LevelBaseline
42
+
41
43
ginkgo .Context ("when calling kubelet API" , func () {
42
44
ginkgo .It ("check /healthz enpoint is accessible via nodes/healthz RBAC" , func (ctx context.Context ) {
43
45
sc := runKubeletAuthzTest (ctx , f , "healthz" , "healthz" )
44
- gomega .Expect (sc ).To (gomega .Equal (http . StatusOK ))
46
+ gomega .Expect (sc ).To (gomega .Equal ("200" ))
45
47
})
46
48
ginkgo .It ("check /healthz enpoint is accessible via nodes/proxy RBAC" , func (ctx context.Context ) {
47
49
sc := runKubeletAuthzTest (ctx , f , "healthz" , "proxy" )
48
- gomega .Expect (sc ).To (gomega .Equal (http . StatusOK ))
50
+ gomega .Expect (sc ).To (gomega .Equal ("200" ))
49
51
})
50
52
ginkgo .It ("check /healthz enpoint is not accessible via nodes/configz RBAC" , func (ctx context.Context ) {
51
53
sc := runKubeletAuthzTest (ctx , f , "healthz" , "configz" )
52
- gomega .Expect (sc ).To (gomega .Equal (http . StatusUnauthorized ))
54
+ gomega .Expect (sc ).To (gomega .Equal ("403" ))
53
55
})
54
56
})
55
57
})
56
58
57
- func runKubeletAuthzTest (ctx context.Context , f * framework.Framework , endpoint , authzSubresource string ) int {
59
+ func runKubeletAuthzTest (ctx context.Context , f * framework.Framework , endpoint , authzSubresource string ) string {
58
60
ns := f .Namespace .Name
59
61
saName := authzSubresource
60
62
crName := authzSubresource
61
63
verb := "get"
62
64
resource := "nodes"
63
65
64
- ginkgo .By (fmt .Sprintf ("Creating Service Account: %s/%s" , ns , saName ))
66
+ ginkgo .By (fmt .Sprintf ("Creating Service Account %s/%s" , ns , saName ))
65
67
66
68
_ , err := f .ClientSet .CoreV1 ().ServiceAccounts (ns ).Create (ctx , & v1.ServiceAccount {
67
69
ObjectMeta : metav1.ObjectMeta {
@@ -112,27 +114,41 @@ func runKubeletAuthzTest(ctx context.Context, f *framework.Framework, endpoint,
112
114
)
113
115
framework .ExpectNoError (err )
114
116
115
- ginkgo .By (fmt .Sprintf ("Getting token for ServiceAccount %s/%s." , ns , saName ))
117
+ pod := e2epod .NewAgnhostPod (ns , fmt .Sprintf ("agnhost-pod-%s" , authzSubresource ), nil , nil , nil )
118
+ pod .Spec .ServiceAccountName = saName
119
+ pod .Spec .Containers [0 ].Env = []v1.EnvVar {
120
+ {
121
+ Name : "NODE_IP" ,
122
+ ValueFrom : & v1.EnvVarSource {
123
+ FieldRef : & v1.ObjectFieldSelector {
124
+ FieldPath : "status.hostIP" ,
125
+ },
126
+ },
127
+ },
128
+ }
116
129
117
- tr , err := f .ClientSet .CoreV1 ().ServiceAccounts (ns ).CreateToken (ctx , saName , & authenticationv1.TokenRequest {}, metav1.CreateOptions {})
118
- framework .ExpectNoError (err )
130
+ ginkgo .By (fmt .Sprintf ("Creating Pod %s in namespace %s with serviceaccount %s" , pod .Name , pod .Namespace , pod .Spec .ServiceAccountName ))
119
131
120
- resp , err := healthCheck (fmt .Sprintf ("https://127.0.0.1:%d/%s" , ports .KubeletPort , endpoint ), tr .Status .Token )
121
- framework .ExpectNoError (err )
122
- return resp .StatusCode
123
- }
132
+ _ = e2epod .NewPodClient (f ).CreateSync (ctx , pod )
124
133
125
- func healthCheck (url , token string ) (* http.Response , error ) {
126
- insecureTransport := http .DefaultTransport .(* http.Transport ).Clone ()
127
- insecureTransport .TLSClientConfig = & tls.Config {InsecureSkipVerify : true }
128
- insecureHTTPClient := & http.Client {
129
- Transport : insecureTransport ,
130
- }
134
+ ginkgo .By ("Running command in Pod" )
131
135
132
- req , err := http .NewRequest (http .MethodGet , url , nil )
133
- if err != nil {
134
- return nil , err
136
+ var hostWarpStart , hostWarpEnd string
137
+ // IPv6 host must be wrapped within [] if you specify a port.
138
+ if framework .TestContext .ClusterIsIPv6 () {
139
+ hostWarpStart = "["
140
+ hostWarpEnd = "]"
135
141
}
136
- req .Header .Set ("Authorization" , fmt .Sprintf ("Bearer %s" , token ))
137
- return insecureHTTPClient .Do (req )
142
+
143
+ result := e2eoutput .RunHostCmdOrDie (ns ,
144
+ pod .Name ,
145
+ fmt .Sprintf ("curl -XGET -sIk -o /dev/null -w '%s' --header \" Authorization: Bearer `%s`\" https://%s$NODE_IP%s:%d/%s" ,
146
+ "%{http_code}" ,
147
+ "cat /var/run/secrets/kubernetes.io/serviceaccount/token" ,
148
+ hostWarpStart ,
149
+ hostWarpEnd ,
150
+ ports .KubeletPort ,
151
+ endpoint ))
152
+
153
+ return result
138
154
}
0 commit comments