k8s.io/apiserver@v0.31.1/pkg/endpoints/handlers/helpers.go (about)

     1  /*
     2  Copyright 2019 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 handlers
    18  
    19  import (
    20  	"net/http"
    21  
    22  	utilnet "k8s.io/apimachinery/pkg/util/net"
    23  	"k8s.io/apiserver/pkg/audit"
    24  	"k8s.io/apiserver/pkg/endpoints/metrics"
    25  	apirequest "k8s.io/apiserver/pkg/endpoints/request"
    26  )
    27  
    28  const (
    29  	maxUserAgentLength      = 1024
    30  	userAgentTruncateSuffix = "...TRUNCATED"
    31  )
    32  
    33  // lazyTruncatedUserAgent implements String() string and it will
    34  // return user-agent which may be truncated.
    35  type lazyTruncatedUserAgent struct {
    36  	req *http.Request
    37  }
    38  
    39  func (lazy *lazyTruncatedUserAgent) String() string {
    40  	ua := "unknown"
    41  	if lazy.req != nil {
    42  		ua = utilnet.GetHTTPClient(lazy.req)
    43  		if len(ua) > maxUserAgentLength {
    44  			ua = ua[:maxUserAgentLength] + userAgentTruncateSuffix
    45  		}
    46  	}
    47  	return ua
    48  }
    49  
    50  // LazyClientIP implements String() string and it will
    51  // calls GetClientIP() lazily only when required.
    52  type lazyClientIP struct {
    53  	req *http.Request
    54  }
    55  
    56  func (lazy *lazyClientIP) String() string {
    57  	if lazy.req != nil {
    58  		if ip := utilnet.GetClientIP(lazy.req); ip != nil {
    59  			return ip.String()
    60  		}
    61  	}
    62  	return "unknown"
    63  }
    64  
    65  // lazyAccept implements String() string and it will
    66  // calls http.Request Header.Get() lazily only when required.
    67  type lazyAccept struct {
    68  	req *http.Request
    69  }
    70  
    71  func (lazy *lazyAccept) String() string {
    72  	if lazy.req != nil {
    73  		accept := lazy.req.Header.Get("Accept")
    74  		return accept
    75  	}
    76  
    77  	return "unknown"
    78  }
    79  
    80  // lazyAPIGroup implements String() string and it will
    81  // lazily get Group from request info.
    82  type lazyAPIGroup struct {
    83  	req *http.Request
    84  }
    85  
    86  func (lazy *lazyAPIGroup) String() string {
    87  	if lazy.req != nil {
    88  		ctx := lazy.req.Context()
    89  		requestInfo, ok := apirequest.RequestInfoFrom(ctx)
    90  		if ok {
    91  			return requestInfo.APIGroup
    92  		}
    93  	}
    94  
    95  	return "unknown"
    96  }
    97  
    98  // lazyAPIVersion implements String() string and it will
    99  // lazily get Group from request info.
   100  type lazyAPIVersion struct {
   101  	req *http.Request
   102  }
   103  
   104  func (lazy *lazyAPIVersion) String() string {
   105  	if lazy.req != nil {
   106  		ctx := lazy.req.Context()
   107  		requestInfo, ok := apirequest.RequestInfoFrom(ctx)
   108  		if ok {
   109  			return requestInfo.APIVersion
   110  		}
   111  	}
   112  
   113  	return "unknown"
   114  }
   115  
   116  // lazyName implements String() string and it will
   117  // lazily get Group from request info.
   118  type lazyName struct {
   119  	req *http.Request
   120  }
   121  
   122  func (lazy *lazyName) String() string {
   123  	if lazy.req != nil {
   124  		ctx := lazy.req.Context()
   125  		requestInfo, ok := apirequest.RequestInfoFrom(ctx)
   126  		if ok {
   127  			return requestInfo.Name
   128  		}
   129  	}
   130  
   131  	return "unknown"
   132  }
   133  
   134  // lazySubresource implements String() string and it will
   135  // lazily get Group from request info.
   136  type lazySubresource struct {
   137  	req *http.Request
   138  }
   139  
   140  func (lazy *lazySubresource) String() string {
   141  	if lazy.req != nil {
   142  		ctx := lazy.req.Context()
   143  		requestInfo, ok := apirequest.RequestInfoFrom(ctx)
   144  		if ok {
   145  			return requestInfo.Subresource
   146  		}
   147  	}
   148  
   149  	return "unknown"
   150  }
   151  
   152  // lazyNamespace implements String() string and it will
   153  // lazily get Group from request info.
   154  type lazyNamespace struct {
   155  	req *http.Request
   156  }
   157  
   158  func (lazy *lazyNamespace) String() string {
   159  	if lazy.req != nil {
   160  		ctx := lazy.req.Context()
   161  		requestInfo, ok := apirequest.RequestInfoFrom(ctx)
   162  		if ok {
   163  			return requestInfo.Namespace
   164  		}
   165  	}
   166  
   167  	return "unknown"
   168  }
   169  
   170  // lazyAuditID implements Stringer interface to lazily retrieve
   171  // the audit ID associated with the request.
   172  type lazyAuditID struct {
   173  	req *http.Request
   174  }
   175  
   176  func (lazy *lazyAuditID) String() string {
   177  	if lazy.req != nil {
   178  		return audit.GetAuditIDTruncated(lazy.req.Context())
   179  	}
   180  
   181  	return "unknown"
   182  }
   183  
   184  // lazyVerb implements String() string and it will
   185  // lazily get normalized Verb
   186  type lazyVerb struct {
   187  	req *http.Request
   188  }
   189  
   190  func (lazy *lazyVerb) String() string {
   191  	if lazy.req == nil {
   192  		return "unknown"
   193  	}
   194  	return metrics.NormalizedVerb(lazy.req)
   195  }
   196  
   197  // lazyResource implements String() string and it will
   198  // lazily get Resource from request info
   199  type lazyResource struct {
   200  	req *http.Request
   201  }
   202  
   203  func (lazy *lazyResource) String() string {
   204  	if lazy.req != nil {
   205  		ctx := lazy.req.Context()
   206  		requestInfo, ok := apirequest.RequestInfoFrom(ctx)
   207  		if ok {
   208  			return requestInfo.Resource
   209  		}
   210  	}
   211  
   212  	return "unknown"
   213  }
   214  
   215  // lazyScope implements String() string and it will
   216  // lazily get Scope from request info
   217  type lazyScope struct {
   218  	req *http.Request
   219  }
   220  
   221  func (lazy *lazyScope) String() string {
   222  	if lazy.req != nil {
   223  		ctx := lazy.req.Context()
   224  		requestInfo, ok := apirequest.RequestInfoFrom(ctx)
   225  		if ok {
   226  			return metrics.CleanScope(requestInfo)
   227  		}
   228  	}
   229  
   230  	return "unknown"
   231  }