Skip to content

Instantly share code, notes, and snippets.

@mjudeikis
Last active October 16, 2019 16:49
Show Gist options
  • Save mjudeikis/5e46f33673d2a9d1df95668f06d9591f to your computer and use it in GitHub Desktop.
Save mjudeikis/5e46f33673d2a9d1df95668f06d9591f to your computer and use it in GitHub Desktop.
test private-link dialer
package main
import (
"bufio"
"crypto/tls"
"crypto/x509"
"fmt"
"io/ioutil"
"net"
"net/http"
"os"
"time"
"github.com/Azure/go-autorest/autorest/to"
"github.com/sirupsen/logrus"
"github.com/ghodss/yaml"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
restclient "k8s.io/client-go/rest"
"github.com/openshift/openshift-azure/pkg/api"
"github.com/openshift/openshift-azure/pkg/util/managedcluster"
"github.com/openshift/openshift-azure/pkg/util/roundtrippers"
)
var log *logrus.Entry
var DialHook = net.Dial
type conn struct {
net.Conn
r *bufio.Reader
}
func (c *conn) Read(b []byte) (int, error) {
return c.r.Read(b)
}
func init() {
logrus.SetLevel(logrus.DebugLevel)
logrus.SetFormatter(&logrus.TextFormatter{
FullTimestamp: true,
})
logrus.SetReportCaller(true)
log = logrus.NewEntry(logrus.StandardLogger())
log.Debug("run init")
// read server certifictes
// load proxy configuration for tests
var cert tls.Certificate
// TODO: improve this
if _, err := os.Stat("secrets/proxy-client.pem"); os.IsNotExist(err) {
cert, err = tls.LoadX509KeyPair("../../secrets/proxy-client.pem", "../../secrets/proxy-client.key")
if err != nil {
panic(fmt.Sprintf("server: loadkeys: %s", err))
}
} else {
cert, err = tls.LoadX509KeyPair("secrets/proxy-client.pem", "secrets/proxy-client.key")
if err != nil {
panic(fmt.Sprintf("server: loadkeys: %s", err))
}
}
ca, err := ioutil.ReadFile("secrets/proxy-ca.pem")
if err != nil {
panic(err)
}
proxyEnv := os.Getenv("PROXYURL_AUSTRALIASOUTHEAST")
log.Debug("dial hook")
DialHook = func(network, address string) (net.Conn, error) {
roots := x509.NewCertPool()
ok := roots.AppendCertsFromPEM(ca)
if !ok {
return nil, err
}
c, err := tls.Dial("tcp", proxyEnv+":8443", &tls.Config{
RootCAs: roots,
Certificates: []tls.Certificate{cert},
InsecureSkipVerify: true,
})
if err != nil {
return nil, err
}
// send the client certificate
// verify the server certificate
// don't set insecureskipverify
r := bufio.NewReader(c)
req, err := http.NewRequest(http.MethodConnect, "", nil)
if err != nil {
return nil, err
}
req.Host = address
err = req.Write(c)
if err != nil {
return nil, err
}
resp, err := http.ReadResponse(r, req)
if err != nil {
return nil, err
}
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("unexpected status code %d", resp.StatusCode)
}
log.Debug("connection ok")
return &conn{Conn: c, r: r}, nil
}
log.Debug("dial hook done")
}
func main() {
logrus.SetLevel(logrus.DebugLevel)
logrus.SetFormatter(&logrus.TextFormatter{
FullTimestamp: true,
})
logrus.SetReportCaller(true)
log := logrus.NewEntry(logrus.StandardLogger())
b, err := ioutil.ReadFile("./_data/containerservice.yaml")
if err != nil {
panic(err)
}
var cs *api.OpenShiftManagedCluster
err = yaml.Unmarshal(b, &cs)
if err != nil {
panic(err)
}
cs.Properties.NetworkProfile.PrivateEndpoint = to.StringPtr("172.30.1.4")
restconfig, err := managedcluster.RestConfigFromV1Config(cs.Config.AdminKubeconfig)
if err != nil {
panic(err)
}
tlsConfig, err := restclient.TLSConfigFor(restconfig)
if err != nil {
panic(err)
}
restconfig.WrapTransport = func(rt http.RoundTripper) http.RoundTripper {
rtNew := &http.Transport{
DialTLS: func(network, addr string) (net.Conn, error) {
_, port, err := net.SplitHostPort(addr)
log.Debug(*cs.Properties.NetworkProfile.PrivateEndpoint)
if err != nil {
return nil, err
}
c, err := DialHook(network, net.JoinHostPort(*cs.Properties.NetworkProfile.PrivateEndpoint, port))
if err != nil {
return nil, err
}
// TOFIX: Current certificate does not contain
// SANs/IPs. This causes validation error. Need to regenerate
// new certificate and remove this
tlsConfig.InsecureSkipVerify = true
return tls.Client(c, tlsConfig), nil
},
}
rtNew.DisableKeepAlives = true
// now wrap our RetryingRoundTripper around the incoming RoundTripper.
return &roundtrippers.RetryingRoundTripper{
Log: log,
RoundTripper: rtNew,
Retries: 5,
GetTimeout: 30 * time.Second,
}
}
restconfig.Host = *cs.Properties.NetworkProfile.PrivateEndpoint
log.Print("get clients")
cli, err := kubernetes.NewForConfig(restconfig)
if err != nil {
panic(err)
}
log.Print("get pods")
pods, err := cli.CoreV1().Pods("kube-system").List(metav1.ListOptions{})
if err != nil {
panic(err)
}
for _, pod := range pods.Items {
fmt.Println(pod.Name)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment