Skip to content
Merged
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: 7 additions & 1 deletion integration_tests/create_postgres_access.lua
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ Test.gql("PostgresAccess connection returns credentials only to its owner", func
caCertificate = "test-ca-certificate",
serverName = "pg-foobar-main-a4f04c0c-rw.someteamname.svc.cluster.local",
username = "user-foobar-role",
relayEndpoint = Contains("https://relay.external.dev."),
relayEndpoint = "https://relay.external.dev.nav.cloud.nais.io:8443",
relayAccess = "someteamname/mapped-access",
relayToken = "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8",
},
Expand Down Expand Up @@ -392,6 +392,12 @@ Test.gql("PostgresAccess connection is null without error until the access is re
end
end)

Test.gql("PostgresAccess connection is null before relay endpoint is published", function(t)
t.addHeader("x-user-email", user:email())
t.query [[query { team(slug: "someteamname") { environment(name: "dev") { postgresAccess(name: "ready-no-endpoint-access") { connection { relayEndpoint } } } } }]]
t.check { data = { team = { environment = { postgresAccess = { connection = Null } } } } }
end)

Test.gql("PostgresAccess connection fails when a ready access has no secrets", function(t)
t.addHeader("x-user-email", user:email())
t.query [[query { team(slug: "someteamname") { environment(name: "dev") { postgresAccess(name: "missing-secret-access") { state connection { password } } } } }]]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ spec:
status:
databaseRole: user-foobar-role
relayAccess: mapped-access
relayEndpoint: https://relay.external.dev.nav.cloud.nais.io:8443
tokenSecret: ready-access-relay-token
serverName: pg-foobar-main-a4f04c0c-rw.someteamname.svc.cluster.local
serverCASecret: pg-foobar-ca
Expand All @@ -24,6 +25,27 @@ status:
---
apiVersion: nais.io/v1
kind: PostgresAccess
metadata:
name: ready-no-endpoint-access
namespace: someteamname
uid: 44444444-4444-4444-8444-444444444444
spec:
postgresBranch: foobar-main-a4f04c0c
username: user@usersen.com
accessLevel: read
expiresAt: "2099-09-17T12:00:00Z"
status:
databaseRole: user-foobar-role
relayAccess: ready-no-endpoint-access
tokenSecret: ready-no-endpoint-access-relay-token
serverName: pg-foobar-main-a4f04c0c-rw.someteamname.svc.cluster.local
serverCASecret: pg-foobar-ca
conditions:
- type: Ready
status: "True"
---
apiVersion: nais.io/v1
kind: PostgresAccess
metadata:
name: recovered-access
namespace: someteamname
Expand Down Expand Up @@ -98,6 +120,7 @@ spec:
status:
databaseRole: user-foobar-role
relayAccess: missing-secret-access
relayEndpoint: https://relay.external.dev.nav.cloud.nais.io:8443
tokenSecret: missing-secret-access-relay-token
serverName: pg-foobar-main-a4f04c0c-rw.someteamname.svc.cluster.local
serverCASecret: pg-foobar-ca
Expand Down
1 change: 0 additions & 1 deletion internal/persistence/postgres/connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ func loadPostgresAccessConnection(ctx context.Context, access *unstructured.Unst
return apierror.Errorf("PostgresAccess %q is not ready", access.GetName())
}
connection.ServerName = serverName
connection.RelayEndpoint = fmt.Sprintf("https://relay.external.%s.%s.cloud.nais.io:8443", input.EnvironmentName, fromContext(ctx).tenantName)
relayName, _, err := unstructured.NestedString(access.Object, "status", "relayAccess")
if err != nil || relayName == "" {
return apierror.Errorf("PostgresAccess %q is not ready", access.GetName())
Expand Down
13 changes: 12 additions & 1 deletion internal/persistence/postgres/queries.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,13 @@ func GetPostgresAccessConnection(ctx context.Context, input PostgresAccessConnec
if state, _ := postgresAccessState(resource, resource.Spec.ExpiresAt.Time); state != PostgresAccessStateReady || access.GetDeletionTimestamp() != nil {
return nil, nil
}
endpoint, _, err := unstructured.NestedString(access.Object, "status", "relayEndpoint")
if err != nil {
return nil, fmt.Errorf("reading relay endpoint for PostgresAccess %q: %w", input.Name, err)
}
if endpoint == "" {
return nil, nil
}

connection, credentialSecretName, err := postgresAccessConnectionDetails(access, time.Now())
if err != nil {
Expand Down Expand Up @@ -307,7 +314,11 @@ func postgresAccessConnectionDetails(access *unstructured.Unstructured, now time
if obj.Status.RelayAccess == "" || obj.Status.TokenSecret == "" || obj.Status.DatabaseRole == "" || obj.Status.ServerName == "" || obj.Status.ServerCASecret == "" {
return nil, "", apierror.Errorf("PostgresAccess %q is not ready", access.GetName())
}
return &PostgresAccessConnectionDetails{}, obj.Status.TokenSecret, nil
endpoint, _, err := unstructured.NestedString(access.Object, "status", "relayEndpoint")
if err != nil || endpoint == "" {
return nil, "", apierror.Errorf("PostgresAccess %q is not ready", access.GetName())
}
return &PostgresAccessConnectionDetails{RelayEndpoint: endpoint}, obj.Status.TokenSecret, nil
}

func toPostgresAccess(u *unstructured.Unstructured, teamSlug slug.Slug, environmentName string) (*PostgresAccess, error) {
Expand Down
8 changes: 6 additions & 2 deletions internal/persistence/postgres/queries_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ func TestPostgresAccessConnectionDetails(t *testing.T) {
"status": map[string]any{
"databaseRole": "personal-role",
"relayAccess": "access",
"relayEndpoint": "https://relay.external.dev.nav.cloud.nais.io:8443",
"tokenSecret": "access-relay-token",
"serverName": "pg-orders-rw.team.svc.cluster.local",
"serverCASecret": "pg-orders-ca",
Expand All @@ -179,6 +180,9 @@ func TestPostgresAccessConnectionDetails(t *testing.T) {
{name: "missing relay mapping", edit: func(u *unstructured.Unstructured) {
unstructured.RemoveNestedField(u.Object, "status", "relayAccess")
}, want: "not ready"},
{name: "missing relay endpoint", edit: func(u *unstructured.Unstructured) {
unstructured.RemoveNestedField(u.Object, "status", "relayEndpoint")
}, want: "not ready"},
{name: "missing server name", edit: func(u *unstructured.Unstructured) {
unstructured.RemoveNestedField(u.Object, "status", "serverName")
}, want: "not ready"},
Expand All @@ -205,8 +209,8 @@ func TestPostgresAccessConnectionDetails(t *testing.T) {
if secretName != "access-relay-token" {
t.Errorf("secret name = %q", secretName)
}
if got == nil {
t.Fatal("connection is nil")
if got == nil || got.RelayEndpoint != "https://relay.external.dev.nav.cloud.nais.io:8443" {
t.Fatalf("connection endpoint = %v, want status endpoint", got)
}
})
}
Expand Down
Loading