Skip to content

Commit

Permalink
Merge pull request #189 from alphagov/185765111-tls-support
Browse files Browse the repository at this point in the history
185765111 tls support
  • Loading branch information
dark5un committed Dec 15, 2023
2 parents ab5b56a + 095d8ec commit 0c1015d
Show file tree
Hide file tree
Showing 17 changed files with 1,063 additions and 130 deletions.
174 changes: 93 additions & 81 deletions CONFIGURATION.md

Large diffs are not rendered by default.

6 changes: 5 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ MYSQL_PASSWORD=toor
integration:
go run github.com/onsi/ginkgo/v2/ginkgo --timeout=5h --nodes=4 -r ci/blackbox --slowSpecThreshold=1800 -stream -failFast

.PHONY: tls_integration
tls_integration:
go run github.com/onsi/ginkgo/v2/ginkgo --timeout=5h -r ci/tls --slowSpecThreshold=1800 -stream -failFast

.PHONY: unit
unit: test_unit test_all_sql

Expand All @@ -14,7 +18,7 @@ test_unit:
.PHONY: test_all_sql
test_all_sql: test_postgres test_mysql
.PHONY: test_postgres
test_postgres: run_postgres_sql_tests start_postgres_10 run_postgres_sql_tests stop_postgres_10 start_postgres_11 run_postgres_sql_tests stop_postgres_11 start_postgres_12 run_postgres_sql_tests stop_postgres_12 start_postgres_13 run_postgres_sql_tests stop_postgres_13
test_postgres: start_postgres_10 run_postgres_sql_tests stop_postgres_10 start_postgres_11 run_postgres_sql_tests stop_postgres_11 start_postgres_12 run_postgres_sql_tests stop_postgres_12 start_postgres_13 run_postgres_sql_tests stop_postgres_13
.PHONY: test_mysql
test_mysql: start_mysql_80 run_mysql_sql_tests stop_mysql_80 start_mysql_57 run_mysql_sql_tests stop_mysql_57

Expand Down
2 changes: 1 addition & 1 deletion ci/blackbox/rdsbroker_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1163,7 +1163,7 @@ func startNewBroker(rdsBrokerConfig *config.Config, brokerName string) (*gexec.S
// Wait for it to be listening
Eventually(rdsBrokerSession, 10*time.Second).Should(And(
gbytes.Say("rds-broker.start"),
gbytes.Say(fmt.Sprintf(`{"port":%d}`, rdsBrokerPort)),
gbytes.Say(fmt.Sprintf(`{"address":"0.0.0.0:%d","host":"0.0.0.0","port":%d,"tls":false}`, rdsBrokerPort, rdsBrokerPort)),
))

rdsBrokerUrl := fmt.Sprintf("http://localhost:%d", rdsBrokerPort)
Expand Down
31 changes: 23 additions & 8 deletions ci/helpers/brokerapi_helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package helpers

import (
"bytes"
"crypto/tls"
"encoding/json"
"fmt"
"io"
Expand Down Expand Up @@ -47,23 +48,37 @@ func BodyBytes(resp *http.Response) ([]byte, error) {
}

type BrokerAPIClient struct {
Url string
Username string
Password string
AcceptsIncomplete bool
Url string
Username string
Password string
AcceptsIncomplete bool
AcceptsSelfSignedCerts bool
}

func NewBrokerAPIClient(Url string, Username string, Password string) *BrokerAPIClient {
return &BrokerAPIClient{
Url: Url,
Username: Username,
Password: Password,
Url: Url,
Username: Username,
Password: Password,
AcceptsSelfSignedCerts: true,
}
}

func (b *BrokerAPIClient) doRequest(action string, path string, body io.Reader, params ...uriParam) (*http.Response, error) {

client := &http.Client{}
var client *http.Client
if b.AcceptsSelfSignedCerts {
client = &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
},
}
} else {
client = &http.Client{}

}

req, err := http.NewRequest(action, b.Url+path, body)
if err != nil {
Expand Down
1 change: 1 addition & 0 deletions ci/integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,5 @@ run:
- -c
- |
cd src/github.com/alphagov/paas-rds-broker
make tls_integration
make integration
566 changes: 566 additions & 0 deletions ci/tls/config.json

Large diffs are not rendered by default.

17 changes: 17 additions & 0 deletions ci/tls/tls_suite_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package tls_test

import (
"testing"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
)

type SuiteData struct {
RdsBrokerPath string
}

func TestTls(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "Tls Suite")
}
139 changes: 139 additions & 0 deletions ci/tls/tls_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
package tls_test

import (
"crypto/rand"
"crypto/rsa"
"crypto/x509"
"crypto/x509/pkix"
"encoding/json"
"encoding/pem"
"fmt"
"math/big"
"os"
"os/exec"
"path/filepath"
"time"

. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
uuid "github.com/satori/go.uuid"

. "github.com/alphagov/paas-rds-broker/ci/helpers"
"github.com/alphagov/paas-rds-broker/config"
"github.com/onsi/gomega/gbytes"
"github.com/onsi/gomega/gexec"
"github.com/phayes/freeport"
)

var (
rdsBrokerSession *gexec.Session
brokerAPIClient *BrokerAPIClient
brokerName string
rdsBrokerPath string
)

var _ = Describe("TLS Support", func() {
BeforeEach(func() {
var err error

// Give a different Broker Name in each execution, to avoid conflicts
brokerName = fmt.Sprintf(
"%s-%s",
"rdsbroker-integration-test",
uuid.NewV4().String(),
)
rdsBrokerPath, err = gexec.Build("github.com/alphagov/paas-rds-broker")
Expect(err).ShouldNot(HaveOccurred())

jsonConfigFilename := "config.json"
jsonFilePath, err := filepath.Abs(jsonConfigFilename)
Expect(err).ShouldNot(HaveOccurred())

jsonData, err := os.ReadFile(jsonFilePath)
Expect(err).ShouldNot(HaveOccurred())

var testConfig config.Config
err = json.Unmarshal(jsonData, &testConfig)
Expect(err).ShouldNot(HaveOccurred())

rdsBrokerSession, brokerAPIClient, _ = startNewBroker(&testConfig, brokerName)
})

AfterEach(func() {
rdsBrokerSession.Kill()
})

Describe("Services", func() {
It("returns the proper CatalogResponse", func() {
_, err := brokerAPIClient.GetCatalog()
Expect(err).ToNot(HaveOccurred())
})
})
})

func startNewBroker(rdsBrokerConfig *config.Config, brokerName string) (*gexec.Session, *BrokerAPIClient, *RDSClient) {
configFile, err := os.CreateTemp("", "rds-broker")
Expect(err).ToNot(HaveOccurred())
defer os.Remove(configFile.Name())

newRDSBrokerConfig := *rdsBrokerConfig
// start the broker in a random port
rdsBrokerPort := freeport.GetPort()
newRDSBrokerConfig.Port = rdsBrokerPort

newRDSBrokerConfig.RDSConfig.BrokerName = "tls_broker"

priv, err := rsa.GenerateKey(rand.Reader, 2048)
Expect(err).NotTo(HaveOccurred())

template := x509.Certificate{
SerialNumber: big.NewInt(1),
Subject: pkix.Name{
Organization: []string{"Acme Co"},
},
NotBefore: time.Now(),
NotAfter: time.Now().Add(time.Hour),
IsCA: true,
KeyUsage: x509.KeyUsageCertSign | x509.KeyUsageDigitalSignature,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
}

derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv)
Expect(err).NotTo(HaveOccurred())

certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
privBytes := x509.MarshalPKCS1PrivateKey(priv)
keyPEM := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: privBytes})

newRDSBrokerConfig.TLS = &config.TLSConfig{
Certificate: string(certPEM),
PrivateKey: string(keyPEM),
}

configJSON, err := json.Marshal(&newRDSBrokerConfig)
Expect(err).ToNot(HaveOccurred())
Expect(os.WriteFile(configFile.Name(), configJSON, 0644)).To(Succeed())
Expect(configFile.Close()).To(Succeed())

command := exec.Command(rdsBrokerPath,
fmt.Sprintf("-config=%s", configFile.Name()),
)
fmt.Printf("\n\n\n----------%s\n%s-----------\n\n", rdsBrokerPath, configFile.Name())
rdsBrokerSession, err := gexec.Start(command, GinkgoWriter, GinkgoWriter)
Expect(err).ShouldNot(HaveOccurred())

// Wait for it to be listening
Eventually(rdsBrokerSession, 10*time.Second).Should(And(
gbytes.Say("rds-broker.start"),
gbytes.Say(fmt.Sprintf(`{"address":"0.0.0.0:%d","host":"0.0.0.0","port":%d,"tls":true}`, rdsBrokerPort, rdsBrokerPort)),
))

rdsBrokerUrl := fmt.Sprintf("https://localhost:%d", rdsBrokerPort)

brokerAPIClient := NewBrokerAPIClient(rdsBrokerUrl, rdsBrokerConfig.Username, rdsBrokerConfig.Password)
rdsClient, err := NewRDSClient(rdsBrokerConfig.RDSConfig.Region, rdsBrokerConfig.RDSConfig.DBPrefix)

Expect(err).ToNot(HaveOccurred())

return rdsBrokerSession, brokerAPIClient, rdsClient
}
Loading

0 comments on commit 0c1015d

Please sign in to comment.