test(e2e): Add test for when an incorrect tag is used in a dynamic host catalog (#2731)

* refact(e2e): Move Dynamic Host Catalog env to its own file

This keeps each scenario consistent (an env_test.go file in each directory)

* refact(e2e): Update to use type casting

* refact(e2e): Rename existing dynamic host catalog test

* test(e2e): Add test for an empty dynamic host catalog

This test verifies that you fail to connect to a target with an empty host set (in a dynamic host catalog)

* fix(e2e): Update return statement since we know err is nil

* fix(e2e): Add ok checks in type assertions
pull/2737/head
Michael Li 3 years ago committed by GitHub
parent 1c9ca14a8e
commit ff8f1be0a1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -51,7 +51,7 @@ func loadConfig() (*config, error) {
return nil, err
}
return &c, err
return &c, nil
}
// NewApiClient creates a new Api client for the specified Boundary instance and

@ -0,0 +1,116 @@
package aws_test
import (
"context"
"encoding/json"
"fmt"
"testing"
"time"
"github.com/hashicorp/boundary/api/hostcatalogs"
"github.com/hashicorp/boundary/api/hostsets"
"github.com/hashicorp/boundary/testing/internal/e2e"
"github.com/hashicorp/boundary/testing/internal/e2e/boundary"
"github.com/stretchr/testify/require"
)
// TestCliCreateAwsDynamicHostCatalogWithEmptyHostSet uses the boundary cli to create a host catalog with the AWS
// plugin. The test sets up an AWS dynamic host catalog, creates some host sets, sets up a target to
// one of the host sets, and attempts to connect to the target.
func TestCliCreateAwsDynamicHostCatalogWithEmptyHostSet(t *testing.T) {
e2e.MaybeSkipTest(t)
c, err := loadConfig()
require.NoError(t, err)
ctx := context.Background()
boundary.AuthenticateAdminCli(t, ctx)
newOrgId := boundary.CreateNewOrgCli(t, ctx)
t.Cleanup(func() {
ctx := context.Background()
boundary.AuthenticateAdminCli(t, ctx)
output := e2e.RunCommand(ctx, "boundary", e2e.WithArgs("scopes", "delete", "-id", newOrgId))
require.NoError(t, output.Err, string(output.Stderr))
})
newProjectId := boundary.CreateNewProjectCli(t, ctx, newOrgId)
newHostCatalogId := boundary.CreateNewAwsHostCatalogCli(t, ctx, newProjectId, c.AwsAccessKeyId, c.AwsSecretAccessKey)
// Set up a host set
newHostSetId := boundary.CreateNewAwsHostSetCli(t, ctx, newHostCatalogId, "tag:empty_test=true")
// Check that there are no hosts in the host set
t.Logf("Looking for items in the host set...")
var actualHostSetCount int
for i := 1; i <= 3; i++ {
if i != 1 {
time.Sleep(3 * time.Second)
}
output := e2e.RunCommand(ctx, "boundary",
e2e.WithArgs(
"host-sets", "read",
"-id", newHostSetId,
"-format", "json",
),
)
require.NoError(t, output.Err, string(output.Stderr))
var hostSetsReadResult hostsets.HostSetReadResult
err := json.Unmarshal(output.Stdout, &hostSetsReadResult)
require.NoError(t, err)
actualHostSetCount = len(hostSetsReadResult.Item.HostIds)
require.Equal(t, actualHostSetCount, 0,
fmt.Sprintf("Detected incorrect number of hosts. Expected: 0, Actual: %d", actualHostSetCount),
)
}
t.Log("Successfully detected zero hosts in the host set")
// Check that there are no hosts in the host catalog
t.Logf("Looking for items in the host catalog...")
var actualHostCatalogCount int
for i := 1; i <= 3; i++ {
if i != 1 {
time.Sleep(3 * time.Second)
}
output := e2e.RunCommand(ctx, "boundary",
e2e.WithArgs("hosts", "list", "-host-catalog-id", newHostCatalogId, "-format", "json"),
)
require.NoError(t, output.Err, string(output.Stderr))
var hostCatalogListResult hostcatalogs.HostCatalogListResult
err := json.Unmarshal(output.Stdout, &hostCatalogListResult)
require.NoError(t, err)
actualHostCatalogCount = len(hostCatalogListResult.Items)
require.Equal(t, actualHostCatalogCount, 0,
fmt.Sprintf("Detected incorrect number of hosts. Expected: 0, Actual: %d", actualHostCatalogCount),
)
}
t.Log("Successfully detected zero hosts in the host catalog")
// Create target
newTargetId := boundary.CreateNewTargetCli(t, ctx, newProjectId, c.TargetPort)
boundary.AddHostSourceToTargetCli(t, ctx, newTargetId, newHostSetId)
// Attempt to connect to target
output := e2e.RunCommand(ctx, "boundary",
e2e.WithArgs(
"connect",
"-target-id", newTargetId,
"-format", "json",
"-exec", "/usr/bin/ssh", "--",
"-l", c.TargetSshUser,
"-i", c.TargetSshKeyPath,
"-o", "UserKnownHostsFile=/dev/null",
"-o", "StrictHostKeyChecking=no",
"-o", "IdentitiesOnly=yes", // forces the use of the provided key
"-p", "{{boundary.port}}", // this is provided by boundary
"{{boundary.ip}}",
"hostname", "-i",
),
)
var response boundary.CliError
err = json.Unmarshal(output.Stderr, &response)
require.NoError(t, err)
require.Equal(t, response.Status, 404, "Expected to error when connecting to a target with zero hosts")
t.Log("Successfully failed to connect to target")
}

@ -16,37 +16,14 @@ import (
"github.com/hashicorp/boundary/api/scopes"
"github.com/hashicorp/boundary/testing/internal/e2e"
"github.com/hashicorp/boundary/testing/internal/e2e/boundary"
"github.com/kelseyhightower/envconfig"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
type config struct {
AwsAccessKeyId string `envconfig:"E2E_AWS_ACCESS_KEY_ID" required:"true"`
AwsSecretAccessKey string `envconfig:"E2E_AWS_SECRET_ACCESS_KEY" required:"true"`
AwsHostSetFilter1 string `envconfig:"E2E_AWS_HOST_SET_FILTER" required:"true"` // e.g. "tag:testtag=true"
AwsHostSetIps1 string `envconfig:"E2E_AWS_HOST_SET_IPS" required:"true"` // e.g. "[\"1.2.3.4\", \"2.3.4.5\"]"
AwsHostSetFilter2 string `envconfig:"E2E_AWS_HOST_SET_FILTER2" required:"true"` // e.g. "tag:testtagtwo=test"
AwsHostSetIps2 string `envconfig:"E2E_AWS_HOST_SET_IPS2" required:"true"` // e.g. "[\"1.2.3.4\"]"
TargetSshKeyPath string `envconfig:"E2E_SSH_KEY_PATH" required:"true"` // e.g. "/Users/username/key.pem"
TargetSshUser string `envconfig:"E2E_SSH_USER" required:"true"` // e.g. "ubuntu"
TargetPort string `envconfig:"E2E_SSH_PORT" default:"22"`
}
func loadConfig() (*config, error) {
var c config
err := envconfig.Process("", &c)
if err != nil {
return nil, err
}
return &c, err
}
// TestCliCreateAwsDynamicHostCatalog uses the boundary cli to create a host catalog with the AWS
// TestCliCreateAwsDynamicHostCatalogWithHostSet uses the boundary cli to create a host catalog with the AWS
// plugin. The test sets up an AWS dynamic host catalog, creates some host sets, sets up a target to
// one of the host sets, and attempts to connect to the target.
func TestCliCreateAwsDynamicHostCatalog(t *testing.T) {
func TestCliCreateAwsDynamicHostCatalogWithHostSet(t *testing.T) {
e2e.MaybeSkipTest(t)
c, err := loadConfig()
require.NoError(t, err)

@ -0,0 +1,25 @@
package aws_test
import "github.com/kelseyhightower/envconfig"
type config struct {
AwsAccessKeyId string `envconfig:"E2E_AWS_ACCESS_KEY_ID" required:"true"`
AwsSecretAccessKey string `envconfig:"E2E_AWS_SECRET_ACCESS_KEY" required:"true"`
AwsHostSetFilter1 string `envconfig:"E2E_AWS_HOST_SET_FILTER" required:"true"` // e.g. "tag:testtag=true"
AwsHostSetIps1 string `envconfig:"E2E_AWS_HOST_SET_IPS" required:"true"` // e.g. "[\"1.2.3.4\", \"2.3.4.5\"]"
AwsHostSetFilter2 string `envconfig:"E2E_AWS_HOST_SET_FILTER2" required:"true"` // e.g. "tag:testtagtwo=test"
AwsHostSetIps2 string `envconfig:"E2E_AWS_HOST_SET_IPS2" required:"true"` // e.g. "[\"1.2.3.4\"]"
TargetSshKeyPath string `envconfig:"E2E_SSH_KEY_PATH" required:"true"` // e.g. "/Users/username/key.pem"
TargetSshUser string `envconfig:"E2E_SSH_USER" required:"true"` // e.g. "ubuntu"
TargetPort string `envconfig:"E2E_SSH_PORT" default:"22"`
}
func loadConfig() (*config, error) {
var c config
err := envconfig.Process("", &c)
if err != nil {
return nil, err
}
return &c, nil
}

@ -273,7 +273,8 @@ func populateBoundaryDatabase(t testing.TB, ctx context.Context, c *config, te T
var authenticationResult boundary.AuthenticateCliOutput
err = json.Unmarshal(buf.Bytes(), &authenticationResult)
require.NoError(t, err)
auth_token := authenticationResult.Item.Attributes["token"].(string)
auth_token, ok := authenticationResult.Item.Attributes["token"].(string)
require.True(t, ok)
connectTarget := infra.ConnectToTarget(t, te.Pool, te.Network, te.Boundary.UriNetwork, auth_token, newTargetId)
t.Cleanup(func() {

@ -52,8 +52,11 @@ func TestCliConnectTargetWithAuthzToken(t *testing.T) {
require.NoError(t, err)
newSessionAuthorization := newSessionAuthorizationResult.Item
retrievedUser := fmt.Sprintf("%s", newSessionAuthorization.Credentials[0].Credential["username"])
retrievedKey := fmt.Sprintf("%s\n", newSessionAuthorization.Credentials[0].Credential["private_key"])
retrievedUser, ok := newSessionAuthorization.Credentials[0].Credential["username"].(string)
require.True(t, ok)
retrievedKey, ok := newSessionAuthorization.Credentials[0].Credential["private_key"].(string)
require.True(t, ok)
retrievedKey += "\n"
assert.Equal(t, c.TargetSshUser, retrievedUser)
k, err := os.ReadFile(c.TargetSshKeyPath)

@ -3,7 +3,6 @@ package static_test
import (
"context"
"encoding/json"
"fmt"
"os"
"testing"
@ -52,8 +51,11 @@ func TestCliConnectTargetWithSsh(t *testing.T) {
require.NoError(t, err)
newSessionAuthorization := newSessionAuthorizationResult.Item
retrievedUser := fmt.Sprintf("%s", newSessionAuthorization.Credentials[0].Credential["username"])
retrievedKey := fmt.Sprintf("%s\n", newSessionAuthorization.Credentials[0].Credential["private_key"])
retrievedUser, ok := newSessionAuthorization.Credentials[0].Credential["username"].(string)
require.True(t, ok)
retrievedKey, ok := newSessionAuthorization.Credentials[0].Credential["private_key"].(string)
require.True(t, ok)
retrievedKey += "\n"
assert.Equal(t, c.TargetSshUser, retrievedUser)
k, err := os.ReadFile(c.TargetSshKeyPath)

@ -65,8 +65,10 @@ func TestCliStaticCredentialStore(t *testing.T) {
require.NoError(t, err)
newSessionAuthorization := newSessionAuthorizationResult.Item
retrievedUser := fmt.Sprintf("%s", newSessionAuthorization.Credentials[0].Credential["username"])
retrievedPassword := fmt.Sprintf("%s", newSessionAuthorization.Credentials[0].Credential["password"])
retrievedUser, ok := newSessionAuthorization.Credentials[0].Credential["username"].(string)
require.True(t, ok)
retrievedPassword, ok := newSessionAuthorization.Credentials[0].Credential["password"].(string)
require.True(t, ok)
assert.Equal(t, c.TargetSshUser, retrievedUser)
assert.Equal(t, "password", retrievedPassword)
@ -156,8 +158,10 @@ func TestApiStaticCredentialStore(t *testing.T) {
newSessionAuthorizationResult, err := tClient.AuthorizeSession(ctx, newTargetId)
require.NoError(t, err)
newSessionAuthorization := newSessionAuthorizationResult.Item
retrievedUser := fmt.Sprintf("%s", newSessionAuthorization.Credentials[0].Credential["username"])
retrievedKey := fmt.Sprintf("%s", newSessionAuthorization.Credentials[0].Credential["private_key"])
retrievedUser, ok := newSessionAuthorization.Credentials[0].Credential["username"].(string)
require.True(t, ok)
retrievedKey, ok := newSessionAuthorization.Credentials[0].Credential["private_key"].(string)
require.True(t, ok)
assert.Equal(t, c.TargetSshUser, retrievedUser)
require.Equal(t, string(k), retrievedKey)
t.Log("Successfully retrieved credentials for target")

@ -126,8 +126,10 @@ func TestCliVaultConnectTargetWithAuthzToken(t *testing.T) {
require.NoError(t, err)
newSessionAuthorization := newSessionAuthorizationResult.Item
retrievedUser := fmt.Sprintf("%s", newSessionAuthorization.Credentials[0].Credential["username"])
retrievedKey := fmt.Sprintf("%s", newSessionAuthorization.Credentials[0].Credential["private_key"])
retrievedUser, ok := newSessionAuthorization.Credentials[0].Credential["username"].(string)
require.True(t, ok)
retrievedKey, ok := newSessionAuthorization.Credentials[0].Credential["private_key"].(string)
require.True(t, ok)
assert.Equal(t, c.TargetSshUser, retrievedUser)
k, err := os.ReadFile(c.TargetSshKeyPath)

@ -3,7 +3,6 @@ package static_with_vault_test
import (
"context"
"encoding/json"
"fmt"
"os"
"testing"
@ -127,8 +126,10 @@ func TestCliVaultConnectTargetWithSsh(t *testing.T) {
require.NoError(t, err)
newSessionAuthorization := newSessionAuthorizationResult.Item
retrievedUser := fmt.Sprintf("%s", newSessionAuthorization.Credentials[0].Credential["username"])
retrievedKey := fmt.Sprintf("%s", newSessionAuthorization.Credentials[0].Credential["private_key"])
retrievedUser, ok := newSessionAuthorization.Credentials[0].Credential["username"].(string)
require.True(t, ok)
retrievedKey, ok := newSessionAuthorization.Credentials[0].Credential["private_key"].(string)
require.True(t, ok)
assert.Equal(t, c.TargetSshUser, retrievedUser)
k, err := os.ReadFile(c.TargetSshKeyPath)

@ -128,8 +128,10 @@ func TestCliVaultConnectTarget(t *testing.T) {
require.NoError(t, err)
newSessionAuthorization := newSessionAuthorizationResult.Item
retrievedUser := fmt.Sprintf("%s", newSessionAuthorization.Credentials[0].Credential["username"])
retrievedKey := fmt.Sprintf("%s", newSessionAuthorization.Credentials[0].Credential["private_key"])
retrievedUser, ok := newSessionAuthorization.Credentials[0].Credential["username"].(string)
require.True(t, ok)
retrievedKey, ok := newSessionAuthorization.Credentials[0].Credential["private_key"].(string)
require.True(t, ok)
assert.Equal(t, c.TargetSshUser, retrievedUser)
k, err := os.ReadFile(c.TargetSshKeyPath)

@ -3,7 +3,6 @@ package static_with_vault_test
import (
"context"
"encoding/json"
"fmt"
"os"
"testing"
@ -159,8 +158,10 @@ func TestCliVaultCredentialStore(t *testing.T) {
for _, v := range newSessionAuthorization.Credentials {
if v.CredentialSource.CredentialType == "ssh_private_key" {
retrievedUser := v.Credential["username"].(string)
retrievedKey := v.Credential["private_key"].(string)
retrievedUser, ok := v.Credential["username"].(string)
require.True(t, ok)
retrievedKey, ok := v.Credential["private_key"].(string)
require.True(t, ok)
assert.Equal(t, c.TargetSshUser, retrievedUser)
keyData, err := os.ReadFile(c.TargetSshKeyPath)
@ -168,8 +169,10 @@ func TestCliVaultCredentialStore(t *testing.T) {
require.Equal(t, string(keyData), retrievedKey)
t.Log("Successfully retrieved private key credentials for target")
} else if v.CredentialSource.CredentialType == "username_password" {
retrievedUser := v.Credential["username"].(string)
retrievedPassword := v.Credential["password"].(string)
retrievedUser, ok := v.Credential["username"].(string)
require.True(t, ok)
retrievedPassword, ok := v.Credential["password"].(string)
require.True(t, ok)
assert.Equal(t, c.TargetSshUser, retrievedUser)
assert.Equal(t, password, retrievedPassword)
t.Log("Successfully retrieved password credentials for target")
@ -305,8 +308,10 @@ func TestApiVaultCredentialStore(t *testing.T) {
require.True(t, keysMatch, "Key retrieved from vault does not match expected value")
t.Log("Successfully retrieved credentials for target")
} else if v.CredentialSource.CredentialType == "username_password" {
retrievedUser := fmt.Sprintf("%s", v.Credential["username"])
retrievedPassword := fmt.Sprintf("%s", v.Credential["password"])
retrievedUser, ok := v.Credential["username"].(string)
require.True(t, ok)
retrievedPassword, ok := v.Credential["password"].(string)
require.True(t, ok)
assert.Equal(t, c.TargetSshUser, retrievedUser)
assert.Equal(t, password, retrievedPassword)
t.Log("Successfully retrieved password credentials for target")

@ -33,7 +33,7 @@ func loadConfig() (*config, error) {
return nil, err
}
return &c, err
return &c, nil
}
// Setup verifies if appropriate credentials are set and adds the boundary controller

Loading…
Cancel
Save