// Copyright (c) 2020 Gitpod GmbH. All rights reserved. // Licensed under the GNU Affero General Public License (AGPL). // See License-AGPL.txt in the project root for license information. package dart import ( "bytes" "context" "fmt" "math/rand" "net/http" "net/url" "regexp" "strings" "sync" toxiproxy "github.com/Shopify/toxiproxy/client" log "github.com/sirupsen/logrus" "k8s.io/client-go/rest" "k8s.io/client-go/tools/portforward" "k8s.io/client-go/transport/spdy" ) const ( // port to toxiproxy's control plane API toxiproxyPort = 8474 ) // ProxiedToxiproxy provides a connection to a toxiproxy pod type ProxiedToxiproxy struct { *toxiproxy.Client closer func() } // NewProxiedToxiproxy connects to a Toxiproxy pod func NewProxiedToxiproxy(cfg *rest.Config, namespace, pod string) (*ProxiedToxiproxy, error) { localPort := rand.Intn(2000) + 31000 ctx, cancel := context.WithCancel(context.Background()) defer cancel() readychan, errchan := forwardPort(ctx, cfg, namespace, pod, fmt.Sprintf("%d:%d", localPort, toxiproxyPort)) select { case <-readychan: case err := <-errchan: return nil, err } log.WithField("port", localPort).Info("forwarding control API of toxiproxy") tpc := toxiproxy.NewClient(fmt.Sprintf("localhost:%d", localPort)) return &ProxiedToxiproxy{ Client: tpc, closer: cancel, }, nil } // Close shuts down the connection to the toxiproxy pod func (p *ProxiedToxiproxy) Close() error { p.closer() return nil } var kubernetesDialerAddrRegexp = regexp.MustCompile(`(?P[\w-\.]+)\/(?P