Skip to content

Commit

Permalink
test/e2e: add HTTPProxy 007,018 and Ingress 001 tests
Browse files Browse the repository at this point in the history
Updates #3621.

Signed-off-by: Steve Kriss <krisss@vmware.com>
  • Loading branch information
skriss committed May 11, 2021
1 parent 20844de commit eb8ff86
Show file tree
Hide file tree
Showing 10 changed files with 946 additions and 1 deletion.
14 changes: 14 additions & 0 deletions test/e2e/certs.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,13 @@ package e2e

import (
"context"
"crypto/tls"

certmanagerv1 "github.com/jetstack/cert-manager/pkg/apis/certmanager/v1"
certmanagermetav1 "github.com/jetstack/cert-manager/pkg/apis/meta/v1"
"github.com/onsi/ginkgo"
"github.com/stretchr/testify/require"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
Expand Down Expand Up @@ -73,3 +75,15 @@ func (c *Certs) CreateSelfSignedCert(ns, name, secretName, dnsName string) func(
require.NoError(c.t, c.client.Delete(context.TODO(), issuer))
}
}

// GetTLSCertificate returns a tls.Certificate containing the data in the specified
// secret. The secret must have the "tls.crt" and "tls.key" keys.
func (c *Certs) GetTLSCertificate(secretNamespace, secretName string) tls.Certificate {
secret := &corev1.Secret{}
require.NoError(c.t, c.client.Get(context.TODO(), client.ObjectKey{Namespace: secretNamespace, Name: secretName}, secret))

cert, err := tls.X509KeyPair(secret.Data["tls.crt"], secret.Data["tls.key"])
require.NoError(c.t, err)

return cert
}
149 changes: 149 additions & 0 deletions test/e2e/fixtures.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ type Fixtures struct {
// test fixture.
Echo *Echo

// EchoSecure provides helpers for working with the TLS-secured
// ingress-conformance-echo-tls test fixture.
EchoSecure *EchoSecure

// HTTPBin provides helpers for working with the kennethreitz/httpbin
// test fixture.
HTTPBin *HTTPBin
Expand Down Expand Up @@ -150,6 +154,151 @@ func (e *Echo) Deploy(ns, name string) func() {
}
}

// EchoSecure manages the TLS-secured ingress-conformance-echo fixture.
type EchoSecure struct {
client client.Client
t ginkgo.GinkgoTInterface
}

// Deploy creates the TLS-secured ingress-conformance-echo-tls fixture, specifically
// the deployment and service, in the given namespace and with the given name, or
// fails the test if it encounters an error. Namespace is defaulted to "default"
// and name is defaulted to "ingress-conformance-echo-tls" if not provided. Returns
// a cleanup function.
func (e *EchoSecure) Deploy(ns, name string) func() {
valOrDefault := func(val, defaultVal string) string {
if val != "" {
return val
}
return defaultVal
}

ns = valOrDefault(ns, "default")
name = valOrDefault(name, "ingress-conformance-echo-tls")

deployment := &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Namespace: ns,
Name: name,
},
Spec: appsv1.DeploymentSpec{
Selector: &metav1.LabelSelector{
MatchLabels: map[string]string{"app.kubernetes.io/name": name},
},
Template: corev1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{"app.kubernetes.io/name": name},
},
Spec: corev1.PodSpec{
Containers: []corev1.Container{
{
Name: "conformance-echo",
Image: "tsaarni/echoserver:latest",
Env: []corev1.EnvVar{
{
Name: "POD_NAME",
ValueFrom: &corev1.EnvVarSource{
FieldRef: &corev1.ObjectFieldSelector{
FieldPath: "metadata.name",
},
},
},
{
Name: "NAMESPACE",
ValueFrom: &corev1.EnvVarSource{
FieldRef: &corev1.ObjectFieldSelector{
FieldPath: "metadata.namespace",
},
},
},
{
Name: "TLS_SERVER_CERT",
Value: "/run/secrets/certs/tls.crt",
},
{
Name: "TLS_SERVER_PRIVKEY",
Value: "/run/secrets/certs/tls.key",
},
{
Name: "TLS_CLIENT_CACERTS",
Value: "/run/secrets/certs/ca.crt",
},
},
Ports: []corev1.ContainerPort{
{
Name: "http-api",
ContainerPort: 3000,
},
{
Name: "https-api",
ContainerPort: 8443,
},
},
ReadinessProbe: &corev1.Probe{
Handler: corev1.Handler{
HTTPGet: &corev1.HTTPGetAction{
Path: "/health",
Port: intstr.FromInt(3000),
},
},
},
VolumeMounts: []corev1.VolumeMount{
{
MountPath: "/run/secrets/certs",
Name: "backend-server-cert",
ReadOnly: true,
},
},
},
},
Volumes: []corev1.Volume{
{
Name: "backend-server-cert",
VolumeSource: corev1.VolumeSource{
Secret: &corev1.SecretVolumeSource{
SecretName: "backend-server-cert",
},
},
},
},
},
},
},
}
require.NoError(e.t, e.client.Create(context.TODO(), deployment))

service := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Namespace: ns,
Name: name,
Annotations: map[string]string{
"projectcontour.io/upstream-protocol.tls": "443",
},
},
Spec: corev1.ServiceSpec{
Ports: []corev1.ServicePort{
{
Name: "http",
Port: 80,
TargetPort: intstr.FromString("http-api"),
},
{
Name: "https",
Port: 443,
TargetPort: intstr.FromString("https-api"),
},
},
Selector: map[string]string{"app.kubernetes.io/name": name},
},
}
require.NoError(e.t, e.client.Create(context.TODO(), service))

return func() {
require.NoError(e.t, e.client.Delete(context.TODO(), service))
require.NoError(e.t, e.client.Delete(context.TODO(), deployment))
}
}

// HTTPBin manages the kennethreitz/httpbin fixture.
type HTTPBin struct {
client client.Client
Expand Down
4 changes: 4 additions & 0 deletions test/e2e/framework.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,10 @@ func NewFramework(t ginkgo.GinkgoTInterface) *Framework {
client: crClient,
t: t,
},
EchoSecure: &EchoSecure{
client: crClient,
t: t,
},
HTTPBin: &HTTPBin{
client: crClient,
t: t,
Expand Down
2 changes: 1 addition & 1 deletion test/e2e/gateway/gateway_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ var _ = Describe("Gateway API", func() {
}

require.NoError(f.T(), f.Client.Create(context.TODO(), gateway))
cleanupCert = f.CreateSelfSignedCert("projectcontour", "tlscert", "tlscert", "tls-gateway.projectcontour.io")
cleanupCert = f.Certs.CreateSelfSignedCert("projectcontour", "tlscert", "tlscert", "tls-gateway.projectcontour.io")
})

AfterEach(func() {
Expand Down
46 changes: 46 additions & 0 deletions test/e2e/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,52 @@ func (h *HTTP) SecureRequestUntil(opts *HTTPSRequestOpts) (*HTTPResponse, bool)
return h.requestUntil(makeRequest, opts.Condition)
}

// SecureRequest makes a single HTTPS request with the provided parameters
// and returns the HTTP response or an error. Note that opts.Condition is
// ignored by this method.
//
// In general, E2E's should use SecureRequestUntil instead of this method since
// SecureRequestUntil will retry requests to account for eventual consistency and
// other ephemeral issues.
func (h *HTTP) SecureRequest(opts *HTTPSRequestOpts) (*HTTPResponse, error) {
req, err := http.NewRequest("GET", h.HTTPSURLBase+opts.Path, nil)
require.NoError(h.t, err, "error creating HTTP request")

req.Host = opts.Host
for _, opt := range opts.RequestOpts {
opt(req)
}

transport := http.DefaultTransport.(*http.Transport).Clone()
transport.TLSClientConfig = &tls.Config{
ServerName: opts.Host,
//nolint:gosec
InsecureSkipVerify: true,
}
for _, opt := range opts.TLSConfigOpts {
opt(transport.TLSClientConfig)
}

client := &http.Client{
Transport: transport,
}

r, err := client.Do(req)
if err != nil {
return nil, err
}
defer r.Body.Close()

bodyBytes, err := ioutil.ReadAll(r.Body)
require.NoError(h.t, err)

return &HTTPResponse{
StatusCode: r.StatusCode,
Headers: r.Header,
Body: bodyBytes,
}, nil
}

func (h *HTTP) requestUntil(makeRequest func() (*http.Response, error), condition func(*http.Response) bool) (*HTTPResponse, bool) {
var res *HTTPResponse

Expand Down
Loading

0 comments on commit eb8ff86

Please sign in to comment.