fix(kubernetes): add prefix only when needed EE-6068 (#3915) (#10310)

pull/10315/head
Dakota Walsh 2023-09-15 09:25:56 +12:00 committed by GitHub
parent dcdf5e1837
commit 0a02f6b02e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 73 additions and 36 deletions

View File

@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"net/http" "net/http"
"strconv" "strconv"
"strings"
"sync" "sync"
"time" "time"
@ -154,17 +155,29 @@ func (factory *ClientFactory) createCachedAdminKubeClient(endpoint *portainer.En
}, nil }, nil
} }
// CreateClient returns a pointer to a new Clientset instance // CreateClient returns a pointer to a new Clientset instance.
func (factory *ClientFactory) CreateClient(endpoint *portainer.Endpoint) (*kubernetes.Clientset, error) { func (factory *ClientFactory) CreateClient(endpoint *portainer.Endpoint) (*kubernetes.Clientset, error) {
switch endpoint.Type { switch endpoint.Type {
case portainer.KubernetesLocalEnvironment: case portainer.KubernetesLocalEnvironment, portainer.AgentOnKubernetesEnvironment, portainer.EdgeAgentOnKubernetesEnvironment:
return buildLocalClient() c, err := factory.CreateConfig(endpoint)
case portainer.AgentOnKubernetesEnvironment: if err != nil {
return factory.buildAgentClient(endpoint) return nil, err
case portainer.EdgeAgentOnKubernetesEnvironment: }
return factory.buildEdgeClient(endpoint) return kubernetes.NewForConfig(c)
} }
return nil, errors.New("unsupported environment type")
}
// CreateConfig returns a pointer to a new kubeconfig ready to create a client.
func (factory *ClientFactory) CreateConfig(endpoint *portainer.Endpoint) (*rest.Config, error) {
switch endpoint.Type {
case portainer.KubernetesLocalEnvironment:
return buildLocalConfig()
case portainer.AgentOnKubernetesEnvironment:
return factory.buildAgentConfig(endpoint)
case portainer.EdgeAgentOnKubernetesEnvironment:
return factory.buildEdgeConfig(endpoint)
}
return nil, errors.New("unsupported environment type") return nil, errors.New("unsupported environment type")
} }
@ -184,20 +197,64 @@ func (rt *agentHeaderRoundTripper) RoundTrip(req *http.Request) (*http.Response,
return rt.roundTripper.RoundTrip(req) return rt.roundTripper.RoundTrip(req)
} }
func (factory *ClientFactory) buildAgentClient(endpoint *portainer.Endpoint) (*kubernetes.Clientset, error) { func (factory *ClientFactory) buildAgentConfig(endpoint *portainer.Endpoint) (*rest.Config, error) {
endpointURL := fmt.Sprintf("https://%s/kubernetes", endpoint.URL) var clientURL strings.Builder
if !strings.HasPrefix(endpoint.URL, "http") {
clientURL.WriteString("https://")
}
clientURL.WriteString(endpoint.URL)
clientURL.WriteString("/kubernetes")
return factory.createRemoteClient(endpointURL) signature, err := factory.signatureService.CreateSignature(portainer.PortainerAgentSignatureMessage)
if err != nil {
return nil, err
}
config, err := clientcmd.BuildConfigFromFlags(clientURL.String(), "")
if err != nil {
return nil, err
}
config.Insecure = true
config.QPS = DefaultKubeClientQPS
config.Burst = DefaultKubeClientBurst
config.Wrap(func(rt http.RoundTripper) http.RoundTripper {
return &agentHeaderRoundTripper{
signatureHeader: signature,
publicKeyHeader: factory.signatureService.EncodedPublicKey(),
roundTripper: rt,
}
})
return config, nil
} }
func (factory *ClientFactory) buildEdgeClient(endpoint *portainer.Endpoint) (*kubernetes.Clientset, error) { func (factory *ClientFactory) buildEdgeConfig(endpoint *portainer.Endpoint) (*rest.Config, error) {
tunnel, err := factory.reverseTunnelService.GetActiveTunnel(endpoint) tunnel, err := factory.reverseTunnelService.GetActiveTunnel(endpoint)
if err != nil { if err != nil {
return nil, errors.Wrap(err, "failed activating tunnel") return nil, errors.Wrap(err, "failed activating tunnel")
} }
endpointURL := fmt.Sprintf("http://127.0.0.1:%d/kubernetes", tunnel.Port) endpointURL := fmt.Sprintf("http://127.0.0.1:%d/kubernetes", tunnel.Port)
return factory.createRemoteClient(endpointURL) config, err := clientcmd.BuildConfigFromFlags(endpointURL, "")
if err != nil {
return nil, err
}
signature, err := factory.signatureService.CreateSignature(portainer.PortainerAgentSignatureMessage)
config.Insecure = true
config.QPS = DefaultKubeClientQPS
config.Burst = DefaultKubeClientBurst
config.Wrap(func(rt http.RoundTripper) http.RoundTripper {
return &agentHeaderRoundTripper{
signatureHeader: signature,
publicKeyHeader: factory.signatureService.EncodedPublicKey(),
roundTripper: rt,
}
})
return config, nil
} }
func (factory *ClientFactory) createRemoteClient(endpointURL string) (*kubernetes.Clientset, error) { func (factory *ClientFactory) createRemoteClient(endpointURL string) (*kubernetes.Clientset, error) {
@ -227,34 +284,14 @@ func (factory *ClientFactory) createRemoteClient(endpointURL string) (*kubernete
} }
func (factory *ClientFactory) CreateRemoteMetricsClient(endpoint *portainer.Endpoint) (*metricsv.Clientset, error) { func (factory *ClientFactory) CreateRemoteMetricsClient(endpoint *portainer.Endpoint) (*metricsv.Clientset, error) {
endpointURL := fmt.Sprintf("https://%s/kubernetes", endpoint.URL) config, err := factory.CreateConfig(endpoint)
signature, err := factory.signatureService.CreateSignature(portainer.PortainerAgentSignatureMessage)
if err != nil { if err != nil {
return nil, err return nil, fmt.Errorf("failed to create metrics KubeConfig")
} }
config, err := clientcmd.BuildConfigFromFlags(endpointURL, "")
if err != nil {
return nil, err
}
config.Insecure = true
config.QPS = DefaultKubeClientQPS
config.Burst = DefaultKubeClientBurst
config.Wrap(func(rt http.RoundTripper) http.RoundTripper {
return &agentHeaderRoundTripper{
signatureHeader: signature,
publicKeyHeader: factory.signatureService.EncodedPublicKey(),
roundTripper: rt,
}
})
return metricsv.NewForConfig(config) return metricsv.NewForConfig(config)
} }
func buildLocalClient() (*kubernetes.Clientset, error) { func buildLocalConfig() (*rest.Config, error) {
config, err := rest.InClusterConfig() config, err := rest.InClusterConfig()
if err != nil { if err != nil {
return nil, err return nil, err
@ -263,7 +300,7 @@ func buildLocalClient() (*kubernetes.Clientset, error) {
config.QPS = DefaultKubeClientQPS config.QPS = DefaultKubeClientQPS
config.Burst = DefaultKubeClientBurst config.Burst = DefaultKubeClientBurst
return kubernetes.NewForConfig(config) return config, nil
} }
func (factory *ClientFactory) MigrateEndpointIngresses(e *portainer.Endpoint) error { func (factory *ClientFactory) MigrateEndpointIngresses(e *portainer.Endpoint) error {