mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-01-19 11:19:30 +00:00
120 lines
3.3 KiB
Go
120 lines
3.3 KiB
Go
|
/*
|
||
|
Copyright 2022 The Kubernetes Authors.
|
||
|
|
||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
you may not use this file except in compliance with the License.
|
||
|
You may obtain a copy of the License at
|
||
|
|
||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||
|
|
||
|
Unless required by applicable law or agreed to in writing, software
|
||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
See the License for the specific language governing permissions and
|
||
|
limitations under the License.
|
||
|
*/
|
||
|
|
||
|
package http
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"net"
|
||
|
"net/http"
|
||
|
"net/url"
|
||
|
"strconv"
|
||
|
"strings"
|
||
|
|
||
|
v1 "k8s.io/api/core/v1"
|
||
|
"k8s.io/component-base/version"
|
||
|
"k8s.io/kubernetes/pkg/probe"
|
||
|
)
|
||
|
|
||
|
// NewProbeRequest returns an http.Request suitable for use as a request for a
|
||
|
// probe.
|
||
|
func NewProbeRequest(url *url.URL, headers http.Header) (*http.Request, error) {
|
||
|
return newProbeRequest(url, headers, "probe")
|
||
|
}
|
||
|
|
||
|
// NewRequestForHTTPGetAction returns an http.Request derived from httpGet.
|
||
|
// When httpGet.Host is empty, podIP will be used instead.
|
||
|
func NewRequestForHTTPGetAction(httpGet *v1.HTTPGetAction, container *v1.Container, podIP string, userAgentFragment string) (*http.Request, error) {
|
||
|
scheme := strings.ToLower(string(httpGet.Scheme))
|
||
|
if scheme == "" {
|
||
|
scheme = "http"
|
||
|
}
|
||
|
|
||
|
host := httpGet.Host
|
||
|
if host == "" {
|
||
|
host = podIP
|
||
|
}
|
||
|
|
||
|
port, err := probe.ResolveContainerPort(httpGet.Port, container)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
path := httpGet.Path
|
||
|
url := formatURL(scheme, host, port, path)
|
||
|
headers := v1HeaderToHTTPHeader(httpGet.HTTPHeaders)
|
||
|
|
||
|
return newProbeRequest(url, headers, userAgentFragment)
|
||
|
}
|
||
|
|
||
|
func newProbeRequest(url *url.URL, headers http.Header, userAgentFragment string) (*http.Request, error) {
|
||
|
req, err := http.NewRequest("GET", url.String(), nil)
|
||
|
if err != nil {
|
||
|
return nil, err
|
||
|
}
|
||
|
|
||
|
if headers == nil {
|
||
|
headers = http.Header{}
|
||
|
}
|
||
|
if _, ok := headers["User-Agent"]; !ok {
|
||
|
// User-Agent header was not defined, set it
|
||
|
headers.Set("User-Agent", userAgent(userAgentFragment))
|
||
|
}
|
||
|
if _, ok := headers["Accept"]; !ok {
|
||
|
// Accept header was not defined. accept all
|
||
|
headers.Set("Accept", "*/*")
|
||
|
} else if headers.Get("Accept") == "" {
|
||
|
// Accept header was overridden but is empty. removing
|
||
|
headers.Del("Accept")
|
||
|
}
|
||
|
req.Header = headers
|
||
|
req.Host = headers.Get("Host")
|
||
|
|
||
|
return req, nil
|
||
|
}
|
||
|
|
||
|
func userAgent(purpose string) string {
|
||
|
v := version.Get()
|
||
|
return fmt.Sprintf("kube-%s/%s.%s", purpose, v.Major, v.Minor)
|
||
|
}
|
||
|
|
||
|
// formatURL formats a URL from args. For testability.
|
||
|
func formatURL(scheme string, host string, port int, path string) *url.URL {
|
||
|
u, err := url.Parse(path)
|
||
|
// Something is busted with the path, but it's too late to reject it. Pass it along as is.
|
||
|
//
|
||
|
// This construction of a URL may be wrong in some cases, but it preserves
|
||
|
// legacy prober behavior.
|
||
|
if err != nil {
|
||
|
u = &url.URL{
|
||
|
Path: path,
|
||
|
}
|
||
|
}
|
||
|
u.Scheme = scheme
|
||
|
u.Host = net.JoinHostPort(host, strconv.Itoa(port))
|
||
|
return u
|
||
|
}
|
||
|
|
||
|
// v1HeaderToHTTPHeader takes a list of HTTPHeader <name, value> string pairs
|
||
|
// and returns a populated string->[]string http.Header map.
|
||
|
func v1HeaderToHTTPHeader(headerList []v1.HTTPHeader) http.Header {
|
||
|
headers := make(http.Header)
|
||
|
for _, header := range headerList {
|
||
|
headers.Add(header.Name, header.Value)
|
||
|
}
|
||
|
return headers
|
||
|
}
|