diff --git a/go.sum b/go.sum index 5976e0b5d..28aa74a02 100644 --- a/go.sum +++ b/go.sum @@ -27,6 +27,7 @@ github.com/cyberark/conjur-authn-k8s-client v0.13.0/go.mod h1:JTeGIeRO59J7mMEc5y github.com/cyberark/secretless-broker v1.4.1-0.20191211191712-251c5ec034af/go.mod h1:+GueI3WCJL5gDYaYa38ZokAR8ceEyCVet7MkuZyjf80= github.com/cyberark/summon v0.7.0/go.mod h1:S7grcxHeUxfL1vRTQUyq9jGK8yG6V/tSlLPQ6tHRO4k= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= github.com/dominikh/go-tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= @@ -165,8 +166,10 @@ github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= @@ -206,6 +209,7 @@ github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= golang.org/x/crypto v0.0.0-20180621125126-a49355c7e3f8/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= diff --git a/test/connector/tcp/mssql/mssql-2017-CU1/dev b/test/connector/tcp/mssql/mssql-2017-CU1/dev new file mode 100755 index 000000000..fc49fa638 --- /dev/null +++ b/test/connector/tcp/mssql/mssql-2017-CU1/dev @@ -0,0 +1,3 @@ +#!/bin/bash -ex + +./start -d diff --git a/test/connector/tcp/mssql/mssql-2017-CU1/docker-compose.yml b/test/connector/tcp/mssql/mssql-2017-CU1/docker-compose.yml new file mode 100644 index 000000000..0571f14b4 --- /dev/null +++ b/test/connector/tcp/mssql/mssql-2017-CU1/docker-compose.yml @@ -0,0 +1,48 @@ +version: '3.0' + +services: + + mssql-2017-CU1: + image: mcr.microsoft.com/mssql/server:2017-CU1-ubuntu + ports: + - 1434:1433 + environment: + # This hardcoded password must match the one in secretless.yml. + SA_PASSWORD: "yourStrong()Password" + ACCEPT_EULA: Y + + secretless-2017-CU1: + image: secretless-broker + ports: + - 2224:2223 + volumes: + - ./secretless.yml:/secretless.yml + depends_on: + - mssql-2017-CU1 + + secretless-2017-CU1-dev: + image: secretless-dev + command: ./bin/reflex + ports: + - 2224:2223 + volumes: + - ../../../../..:/secretless + - ./secretless.yml:/secretless.yml + depends_on: + - mssql-2017-CU1 + + test: + build: + context: .. + command: sleep 999d + environment: + TEST_ROOT: /secretless/test/connector/tcp/mssql + DB_PROTOCOL: mssql + DB_HOST_TLS: mssql-2017-CU1 + DB_HOST_NO_TLS: mssql-2017-CU1 # TODO: configure a non-ssl container? + DB_PORT: 1433 + DB_USER: sa + DB_PASSWORD: yourStrong()Password + SECRETLESS_HOST: + volumes: + - ../../../../..:/secretless diff --git a/test/connector/tcp/mssql/mssql-2017-CU1/secretless.yml b/test/connector/tcp/mssql/mssql-2017-CU1/secretless.yml new file mode 100644 index 000000000..a4ca7b294 --- /dev/null +++ b/test/connector/tcp/mssql/mssql-2017-CU1/secretless.yml @@ -0,0 +1,12 @@ +version: 2 + +services: + mssql: + connector: mssql + listenOn: tcp://0.0.0.0:2223 + credentials: + username: sa + # This hardcoded password must match the one in the docker-compose. + password: yourStrong()Password + host: mssql-2017-CU1 + port: 1433 diff --git a/test/connector/tcp/mssql/mssql-2017-CU1/start b/test/connector/tcp/mssql/mssql-2017-CU1/start new file mode 100755 index 000000000..2b2dd2e0a --- /dev/null +++ b/test/connector/tcp/mssql/mssql-2017-CU1/start @@ -0,0 +1,12 @@ +#!/bin/bash -ex + +mssql_host="mssql-2017-CU1" +secretless_host="secretless-2017-CU1" +while getopts ":d" opt; do + case $opt in + d) secretless_host=secretless-2017-CU1-dev;; + *) echo "Unknown option -$OPTARG"; exit 1;; + esac +done + +../start -m $mssql_host -s $secretless_host diff --git a/test/connector/tcp/mssql/mssql-2017-CU1/stop b/test/connector/tcp/mssql/mssql-2017-CU1/stop new file mode 100755 index 000000000..459e614e7 --- /dev/null +++ b/test/connector/tcp/mssql/mssql-2017-CU1/stop @@ -0,0 +1,3 @@ +#!/bin/bash -ex + +../stop diff --git a/test/connector/tcp/mssql/mssql-2017-CU1/test b/test/connector/tcp/mssql/mssql-2017-CU1/test new file mode 100755 index 000000000..76e5eee20 --- /dev/null +++ b/test/connector/tcp/mssql/mssql-2017-CU1/test @@ -0,0 +1,12 @@ +#!/bin/bash -e + +# Automatically detect if we're devmode based on the existence +# of the secretless-dev container. We assume that you started +# your workflow using `./dev` if you are developing, and this +# command will use the secretless-dev container. +secretless_host="secretless-2017-CU1" +if [[ ! -z $(docker-compose ps -q secretless-2017-CU1-dev) ]]; then + secretless_host=secretless-2017-CU1-dev +fi + +../test -s $secretless_host diff --git a/test/connector/tcp/mssql/mssql-2017-CU1/test-local b/test/connector/tcp/mssql/mssql-2017-CU1/test-local new file mode 100755 index 000000000..e3df8f5d0 --- /dev/null +++ b/test/connector/tcp/mssql/mssql-2017-CU1/test-local @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +# this is for local testing + +export TEST_ROOT="/secretless/test/connector/tcp/mssql" +export DB_PROTOCOL="mssql" +export DB_HOST_TLS="mssql-2017-CU1" +export DB_HOST_NO_TLS="mssql-2017-CU1" +export DB_PORT="1434" +export DB_USER="sa" +export DB_PASSWORD="yourStrong()Password" +export SECRETLESS_HOST="127.0.0.1" +export SECRETLESS_PORT="2224" + +cd .. +go test -v diff --git a/test/connector/tcp/mssql/mssql-2017-CU1/wait_for_mssql b/test/connector/tcp/mssql/mssql-2017-CU1/wait_for_mssql new file mode 100755 index 000000000..e2fac62ef --- /dev/null +++ b/test/connector/tcp/mssql/mssql-2017-CU1/wait_for_mssql @@ -0,0 +1,3 @@ +#!/bin/bash -ex + +../wait_for_mssql -m mssql-2017-CU1 diff --git a/test/connector/tcp/mssql/mssql-2019/dev b/test/connector/tcp/mssql/mssql-2019/dev new file mode 100755 index 000000000..fc49fa638 --- /dev/null +++ b/test/connector/tcp/mssql/mssql-2019/dev @@ -0,0 +1,3 @@ +#!/bin/bash -ex + +./start -d diff --git a/test/connector/tcp/mssql/mssql-2019/docker-compose.yml b/test/connector/tcp/mssql/mssql-2019/docker-compose.yml new file mode 100644 index 000000000..5327a6888 --- /dev/null +++ b/test/connector/tcp/mssql/mssql-2019/docker-compose.yml @@ -0,0 +1,48 @@ +version: '3.0' + +services: + + mssql-2019: + image: mcr.microsoft.com/mssql/server:2019-latest + ports: + - 1435:1433 + environment: + # This hardcoded password must match the one in secretless.yml. + SA_PASSWORD: "yourStrong()Password" + ACCEPT_EULA: Y + + secretless-2019: + image: secretless-broker + ports: + - 2225:2223 + volumes: + - ./secretless.yml:/secretless.yml + depends_on: + - mssql-2019 + + secretless-2019-dev: + image: secretless-dev + command: ./bin/reflex + ports: + - 2225:2223 + volumes: + - ../../../../..:/secretless + - ./secretless.yml:/secretless.yml + depends_on: + - mssql-2019 + + test: + build: + context: .. + command: sleep 999d + environment: + TEST_ROOT: /secretless/test/connector/tcp/mssql + DB_PROTOCOL: mssql + DB_HOST_TLS: mssql-2019 + DB_HOST_NO_TLS: mssql-2019 # TODO: configure a non-ssl container? + DB_PORT: 1433 + DB_USER: sa + DB_PASSWORD: yourStrong()Password + SECRETLESS_HOST: + volumes: + - ../../../../..:/secretless diff --git a/test/connector/tcp/mssql/mssql-2019/secretless.yml b/test/connector/tcp/mssql/mssql-2019/secretless.yml new file mode 100644 index 000000000..d0fd94382 --- /dev/null +++ b/test/connector/tcp/mssql/mssql-2019/secretless.yml @@ -0,0 +1,12 @@ +version: 2 + +services: + mssql: + connector: mssql + listenOn: tcp://0.0.0.0:2223 + credentials: + username: sa + # This hardcoded password must match the one in the docker-compose. + password: yourStrong()Password + host: mssql-2019 + port: 1433 diff --git a/test/connector/tcp/mssql/mssql-2019/start b/test/connector/tcp/mssql/mssql-2019/start new file mode 100755 index 000000000..a31d2a43e --- /dev/null +++ b/test/connector/tcp/mssql/mssql-2019/start @@ -0,0 +1,12 @@ +#!/bin/bash -ex + +mssql_host="mssql-2019" +secretless_host="secretless-2019" +while getopts ":d" opt; do + case $opt in + d) secretless_host=secretless-2019-dev;; + *) echo "Unknown option -$OPTARG"; exit 1;; + esac +done + +../start -m $mssql_host -s $secretless_host diff --git a/test/connector/tcp/mssql/mssql-2019/stop b/test/connector/tcp/mssql/mssql-2019/stop new file mode 100755 index 000000000..459e614e7 --- /dev/null +++ b/test/connector/tcp/mssql/mssql-2019/stop @@ -0,0 +1,3 @@ +#!/bin/bash -ex + +../stop diff --git a/test/connector/tcp/mssql/mssql-2019/test b/test/connector/tcp/mssql/mssql-2019/test new file mode 100755 index 000000000..4408dc91d --- /dev/null +++ b/test/connector/tcp/mssql/mssql-2019/test @@ -0,0 +1,12 @@ +#!/bin/bash -e + +# Automatically detect if we're devmode based on the existence +# of the secretless-dev container. We assume that you started +# your workflow using `./dev` if you are developing, and this +# command will use the secretless-dev container. +secretless_host="secretless-2019" +if [[ ! -z $(docker-compose ps -q secretless-2019-dev) ]]; then + secretless_host=secretless-2019-dev +fi + +../test -s $secretless_host diff --git a/test/connector/tcp/mssql/mssql-2019/test-local b/test/connector/tcp/mssql/mssql-2019/test-local new file mode 100755 index 000000000..b89b24c14 --- /dev/null +++ b/test/connector/tcp/mssql/mssql-2019/test-local @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +# this is for local testing + +export TEST_ROOT="/secretless/test/connector/tcp/mssql" +export DB_PROTOCOL="mssql" +export DB_HOST_TLS="mssql-2019" +export DB_HOST_NO_TLS="mssql-2019" +export DB_PORT="1435" +export DB_USER="sa" +export DB_PASSWORD="yourStrong()Password" +export SECRETLESS_HOST="127.0.0.1" +export SECRETLESS_PORT="2225" + +cd .. +go test -v diff --git a/test/connector/tcp/mssql/mssql-2019/wait_for_mssql b/test/connector/tcp/mssql/mssql-2019/wait_for_mssql new file mode 100755 index 000000000..43783b0b0 --- /dev/null +++ b/test/connector/tcp/mssql/mssql-2019/wait_for_mssql @@ -0,0 +1,3 @@ +#!/bin/bash -ex + +../wait_for_mssql -m mssql-2019 diff --git a/test/connector/tcp/mssql/mssql_connector_test.go b/test/connector/tcp/mssql/mssql_connector_test.go index 2738f4551..17e38c13e 100644 --- a/test/connector/tcp/mssql/mssql_connector_test.go +++ b/test/connector/tcp/mssql/mssql_connector_test.go @@ -2,6 +2,7 @@ package mssqltest import ( "fmt" + "strconv" "testing" "github.com/stretchr/testify/assert" @@ -37,9 +38,14 @@ func RunTests(t *testing.T, queryExec dbQueryExecutor) { }) t.Run("Cannot connect directly to MSSQL", func(t *testing.T) { + // Set Host and Port to $DB_HOST_TLS and $DB_PORT environment + // variables, respectively. + envCfg := testutil.NewDbConfigFromEnv() cfg := defaultSecretlessDbConfig() - cfg.Port = 1433 - cfg.Host = "mssql" + cfg.Host = envCfg.HostWithTLS + var err error + cfg.Port, err = strconv.Atoi(envCfg.Port) + assert.NoError(t, err) // This is for local testing. Locally, Secretless and and the target service // are exposed on 127.0.0.1 via port mappings @@ -47,7 +53,7 @@ func RunTests(t *testing.T, queryExec dbQueryExecutor) { cfg.Host = "127.0.0.1" } - _, err := queryExec( + _, err = queryExec( cfg, "", ) diff --git a/test/connector/tcp/mssql/mssql_query.go b/test/connector/tcp/mssql/mssql_query.go index b0efe84bb..5005ef430 100644 --- a/test/connector/tcp/mssql/mssql_query.go +++ b/test/connector/tcp/mssql/mssql_query.go @@ -8,14 +8,12 @@ import ( "os/exec" "text/tabwriter" - _ "github.com/denisenkom/go-mssqldb" - "github.com/cyberark/secretless-broker/test/util/testutil" ) type dbConfig struct { - Host string - Port int + Host string + Port int Username string Password string Database string @@ -26,7 +24,7 @@ type dbQueryExecutor func(cfg dbConfig, query string) (string, error) func defaultSecretlessDbConfig() dbConfig { return dbConfig{ Host: testutil.SecretlessHost, - Port: 2223, + Port: testutil.SecretlessPort, Username: "dummy", Password: "dummy", } @@ -50,7 +48,7 @@ func sqlcmdExec( out, err := exec.Command( "sqlcmd", - args... + args..., ).Output() if err != nil { @@ -99,7 +97,6 @@ func gomssqlExec( } defer rows.Close() - // Execute the query cols, err := rows.Columns() if err != nil { diff --git a/test/connector/tcp/mssql/start b/test/connector/tcp/mssql/start index 6a05847ca..98ecae01b 100755 --- a/test/connector/tcp/mssql/start +++ b/test/connector/tcp/mssql/start @@ -1,21 +1,33 @@ #!/bin/bash -ex -SECRETLESS_HOST=secretless -while getopts :d opt; do +mssql_host=mssql +while getopts :dm:s: opt; do case $opt in - d) SECRETLESS_HOST=secretless-dev;; + d) dev_mode=true;; + m) mssql_host=${OPTARG};; + s) secretless_host=${OPTARG};; \?) echo "Unknown option -$OPTARG"; exit 1;; esac done +# If the secretless host is not explicitly set on the command line, +# then use one of the default names (either secretless or +# secretless-dev, depending on whether testing is being done in +# development mode) for the secretless host. +if [[ -z $secretless_host ]]; then + secretless_host=secretless + if [[ "$dev_mode" = true ]]; then + secretless_host=secretless-dev + fi +fi ./stop docker-compose build # the order of the services is important. mssql must be up before we start secretless -docker-compose up -d mssql +docker-compose up -d $secretless_host -time ./wait_for_mssql -docker-compose logs mssql +time ./wait_for_mssql -m $mssql_host +docker-compose logs $mssql_host -docker-compose up -d $SECRETLESS_HOST +docker-compose up -d $secretless_host diff --git a/test/connector/tcp/mssql/test b/test/connector/tcp/mssql/test index 700a18b05..3026b62e4 100755 --- a/test/connector/tcp/mssql/test +++ b/test/connector/tcp/mssql/test @@ -1,12 +1,22 @@ #!/bin/bash -e -# Automatically detect if we're devmode based on the existence -# of the secretless-dev container. We assume that you started -# your workflow using `./dev` if you are developing, and this -# command will use the secretless-dev container. -export SECRETLESS_HOST=secretless -if [[ ! -z $(docker-compose ps -q secretless-dev) ]]; then - export SECRETLESS_HOST=secretless-dev +while getopts :s: opt; do + case $opt in + s) SECRETLESS_HOST=${OPTARG};; + \?) echo "Unknown option -$OPTARG"; exit 1;; + esac +done +# If the secretless host is not explicitly set on the command line, +# then use the default names (either secretless or secretless-dev) +# for the secretless host. Automatically detect if we're devmode +# based on the existence of the secretless-dev container. We assume +# that you started your workflow using `./dev` if you are developing, +# and this command will use the secretless-dev container. +if [[ -z $SECRETLESS_HOST ]]; then + export SECRETLESS_HOST=secretless + if [[ ! -z $(docker-compose ps -q secretless-dev) ]]; then + SECRETLESS_HOST=secretless-dev + fi fi echo "Waiting for '$SECRETLESS_HOST' service to start" diff --git a/test/connector/tcp/mssql/wait_for_mssql b/test/connector/tcp/mssql/wait_for_mssql index 09521491b..30e210234 100755 --- a/test/connector/tcp/mssql/wait_for_mssql +++ b/test/connector/tcp/mssql/wait_for_mssql @@ -1,7 +1,15 @@ #!/bin/bash +mssql_host=mssql +while getopts :m: opt; do + case $opt in + m) mssql_host=${OPTARG};; + \?) echo "Unknown option -$OPTARG"; exit 1;; + esac +done + mssql_is_up() { - docker-compose logs mssql | grep "SQL Server is now ready for client connections" + docker-compose logs $mssql_host | grep "SQL Server is now ready for client connections" } # TODO: Use bash-lib for this function once it is implemented there diff --git a/test/util/testutil/init.go b/test/util/testutil/init.go index 588648919..6c1d9499d 100644 --- a/test/util/testutil/init.go +++ b/test/util/testutil/init.go @@ -3,6 +3,7 @@ package testutil import ( "log" "os" + "strconv" ) // Verbose reads the VERBOSE environment variable to determine output mode. @@ -18,12 +19,12 @@ var Verbose = func() bool { // DBConfig holds configuration information for a database type DBConfig struct { - HostWithTLS string + HostWithTLS string HostWithoutTLS string - Port string - User string - Password string - Protocol string + Port string + User string + Password string + Protocol string } // NewDbConfigFromEnv creates a new DbConfig from ENV variables. The variables @@ -49,19 +50,19 @@ func NewDbConfigFromEnv() DBConfig { // Validate they exist for _, field := range requiredEnvVars { - if _, found := os.LookupEnv(field); !found { + if _, found := os.LookupEnv(field); !found { log.Panicf("ERROR: $%v envvar wasn't found\n", field) } } // Read them into the DBConfig return DBConfig{ - HostWithTLS: os.Getenv("DB_HOST_TLS"), + HostWithTLS: os.Getenv("DB_HOST_TLS"), HostWithoutTLS: os.Getenv("DB_HOST_NO_TLS"), - Port: os.Getenv("DB_PORT"), - User: os.Getenv("DB_USER"), - Password: os.Getenv("DB_PASSWORD"), - Protocol: os.Getenv("DB_PROTOCOL"), + Port: os.Getenv("DB_PORT"), + User: os.Getenv("DB_USER"), + Password: os.Getenv("DB_PASSWORD"), + Protocol: os.Getenv("DB_PROTOCOL"), } } @@ -77,6 +78,21 @@ var SecretlessHost = func() string { return "secretless" }() +// SecretlessPort gets its value from the SECRETLESS_PORT ENV variable, and +// allows us to specify a different port to use for the secretlessy-proxy +// host. +var SecretlessPort = func() int { + port := 2223 + if portEnv, ok := os.LookupEnv("SECRETLESS_PORT"); ok { + var err error + port, err = strconv.Atoi(portEnv) + if err != nil { + log.Panicf("ERROR: Invalid SECRETLESS_PORT envvar: $%v\n", portEnv) + } + } + return port +}() + func init() { // TEST_ROOT is used to direct where secretless.yml gets generated testRoot, ok := os.LookupEnv("TEST_ROOT")