...

Source file src/k8s.io/kubernetes/pkg/kubelet/server/auth.go

Documentation: k8s.io/kubernetes/pkg/kubelet/server

     1  /*
     2  Copyright 2015 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package server
    18  
    19  import (
    20  	"net/http"
    21  	"strings"
    22  
    23  	"k8s.io/apimachinery/pkg/types"
    24  	"k8s.io/apiserver/pkg/authentication/authenticator"
    25  	"k8s.io/apiserver/pkg/authentication/user"
    26  	"k8s.io/apiserver/pkg/authorization/authorizer"
    27  	"k8s.io/klog/v2"
    28  )
    29  
    30  // KubeletAuth implements AuthInterface
    31  type KubeletAuth struct {
    32  	// authenticator identifies the user for requests to the Kubelet API
    33  	authenticator.Request
    34  	// authorizerAttributeGetter builds authorization.Attributes for a request to the Kubelet API
    35  	authorizer.RequestAttributesGetter
    36  	// authorizer determines whether a given authorization.Attributes is allowed
    37  	authorizer.Authorizer
    38  }
    39  
    40  // NewKubeletAuth returns a kubelet.AuthInterface composed of the given authenticator, attribute getter, and authorizer
    41  func NewKubeletAuth(authenticator authenticator.Request, authorizerAttributeGetter authorizer.RequestAttributesGetter, authorizer authorizer.Authorizer) AuthInterface {
    42  	return &KubeletAuth{authenticator, authorizerAttributeGetter, authorizer}
    43  }
    44  
    45  // NewNodeAuthorizerAttributesGetter creates a new authorizer.RequestAttributesGetter for the node.
    46  func NewNodeAuthorizerAttributesGetter(nodeName types.NodeName) authorizer.RequestAttributesGetter {
    47  	return nodeAuthorizerAttributesGetter{nodeName: nodeName}
    48  }
    49  
    50  type nodeAuthorizerAttributesGetter struct {
    51  	nodeName types.NodeName
    52  }
    53  
    54  func isSubpath(subpath, path string) bool {
    55  	path = strings.TrimSuffix(path, "/")
    56  	return subpath == path || (strings.HasPrefix(subpath, path) && subpath[len(path)] == '/')
    57  }
    58  
    59  // GetRequestAttributes populates authorizer attributes for the requests to the kubelet API.
    60  // Default attributes are: {apiVersion=v1,verb=<http verb from request>,resource=nodes,name=<node name>,subresource=proxy}
    61  // More specific verb/resource is set for the following request patterns:
    62  //
    63  //	/stats/*   => verb=<api verb from request>, resource=nodes, name=<node name>, subresource=stats
    64  //	/metrics/* => verb=<api verb from request>, resource=nodes, name=<node name>, subresource=metrics
    65  //	/logs/*    => verb=<api verb from request>, resource=nodes, name=<node name>, subresource=log
    66  func (n nodeAuthorizerAttributesGetter) GetRequestAttributes(u user.Info, r *http.Request) authorizer.Attributes {
    67  
    68  	apiVerb := ""
    69  	switch r.Method {
    70  	case "POST":
    71  		apiVerb = "create"
    72  	case "GET":
    73  		apiVerb = "get"
    74  	case "PUT":
    75  		apiVerb = "update"
    76  	case "PATCH":
    77  		apiVerb = "patch"
    78  	case "DELETE":
    79  		apiVerb = "delete"
    80  	}
    81  
    82  	requestPath := r.URL.Path
    83  
    84  	// Default attributes mirror the API attributes that would allow this access to the kubelet API
    85  	attrs := authorizer.AttributesRecord{
    86  		User:            u,
    87  		Verb:            apiVerb,
    88  		Namespace:       "",
    89  		APIGroup:        "",
    90  		APIVersion:      "v1",
    91  		Resource:        "nodes",
    92  		Subresource:     "proxy",
    93  		Name:            string(n.nodeName),
    94  		ResourceRequest: true,
    95  		Path:            requestPath,
    96  	}
    97  
    98  	// Override subresource for specific paths
    99  	// This allows subdividing access to the kubelet API
   100  	switch {
   101  	case isSubpath(requestPath, statsPath):
   102  		attrs.Subresource = "stats"
   103  	case isSubpath(requestPath, metricsPath):
   104  		attrs.Subresource = "metrics"
   105  	case isSubpath(requestPath, logsPath):
   106  		// "log" to match other log subresources (pods/log, etc)
   107  		attrs.Subresource = "log"
   108  	case isSubpath(requestPath, checkpointPath):
   109  		attrs.Subresource = "checkpoint"
   110  	}
   111  
   112  	klog.V(5).InfoS("Node request attributes", "user", attrs.GetUser().GetName(), "verb", attrs.GetVerb(), "resource", attrs.GetResource(), "subresource", attrs.GetSubresource())
   113  
   114  	return attrs
   115  }
   116  

View as plain text