k8s.io/kubernetes@v1.29.3/pkg/registry/core/pod/rest/log.go (about) 1 /* 2 Copyright 2014 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 rest 18 19 import ( 20 "context" 21 "fmt" 22 23 utilruntime "k8s.io/apimachinery/pkg/util/runtime" 24 25 "k8s.io/apimachinery/pkg/api/errors" 26 "k8s.io/apimachinery/pkg/runtime" 27 genericregistry "k8s.io/apiserver/pkg/registry/generic/registry" 28 genericrest "k8s.io/apiserver/pkg/registry/generic/rest" 29 "k8s.io/apiserver/pkg/registry/rest" 30 api "k8s.io/kubernetes/pkg/apis/core" 31 "k8s.io/kubernetes/pkg/apis/core/validation" 32 "k8s.io/kubernetes/pkg/kubelet/client" 33 "k8s.io/kubernetes/pkg/registry/core/pod" 34 35 // ensure types are installed 36 _ "k8s.io/kubernetes/pkg/apis/core/install" 37 ) 38 39 // LogREST implements the log endpoint for a Pod 40 type LogREST struct { 41 KubeletConn client.ConnectionInfoGetter 42 Store *genericregistry.Store 43 } 44 45 // LogREST implements GetterWithOptions 46 var _ = rest.GetterWithOptions(&LogREST{}) 47 48 // New creates a new Pod log options object 49 func (r *LogREST) New() runtime.Object { 50 // TODO - return a resource that represents a log 51 return &api.Pod{} 52 } 53 54 // Destroy cleans up resources on shutdown. 55 func (r *LogREST) Destroy() { 56 // Given that underlying store is shared with REST, 57 // we don't destroy it here explicitly. 58 } 59 60 // ProducesMIMETypes returns a list of the MIME types the specified HTTP verb (GET, POST, DELETE, 61 // PATCH) can respond with. 62 func (r *LogREST) ProducesMIMETypes(verb string) []string { 63 // Since the default list does not include "plain/text", we need to 64 // explicitly override ProducesMIMETypes, so that it gets added to 65 // the "produces" section for pods/{name}/log 66 return []string{ 67 "text/plain", 68 } 69 } 70 71 // ProducesObject returns an object the specified HTTP verb respond with. It will overwrite storage object if 72 // it is not nil. Only the type of the return object matters, the value will be ignored. 73 func (r *LogREST) ProducesObject(verb string) interface{} { 74 return "" 75 } 76 77 // Get retrieves a runtime.Object that will stream the contents of the pod log 78 func (r *LogREST) Get(ctx context.Context, name string, opts runtime.Object) (runtime.Object, error) { 79 // register the metrics if the context is used. This assumes sync.Once is fast. If it's not, it could be an init block. 80 registerMetrics() 81 82 logOpts, ok := opts.(*api.PodLogOptions) 83 if !ok { 84 return nil, fmt.Errorf("invalid options object: %#v", opts) 85 } 86 87 countSkipTLSMetric(logOpts.InsecureSkipTLSVerifyBackend) 88 89 if errs := validation.ValidatePodLogOptions(logOpts); len(errs) > 0 { 90 return nil, errors.NewInvalid(api.Kind("PodLogOptions"), name, errs) 91 } 92 location, transport, err := pod.LogLocation(ctx, r.Store, r.KubeletConn, name, logOpts) 93 if err != nil { 94 return nil, err 95 } 96 return &genericrest.LocationStreamer{ 97 Location: location, 98 Transport: transport, 99 ContentType: "text/plain", 100 Flush: logOpts.Follow, 101 ResponseChecker: genericrest.NewGenericHttpResponseChecker(api.Resource("pods/log"), name), 102 RedirectChecker: genericrest.PreventRedirects, 103 TLSVerificationErrorCounter: podLogsTLSFailure, 104 DeprecatedTLSVerificationErrorCounter: deprecatedPodLogsTLSFailure, 105 }, nil 106 } 107 108 func countSkipTLSMetric(insecureSkipTLSVerifyBackend bool) { 109 usageType := usageEnforce 110 if insecureSkipTLSVerifyBackend { 111 usageType = usageSkipAllowed 112 } 113 114 counter, err := podLogsUsage.GetMetricWithLabelValues(usageType) 115 if err != nil { 116 utilruntime.HandleError(err) 117 return 118 } 119 counter.Inc() 120 121 deprecatedPodLogsUsage.WithLabelValues(usageType).Inc() 122 } 123 124 // NewGetOptions creates a new options object 125 func (r *LogREST) NewGetOptions() (runtime.Object, bool, string) { 126 return &api.PodLogOptions{}, false, "" 127 } 128 129 // OverrideMetricsVerb override the GET verb to CONNECT for pod log resource 130 func (r *LogREST) OverrideMetricsVerb(oldVerb string) (newVerb string) { 131 newVerb = oldVerb 132 133 if oldVerb == "GET" { 134 newVerb = "CONNECT" 135 } 136 137 return 138 }