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 }