mirror of https://github.com/linkerd/linkerd2.git
222 lines
8.9 KiB
Go
222 lines
8.9 KiB
Go
package iptablestest
|
|
|
|
import (
|
|
"fmt"
|
|
"io/ioutil"
|
|
"net/http"
|
|
"net/url"
|
|
"os"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
const (
|
|
ignoredContainerPort = "7070"
|
|
proxyContainerPort = "8080"
|
|
notTheProxyContainerPort = "9090"
|
|
integrationTestsEnvironmentVariable = "CONDUIT_INTEGRATION_TESTS_ENABLED"
|
|
)
|
|
|
|
func TestPodWithNoRules(t *testing.T) {
|
|
podWithNoRulesIp := os.Getenv("POD_WITH_NO_RULES_IP")
|
|
svcName := "svc-pod-with-no-rules"
|
|
|
|
t.Run("succeeds connecting to pod directly through container's exposed port", func(t *testing.T) {
|
|
checkIfIntegrationTestsAreEnabled(t)
|
|
expectSuccessfulGetRequestTo(t, podWithNoRulesIp, proxyContainerPort)
|
|
})
|
|
|
|
t.Run("fails to connect to pod directly through any port that isn't the container's exposed port", func(t *testing.T) {
|
|
checkIfIntegrationTestsAreEnabled(t)
|
|
expectCannotConnectGetRequestTo(t, podWithNoRulesIp, "8088")
|
|
expectCannotConnectGetRequestTo(t, podWithNoRulesIp, "8888")
|
|
expectCannotConnectGetRequestTo(t, podWithNoRulesIp, "8988")
|
|
})
|
|
|
|
t.Run("succeeds connecting to pod via a service through container's exposed port", func(t *testing.T) {
|
|
checkIfIntegrationTestsAreEnabled(t)
|
|
expectSuccessfulGetRequestTo(t, svcName, proxyContainerPort)
|
|
})
|
|
|
|
t.Run("fails to connect to pod via a service through any port that isn't the container's exposed port", func(t *testing.T) {
|
|
checkIfIntegrationTestsAreEnabled(t)
|
|
expectCannotConnectGetRequestTo(t, svcName, "8088")
|
|
expectCannotConnectGetRequestTo(t, svcName, "8888")
|
|
expectCannotConnectGetRequestTo(t, svcName, "8988")
|
|
})
|
|
}
|
|
|
|
func TestPodRedirectsAllPorts(t *testing.T) {
|
|
podRedirectsAllPortsIp := os.Getenv("POD_REDIRECTS_ALL_PORTS_IP")
|
|
svcName := "svc-pod-redirects-all-ports"
|
|
|
|
t.Run("succeeds connecting to pod directly through container's exposed port", func(t *testing.T) {
|
|
checkIfIntegrationTestsAreEnabled(t)
|
|
expectSuccessfulGetRequestTo(t, podRedirectsAllPortsIp, proxyContainerPort)
|
|
})
|
|
|
|
t.Run("succeeds connecting to pod directly through any port that isn't the container's exposed port", func(t *testing.T) {
|
|
checkIfIntegrationTestsAreEnabled(t)
|
|
expectSuccessfulGetRequestTo(t, podRedirectsAllPortsIp, "8088")
|
|
expectSuccessfulGetRequestTo(t, podRedirectsAllPortsIp, "8888")
|
|
expectSuccessfulGetRequestTo(t, podRedirectsAllPortsIp, "8988")
|
|
|
|
})
|
|
|
|
t.Run("succeeds connecting to pod via a service through container's exposed port", func(t *testing.T) {
|
|
checkIfIntegrationTestsAreEnabled(t)
|
|
expectSuccessfulGetRequestTo(t, svcName, proxyContainerPort)
|
|
})
|
|
|
|
t.Run("fails to connect to pod via a service through any port that isn't the container's exposed port", func(t *testing.T) {
|
|
checkIfIntegrationTestsAreEnabled(t)
|
|
expectCannotConnectGetRequestTo(t, svcName, "8088")
|
|
expectCannotConnectGetRequestTo(t, svcName, "8888")
|
|
expectCannotConnectGetRequestTo(t, svcName, "8988")
|
|
})
|
|
}
|
|
|
|
func TestPodWithSomePortsRedirected(t *testing.T) {
|
|
podRedirectsSomePortsIp := os.Getenv("POD_REDIRECTS_WHITELISTED_IP")
|
|
|
|
t.Run("succeeds connecting to pod directly through container's exposed port", func(t *testing.T) {
|
|
checkIfIntegrationTestsAreEnabled(t)
|
|
expectSuccessfulGetRequestTo(t, podRedirectsSomePortsIp, proxyContainerPort)
|
|
})
|
|
|
|
t.Run("succeeds connecting to pod directly through ports configured to redirect", func(t *testing.T) {
|
|
checkIfIntegrationTestsAreEnabled(t)
|
|
expectSuccessfulGetRequestTo(t, podRedirectsSomePortsIp, "9090")
|
|
expectSuccessfulGetRequestTo(t, podRedirectsSomePortsIp, "9099")
|
|
})
|
|
|
|
t.Run("fails to connect to pod via through any port that isn't configured to redirect", func(t *testing.T) {
|
|
checkIfIntegrationTestsAreEnabled(t)
|
|
expectCannotConnectGetRequestTo(t, podRedirectsSomePortsIp, "8088")
|
|
expectCannotConnectGetRequestTo(t, podRedirectsSomePortsIp, "8888")
|
|
expectCannotConnectGetRequestTo(t, podRedirectsSomePortsIp, "8988")
|
|
})
|
|
}
|
|
|
|
func TestPodWithSomePortsIgnored(t *testing.T) {
|
|
podIgnoredSomePortsIp := os.Getenv("POD_DOEST_REDIRECT_BLACKLISTED_IP")
|
|
|
|
t.Run("succeeds connecting to pod directly through container's exposed port", func(t *testing.T) {
|
|
checkIfIntegrationTestsAreEnabled(t)
|
|
expectSuccessfulGetRequestTo(t, podIgnoredSomePortsIp, proxyContainerPort)
|
|
})
|
|
|
|
t.Run("succeeds connecting to pod directly through ports configured to redirect", func(t *testing.T) {
|
|
checkIfIntegrationTestsAreEnabled(t)
|
|
expectSuccessfulGetRequestTo(t, podIgnoredSomePortsIp, "9090")
|
|
expectSuccessfulGetRequestTo(t, podIgnoredSomePortsIp, "9099")
|
|
})
|
|
|
|
t.Run("doesnt redirect when through port that is ignored", func(t *testing.T) {
|
|
checkIfIntegrationTestsAreEnabled(t)
|
|
response := expectSuccessfulGetRequestTo(t, podIgnoredSomePortsIp, ignoredContainerPort)
|
|
|
|
if response == "proxy" {
|
|
t.Fatalf("Expected connection through ignored port to directly hit service, but hit [%s]", response)
|
|
}
|
|
|
|
if !strings.Contains(response, ignoredContainerPort) {
|
|
t.Fatalf("Expected to be able to connect to %s without redirects, but got back %s", ignoredContainerPort, response)
|
|
}
|
|
})
|
|
}
|
|
|
|
func TestPodMakesOutboundConnection(t *testing.T) {
|
|
podIgnoredSomePortsIp := os.Getenv("POD_DOEST_REDIRECT_BLACKLISTED_IP")
|
|
podWithNoRulesIp := os.Getenv("POD_WITH_NO_RULES_IP")
|
|
podWithNoRulesName := "pod-with-no-rules"
|
|
|
|
proxyPodName := "pod-doesnt-redirect-blacklisted"
|
|
proxyPodIp := podIgnoredSomePortsIp
|
|
|
|
t.Run("connecting to another pod from non-proxy container gets redirected to proxy", func(t *testing.T) {
|
|
checkIfIntegrationTestsAreEnabled(t)
|
|
portOfContainerToMAkeTheRequest := ignoredContainerPort
|
|
targetPodIp := podWithNoRulesIp
|
|
targetPort := ignoredContainerPort
|
|
|
|
response := makeCallFromContainerToAnother(t, proxyPodIp, portOfContainerToMAkeTheRequest, targetPodIp, targetPort)
|
|
|
|
expectedDownstreamResponse := fmt.Sprintf("me:[%s:%s]downstream:[proxy]", proxyPodName, portOfContainerToMAkeTheRequest)
|
|
if !strings.Contains(response, expectedDownstreamResponse) {
|
|
t.Fatalf("Expected response to be redirected to the proxy, expected %s but it was %s", expectedDownstreamResponse, response)
|
|
}
|
|
})
|
|
|
|
t.Run("connecting to another pod from proxy container does not get redirected to proxy", func(t *testing.T) {
|
|
checkIfIntegrationTestsAreEnabled(t)
|
|
targetPodName := podWithNoRulesName
|
|
targetPodIp := podWithNoRulesIp
|
|
|
|
response := makeCallFromContainerToAnother(t, proxyPodIp, proxyContainerPort, targetPodIp, notTheProxyContainerPort)
|
|
|
|
expectedDownstreamResponse := fmt.Sprintf("me:[proxy]downstream:[%s:%s]", targetPodName, notTheProxyContainerPort)
|
|
if !strings.Contains(response, expectedDownstreamResponse) {
|
|
t.Fatalf("Expected response not to be redirected to the proxy, expected %s but it was %s", expectedDownstreamResponse, response)
|
|
}
|
|
})
|
|
|
|
t.Run("connecting to loopback from non-proxy container does not get redirected to proxy", func(t *testing.T) {
|
|
checkIfIntegrationTestsAreEnabled(t)
|
|
|
|
response := makeCallFromContainerToAnother(t, proxyPodIp, ignoredContainerPort, "127.0.0.1", notTheProxyContainerPort)
|
|
|
|
expectedDownstreamResponse := fmt.Sprintf("me:[%s:%s]downstream:[%s:%s]", proxyPodName, ignoredContainerPort, proxyPodName, notTheProxyContainerPort)
|
|
if !strings.Contains(response, expectedDownstreamResponse) {
|
|
t.Fatalf("Expected response not to be redirected to the proxy, expected %s but it was %s", expectedDownstreamResponse, response)
|
|
}
|
|
})
|
|
}
|
|
|
|
func makeCallFromContainerToAnother(t *testing.T, fromPodNamed string, fromContainerAtPort string, podIWantToReachName string, containerPortIWantToReach string) string {
|
|
downstreamUrl := fmt.Sprintf("http://%s:%s", podIWantToReachName, containerPortIWantToReach)
|
|
|
|
//Make request asking target to make a back-end request
|
|
targetUrl := fmt.Sprintf("http://%s:%s/call?url=%s", fromPodNamed, fromContainerAtPort, url.QueryEscape(downstreamUrl))
|
|
return expectSuccessfulGetRequestToUrl(t, targetUrl)
|
|
}
|
|
|
|
func checkIfIntegrationTestsAreEnabled(t *testing.T) {
|
|
if _, isSet := os.LookupEnv(integrationTestsEnvironmentVariable); !isSet {
|
|
fmt.Printf("=> Environment variable [%s] isn't set, skipping this test\n", integrationTestsEnvironmentVariable)
|
|
t.SkipNow()
|
|
} else {
|
|
t.Parallel()
|
|
}
|
|
}
|
|
|
|
func expectCannotConnectGetRequestTo(t *testing.T, host string, port string) {
|
|
targetUrl := fmt.Sprintf("http://%s:%s/", host, port)
|
|
fmt.Printf("Expecting failed GET to %s\n", targetUrl)
|
|
resp, err := http.Get(targetUrl)
|
|
if err == nil {
|
|
t.Fatalf("Expected error when connecting to %s, got:\n%+v", targetUrl, resp)
|
|
}
|
|
}
|
|
|
|
func expectSuccessfulGetRequestTo(t *testing.T, host string, port string) string {
|
|
targetUrl := fmt.Sprintf("http://%s:%s/", host, port)
|
|
|
|
return expectSuccessfulGetRequestToUrl(t, targetUrl)
|
|
}
|
|
|
|
func expectSuccessfulGetRequestToUrl(t *testing.T, url string) string {
|
|
fmt.Printf("Expecting successful GET to %s\n", url)
|
|
resp, err := http.Get(url)
|
|
if err != nil {
|
|
t.Fatalf("failed to send HTTP GET to %s:\n%v", url, err)
|
|
}
|
|
body, err := ioutil.ReadAll(resp.Body)
|
|
if err != nil {
|
|
t.Fatalf("failed reading GET response from %s:\n%v", url, err)
|
|
}
|
|
response := string(body)
|
|
fmt.Printf("Response from %s: %s", url, response)
|
|
return response
|
|
}
|