package static_test import ( "context" "encoding/json" "fmt" "os" "testing" "github.com/hashicorp/boundary/api/credentials" "github.com/hashicorp/boundary/api/targets" "github.com/hashicorp/boundary/testing/internal/e2e" "github.com/hashicorp/boundary/testing/internal/e2e/boundary" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) // TestCliConnectTargetWithSsh uses the boundary cli to create a credential using boundary's // built-in credential store. The test attaches that credential to a target and attempts to connect // to that target using those credentials. func TestCliConnectTargetWithSsh(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) newProjectId := boundary.CreateNewProjectCli(t, ctx, newOrgId) newHostCatalogId := boundary.CreateNewHostCatalogCli(t, ctx, newProjectId) newHostSetId := boundary.CreateNewHostSetCli(t, ctx, newHostCatalogId) newHostId := boundary.CreateNewHostCli(t, ctx, newHostCatalogId, c.TargetIp) boundary.AddHostToHostSetCli(t, ctx, newHostSetId, newHostId) newTargetId := boundary.CreateNewTargetCli(t, ctx, newProjectId, c.TargetPort) boundary.AddHostSourceToTargetCli(t, ctx, newTargetId, newHostSetId) newCredentialStoreId := boundary.CreateNewCredentialStoreStaticCli(t, ctx, newProjectId) // Create credentials output := e2e.RunCommand(ctx, "boundary", e2e.WithArgs( "credentials", "create", "ssh-private-key", "-credential-store-id", newCredentialStoreId, "-username", c.TargetSshUser, "-private-key", "file://"+c.TargetSshKeyPath, "-format", "json", ), ) require.NoError(t, output.Err, string(output.Stderr)) var newCredentialsResult credentials.CredentialCreateResult err = json.Unmarshal(output.Stdout, &newCredentialsResult) require.NoError(t, err) newCredentialsId := newCredentialsResult.Item.Id t.Logf("Created Credentials: %s", newCredentialsId) // Add credentials to target output = e2e.RunCommand(ctx, "boundary", e2e.WithArgs( "targets", "add-credential-sources", "-id", newTargetId, "-brokered-credential-source", newCredentialsId, ), ) require.NoError(t, output.Err, string(output.Stderr)) // Get credentials for target output = e2e.RunCommand(ctx, "boundary", e2e.WithArgs("targets", "authorize-session", "-id", newTargetId, "-format", "json"), ) require.NoError(t, output.Err, string(output.Stderr)) var newSessionAuthorizationResult targets.SessionAuthorizationResult err = json.Unmarshal(output.Stdout, &newSessionAuthorizationResult) 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"]) assert.Equal(t, c.TargetSshUser, retrievedUser) k, err := os.ReadFile(c.TargetSshKeyPath) require.NoError(t, err) require.Equal(t, string(k), retrievedKey) t.Log("Successfully retrieved credentials for target") // Connect to target using ssh option output = e2e.RunCommand(ctx, "boundary", e2e.WithArgs( "connect", "ssh", "-target-id", newTargetId, "--", "-o", "UserKnownHostsFile=/dev/null", "-o", "StrictHostKeyChecking=no", "-o", "IdentitiesOnly=yes", // forces the use of the provided key ), ) require.NoError(t, output.Err, string(output.Stderr)) t.Log("Successfully connected to target") }