Skip to content

Commit

Permalink
Added full-fledged testing with mTLS http server
Browse files Browse the repository at this point in the history
  • Loading branch information
scr-oath committed Oct 14, 2022
1 parent 2ce0db2 commit a84020e
Show file tree
Hide file tree
Showing 14 changed files with 792 additions and 116 deletions.
3 changes: 2 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ require (
github.com/pkg/errors v0.9.1
github.com/posener/complete v1.2.3
github.com/spf13/afero v1.2.2
github.com/stretchr/testify v1.8.0
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.232
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/tag v1.0.233
github.com/tencentyun/cos-go-sdk-v5 v0.7.29
Expand Down Expand Up @@ -161,12 +162,12 @@ require (
github.com/mozillazg/go-httpheader v0.3.0 // indirect
github.com/nu7hatch/gouuid v0.0.0-20131221200532-179d4d0c4d8d // indirect
github.com/oklog/run v1.0.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/satori/go.uuid v1.2.0 // indirect
github.com/sergi/go-diff v1.2.0 // indirect
github.com/shopspring/decimal v1.2.0 // indirect
github.com/spf13/cast v1.3.1 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/stretchr/objx v0.1.1 // indirect
github.com/ulikunitz/xz v0.5.8 // indirect
github.com/vmihailenco/msgpack/v4 v4.3.12 // indirect
github.com/vmihailenco/tagparser v0.1.1 // indirect
Expand Down
6 changes: 4 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -580,15 +580,17 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0 h1:M2gUjqZET1qApGOWNSnZ49BAIMX4F/1plDv3+l31EJ4=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.194/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.232 h1:kwsWbh4rEw42ZDe9/812ebhbwNZxlQyZ2sTmxBOKhN4=
github.com/tencentcloud/tencentcloud-sdk-go/tencentcloud/common v1.0.232/go.mod h1:7sCQWVkxcsR38nffDW057DRGk8mUjK1Ing/EFOK8s8Y=
Expand Down
113 changes: 0 additions & 113 deletions internal/backend/remote-state/http/backend_test.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
package http

import (
"crypto/rsa"
"crypto/tls"
"crypto/x509"
"encoding/pem"
"io"
"net/http"
"net/http/httptest"
"os"
"testing"
"time"
Expand Down Expand Up @@ -169,109 +162,3 @@ func testWithEnv(t *testing.T, key string, value string) func() {
}
}
}

const sampleState = `
{
"version": 4,
"serial": 0,
"lineage": "666f9301-7e65-4b19-ae23-71184bb19b03",
"remote": {
"type": "http",
"config": {
"path": "local-state.tfstate"
}
}
}
`

func testCerts(t *testing.T, server *httptest.Server) (certFile, keyFile string) {
// Create the CERTIFICATE
f, err := os.CreateTemp(os.TempDir(), "cert.*")
if err != nil {
t.Fatal(err)
}
certFile = f.Name()
t.Cleanup(func() {
_ = os.Remove(certFile)
})
cert := server.TLS.Certificates[0]
for _, certData := range cert.Certificate {
if err = pem.Encode(f, &pem.Block{Type: "CERTIFICATE", Bytes: certData}); err != nil {
t.Fatal(err)
}
}
f.Close()

// Create the RSA PRIVATE KEY
if f, err = os.CreateTemp(os.TempDir(), "key.*"); err != nil {
t.Fatal(err)
}
keyFile = f.Name()
t.Cleanup(func() {
_ = os.Remove(keyFile)
})
if err = pem.Encode(f, &pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: x509.MarshalPKCS1PrivateKey(cert.PrivateKey.(*rsa.PrivateKey)),
}); err != nil {
t.Fatal(err)
}
return
}

func TestMTLS(t *testing.T) {
ts := httptest.NewUnstartedServer(http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
_, _ = io.WriteString(writer, sampleState)
}))
ts.TLS = &tls.Config{
ClientAuth: tls.RequireAnyClientCert,
}
ts.StartTLS()
defer ts.Close()

url := ts.URL + "/state"

t.Run("fail with no client cert", func(t *testing.T) {
conf := map[string]cty.Value{
"address": cty.StringVal(url),
"skip_cert_verification": cty.BoolVal(true),
}
b := backend.TestBackendConfig(t, New(), configs.SynthBody("synth", conf)).(*Backend)
if b == nil {
t.Fatalf("nil b")
}
sm, err := b.StateMgr(backend.DefaultStateName)
if err != nil {
t.Fatal(err)
}
if err := sm.RefreshState(); err == nil {
t.Fatal("expected error refreshing state because no client cert is passed")
}
})

t.Run("pass with cacert and client cert", func(t *testing.T) {
certFile, keyFile := testCerts(t, ts)

conf := map[string]cty.Value{
"address": cty.StringVal(url),
"client_ca_certificate_pem": cty.StringVal(certFile),
"client_certificate_pem": cty.StringVal(certFile),
"client_private_key_pem": cty.StringVal(keyFile),
}
b := backend.TestBackendConfig(t, New(), configs.SynthBody("synth", conf)).(*Backend)
if b == nil {
t.Fatalf("nil b")
}
sm, err := b.StateMgr(backend.DefaultStateName)
if err != nil {
t.Fatal(err)
}
if err = sm.RefreshState(); err != nil {
t.Fatal(err)
}
state := sm.State()
if state == nil {
t.Fatal("nil state")
}
})
}
95 changes: 95 additions & 0 deletions internal/backend/remote-state/http/mock_server_test.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit a84020e

Please sign in to comment.