Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 2 additions & 6 deletions e2e/openapi-cfg.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ output-options:
- getRelays
- listGateways
- createProject
- createKubernetesPamResource
- createRedisPamResource
- createPamFolder
- createPamAccountTemplate
- deleteSecretV4
- updateSecretV4
- createSecretV4
Expand All @@ -32,11 +32,7 @@ output-options:
- attachUniversalAuth
- createUniversalAuthClientSecret
- createCloudflareAppConnection
- createPostgresPamResource
- createPostgresPamAccount
- createSshPamResource
- createSshPamAccount
- createRedisPamAccount
- createWindowsPamResource
- createWindowsPamAccount
- createAwsAppConnection
3,259 changes: 911 additions & 2,348 deletions e2e/packages/client/client.gen.go

Large diffs are not rendered by default.

26 changes: 26 additions & 0 deletions e2e/pam/pam_helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,32 @@ func SetupPAMInfra(t *testing.T, ctx context.Context, opts ...SetupPAMOption) *P
}
}

// CreatePamFolder creates a PAM folder in the project and returns its ID.
func CreatePamFolder(t *testing.T, ctx context.Context, infra *PAMTestInfra, name string) openapitypes.UUID {
resp, err := infra.ApiClient.CreatePamFolderWithResponse(ctx, client.CreatePamFolderJSONRequestBody{
Name: name,
})
require.NoError(t, err)
require.Equal(t, http.StatusOK, resp.StatusCode(), "create folder: %s", string(resp.Body))
slog.Info("Created PAM folder", "folderId", resp.JSON200.Folder.Id, "name", name)
return resp.JSON200.Folder.Id
}

// CreatePamTemplate creates an account template of the given type, attached to the infra gateway,
// and returns its ID. Accounts created from it inherit the gateway.
func CreatePamTemplate(t *testing.T, ctx context.Context, infra *PAMTestInfra, name string, accountType client.CreatePamAccountTemplateJSONBodyType) openapitypes.UUID {
gatewayId := infra.GatewayId
resp, err := infra.ApiClient.CreatePamAccountTemplateWithResponse(ctx, client.CreatePamAccountTemplateJSONRequestBody{
Name: name,
Type: accountType,
GatewayId: &gatewayId,
})
require.NoError(t, err)
require.Equal(t, http.StatusOK, resp.StatusCode(), "create template: %s", string(resp.Body))
slog.Info("Created PAM template", "templateId", resp.JSON200.Template.Id, "name", name, "type", accountType)
return resp.JSON200.Template.Id
}

func LoginUser(t *testing.T, ctx context.Context, infra *PAMTestInfra) {
loginCmd := helpers.Command{
Test: t,
Expand Down
64 changes: 26 additions & 38 deletions e2e/pam/postgres_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import (
"testing"
"time"

"github.com/google/uuid"
"github.com/infisical/cli/e2e-tests/packages/client"
helpers "github.com/infisical/cli/e2e-tests/util"
"github.com/jackc/pgx/v5"
Expand All @@ -18,10 +17,6 @@ import (
)

func TestPAM_Postgres_ConnectToDatabase(t *testing.T) {
// TODO: Re-enable once the PAM revamp's e2e tests are updated. Temporarily
// skipped so it stops blocking production.
t.Skip("Temporarily disabled pending PAM revamp test updates")

ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)

Expand Down Expand Up @@ -59,20 +54,27 @@ func TestPAM_Postgres_ConnectToDatabase(t *testing.T) {
directConn.Close(ctx)
slog.Info("Verified PAM Postgres is accessible directly")

// Get host/port for PAM resource creation
// Get host/port for the PAM account
pgHost, err := pgContainer.Host(ctx)
require.NoError(t, err)
pgPort, err := pgContainer.MappedPort(ctx, "5432")
require.NoError(t, err)

// Create Postgres PAM resource via API
resourceName := "pg-resource"
pgResResp, err := infra.ApiClient.CreatePostgresPamResourceWithResponse(
// Create folder + template + account (new PAM model)
folderName := "pg-folder"
accountName := "pg-account"
folderId := CreatePamFolder(t, ctx, infra, folderName)
templateId := CreatePamTemplate(t, ctx, infra, "pg-template", client.CreatePamAccountTemplateJSONBodyTypePostgres)

gatewayId := infra.GatewayId
password := pgPassword
acctResp, err := infra.ApiClient.CreatePostgresPamAccountWithResponse(
ctx,
client.CreatePostgresPamResourceJSONRequestBody{
ProjectId: uuid.MustParse(infra.ProjectId),
GatewayId: &infra.GatewayId,
Name: resourceName,
client.CreatePostgresPamAccountJSONRequestBody{
FolderId: folderId,
TemplateId: templateId,
GatewayId: &gatewayId,
Name: accountName,
ConnectionDetails: struct {
Database string `json:"database"`
Host string `json:"host"`
Expand All @@ -87,47 +89,30 @@ func TestPAM_Postgres_ConnectToDatabase(t *testing.T) {
SslEnabled: false,
SslRejectUnauthorized: false,
},
},
)
require.NoError(t, err)
require.Equal(t, http.StatusOK, pgResResp.StatusCode())
resourceId := pgResResp.JSON200.Resource.Id
slog.Info("Created Postgres PAM resource", "resourceId", resourceId)

// Create Postgres PAM account via API
accountName := "pg-account"
pgAcctResp, err := infra.ApiClient.CreatePostgresPamAccountWithResponse(
ctx,
client.CreatePostgresPamAccountJSONRequestBody{
ResourceId: resourceId,
Name: accountName,
Credentials: struct {
Password string `json:"password"`
Username string `json:"username"`
Password *string `json:"password,omitempty"`
Username string `json:"username"`
}{
Username: pgUser,
Password: pgPassword,
Password: &password,
},
},
)
require.NoError(t, err)
require.Equal(t, http.StatusOK, pgAcctResp.StatusCode())
require.Equal(t, http.StatusOK, acctResp.StatusCode(), "create account: %s", string(acctResp.Body))
slog.Info("Created Postgres PAM account")

// Login with provisioned admin user
LoginUser(t, ctx, infra)

// Run pam db access
// Run pam access <folder>/<account>
freePort := helpers.GetFreePort()
pamCmd := helpers.Command{
Test: t,
RunMethod: helpers.RunMethodSubprocess,
DisableTempHomeDir: true,
Args: []string{
"pam", "db", "access",
"--resource", resourceName,
"--account", accountName,
"--project-id", infra.ProjectId,
"pam", "access", fmt.Sprintf("%s/%s", folderName, accountName),
"--duration", "5m",
"--port", fmt.Sprintf("%d", freePort),
},
Expand All @@ -143,16 +128,19 @@ func TestPAM_Postgres_ConnectToDatabase(t *testing.T) {
result := helpers.WaitFor(t, helpers.WaitForOptions{
EnsureCmdRunning: &pamCmd,
Condition: func() helpers.ConditionResult {
if strings.Contains(pamCmd.Stdout(), "Database Proxy Session Started") {
if strings.Contains(pamCmd.Stdout(), "Proxy Session Started") {
return helpers.ConditionSuccess
}
return helpers.ConditionWait
},
})
if result != helpers.WaitSuccess {
pamCmd.DumpOutput()
}
require.Equal(t, helpers.WaitSuccess, result, "Database proxy should start successfully")

// Connect via pgx to the proxy and run SELECT 1
proxyConnStr := fmt.Sprintf("postgres://%s@localhost:%d/%s?sslmode=disable", pgUser, freePort, pgDatabase)
proxyConnStr := fmt.Sprintf("postgres://%s@127.0.0.1:%d/%s?sslmode=disable", pgUser, freePort, pgDatabase)
var proxyConn *pgx.Conn
connectResult := helpers.WaitFor(t, helpers.WaitForOptions{
EnsureCmdRunning: &pamCmd,
Expand Down
Loading
Loading