From 4d61408132b25f3b4ede560c31c8ed4452105196 Mon Sep 17 00:00:00 2001 From: Johnny Fredheim Horvi Date: Thu, 17 Sep 2026 14:26:37 +0200 Subject: [PATCH 01/19] feat: pgaccess --- .../console-backend-rbac/templates/rbac.yaml | 14 + integration_tests/create_postgres_access.lua | 235 ++ .../postgres_access_expired-access.yaml | 20 + ...postgres_access_missing-secret-access.yaml | 20 + .../postgres_access_pending-access.yaml | 20 + .../someteamname/postgres_access_ready.yaml | 23 + .../dev/someteamname/postgres_foobar.yaml | 15 + .../someteamname/postgres_progressing.yaml | 22 + .../secret_ready_access_credentials.yaml | 10 + internal/auth/authz/queries.go | 4 + ...add_postgres_access_read_authorization.sql | 29 + .../graph/gengql/activitylog.generated.go | 14 + internal/graph/gengql/postgres.generated.go | 3079 +++++++++++++---- internal/graph/gengql/root_.generated.go | 608 ++++ internal/graph/gengql/schema.generated.go | 265 ++ internal/graph/postgres.resolvers.go | 32 + internal/graph/schema/postgres.graphqls | 140 + internal/persistence/postgres/activitylog.go | 36 +- internal/persistence/postgres/models.go | 220 ++ internal/persistence/postgres/node.go | 17 +- internal/persistence/postgres/queries.go | 346 +- internal/persistence/postgres/queries_test.go | 224 ++ 22 files changed, 4711 insertions(+), 682 deletions(-) create mode 100644 integration_tests/create_postgres_access.lua create mode 100644 integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_expired-access.yaml create mode 100644 integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_missing-secret-access.yaml create mode 100644 integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_pending-access.yaml create mode 100644 integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_ready.yaml create mode 100644 integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_foobar.yaml create mode 100644 integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_progressing.yaml create mode 100644 integration_tests/k8s_resources/create_postgres_access/dev/someteamname/secret_ready_access_credentials.yaml create mode 100644 internal/database/migrations/0075_add_postgres_access_read_authorization.sql create mode 100644 internal/persistence/postgres/queries_test.go diff --git a/charts/console-backend-rbac/templates/rbac.yaml b/charts/console-backend-rbac/templates/rbac.yaml index 715aa0e95..79d7840d3 100644 --- a/charts/console-backend-rbac/templates/rbac.yaml +++ b/charts/console-backend-rbac/templates/rbac.yaml @@ -119,6 +119,13 @@ rules: - update - patch - delete + - apiGroups: + - "nais.io" + resources: + - postgresaccesses + verbs: + - get + - create - apiGroups: - "aiven.nais.io" resources: @@ -273,6 +280,13 @@ rules: - get - list - watch + - apiGroups: + - "nais.io" + resources: + - postgresaccesses + verbs: + - get + - create - apiGroups: - "" resources: diff --git a/integration_tests/create_postgres_access.lua b/integration_tests/create_postgres_access.lua new file mode 100644 index 000000000..181113683 --- /dev/null +++ b/integration_tests/create_postgres_access.lua @@ -0,0 +1,235 @@ +local user = User.new("user", "user@usersen.com") +local otherMemberUser = User.new("othermember", "othermember@usersen.com") +local nonMemberUser = User.new("nonmember", "other@user.com") + +local mainTeam = Team.new("someteamname", "purpose", "#slack_channel") +mainTeam:addMember(user) +mainTeam:addMember(otherMemberUser) + +Helper.readK8sResources("k8s_resources/create_postgres_access") + +Test.gql("Create personal postgres access without authorization", function(t) + t.addHeader("x-user-email", nonMemberUser:email()) + t.query [[ + mutation CreatePostgresAccess { + createPostgresAccess(input: { + postgresInstance: "foobar" + environmentName: "dev" + teamSlug: "someteamname" + accessLevel: READ + clientWireGuardPublicKey: "client-public-key" + }) { + name + expiresAt + } + } + ]] + + t.check { + errors = { + { + locations = NotNull(), + message = Contains('you need the "postgres:access:grant" authorization.'), + path = { "createPostgresAccess" }, + }, + }, + data = Null, + } +end) + +Test.gql("Create personal postgres access rejects an unknown instance", function(t) + t.addHeader("x-user-email", user:email()) + t.query [[ + mutation CreatePostgresAccess { + createPostgresAccess(input: { + postgresInstance: "unknown" + environmentName: "dev" + teamSlug: "someteamname" + accessLevel: READ + clientWireGuardPublicKey: "client-public-key" + }) { + name + expiresAt + } + } + ]] + + t.check { + errors = { + { + extensions = { field = "postgresInstance" }, + message = Contains("Could not find postgres cluster"), + path = { "createPostgresAccess" }, + }, + }, + data = Null, + } +end) + +Test.gql("Create personal postgres access rejects an unavailable instance", function(t) + t.addHeader("x-user-email", user:email()) + t.query [[ + mutation CreatePostgresAccess { + createPostgresAccess(input: { + postgresInstance: "progressing" + environmentName: "dev" + teamSlug: "someteamname" + accessLevel: READ + clientWireGuardPublicKey: "client-public-key" + }) { + name + expiresAt + } + } + ]] + + t.check { + errors = { + { + extensions = { field = "postgresInstance" }, + message = Contains("is not available"), + path = { "createPostgresAccess" }, + }, + }, + data = Null, + } +end) + +Test.gql("Create personal postgres access", function(t) + t.addHeader("x-user-email", user:email()) + t.query [[ + mutation CreatePostgresAccess { + createPostgresAccess(input: { + postgresInstance: "foobar" + environmentName: "dev" + teamSlug: "someteamname" + accessLevel: READWRITE + clientWireGuardPublicKey: "client-public-key" + }) { + name + expiresAt + } + } + ]] + + t.check { + data = { + createPostgresAccess = { + name = NotNull(), + expiresAt = NotNull(), + }, + }, + } +end) + +Test.gql("Personal postgres access is audited as a self-grant", function(t) + t.addHeader("x-user-email", user:email()) + t.query [[ + { + team(slug: "someteamname") { + activityLog { + nodes { + message + ... on PostgresPersonalAccessCreatedActivityLogEntry { + data { + username + expiresAt + } + } + } + } + } + } + ]] + + t.check { + data = { + team = { + activityLog = { + nodes = { + { + message = Contains("Created personal Postgres access for user@usersen.com"), + data = { + username = "user@usersen.com", + expiresAt = NotNull(), + }, + }, + }, + }, + }, + }, + } +end) + +Test.gql("PostgresAccess connection returns credentials only to its owner", function(t) + t.addHeader("x-user-email", user:email()) + t.query [[ + query GetPostgresAccessConnection { + postgresAccessConnection(input: {name: "ready-access", teamSlug: "someteamname", environmentName: "dev"}) { + password + caCertificate + serverName + tunnel { + endpoint + gatewayPublicKey + } + } + } + ]] + + t.check { + data = { + postgresAccessConnection = { + password = "supersecret", + caCertificate = "test-ca-certificate", + serverName = "pg-foobar-rw.someteamname.svc.cluster.local", + tunnel = { endpoint = "1.2.3.4:12345", gatewayPublicKey = "gw-public-key" }, + }, + }, + } +end) + +Test.gql("PostgresAccess connection rejects a different team member", function(t) + t.addHeader("x-user-email", otherMemberUser:email()) + t.query [[ + query { postgresAccessConnection(input: {name: "ready-access", teamSlug: "someteamname", environmentName: "dev"}) { password } } + ]] + t.check { + errors = { { locations = NotNull(), path = { "postgresAccessConnection" }, message = Contains("not authorized") } }, + data = Null, + } +end) + +Test.gql("PostgresAccess connection rejects expired, unready, and missing-secret access", function(t) + t.addHeader("x-user-email", user:email()) + for _, test in ipairs({ + { name = "expired-access", message = "has expired" }, + { name = "pending-access", message = "is not ready" }, + { name = "missing-secret-access", message = "credentials" }, + }) do + t.query(string.format( + [[query { postgresAccessConnection(input: {name: "%s", teamSlug: "someteamname", environmentName: "dev"}) { password } }]], + test.name)) + t.check { + errors = { { locations = NotNull(), path = { "postgresAccessConnection" }, message = Contains(test.message) } }, + data = Null, + } + end +end) + +Test.gql("Personal postgres connection retrieval is audited", function(t) + t.addHeader("x-user-email", user:email()) + t.query [[ + query { postgresAccessConnection(input: {name: "ready-access", teamSlug: "someteamname", environmentName: "dev"}) { password } } + ]] + t.check { data = { postgresAccessConnection = { password = "supersecret" } } } + + t.query [[ + { team(slug: "someteamname") { activityLog(first: 1) { nodes { message ... on PostgresPersonalAccessConnectionActivityLogEntry { resourceName } } } } } + ]] + t.check { + data = { team = { activityLog = { nodes = { + { message = Contains("Retrieved personal Postgres connection materials"), resourceName = "ready-access" }, + } } } }, + } +end) diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_expired-access.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_expired-access.yaml new file mode 100644 index 000000000..0e3b15701 --- /dev/null +++ b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_expired-access.yaml @@ -0,0 +1,20 @@ +apiVersion: nais.io/v1 +kind: PostgresAccess +metadata: + name: expired-access + namespace: someteamname +spec: + postgresInstance: foobar + username: user@usersen.com + accessLevel: read + expiresAt: "2000-01-01T00:00:00Z" + clientWireGuardPublicKey: client-public-key +status: + credentialSecretName: expired-access-credentials + serverName: pg-foobar-rw.someteamname.svc.cluster.local + conditions: + - type: Ready + status: "True" + tunnel: + endpoint: "1.2.3.4:12345" + gatewayPublicKey: gw-public-key diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_missing-secret-access.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_missing-secret-access.yaml new file mode 100644 index 000000000..b8beb8444 --- /dev/null +++ b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_missing-secret-access.yaml @@ -0,0 +1,20 @@ +apiVersion: nais.io/v1 +kind: PostgresAccess +metadata: + name: missing-secret-access + namespace: someteamname +spec: + postgresInstance: foobar + username: user@usersen.com + accessLevel: read + expiresAt: "2099-09-17T12:00:00Z" + clientWireGuardPublicKey: client-public-key +status: + credentialSecretName: missing-secret-access-credentials + serverName: pg-foobar-rw.someteamname.svc.cluster.local + conditions: + - type: Ready + status: "True" + tunnel: + endpoint: "1.2.3.4:12345" + gatewayPublicKey: gw-public-key diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_pending-access.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_pending-access.yaml new file mode 100644 index 000000000..67410521c --- /dev/null +++ b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_pending-access.yaml @@ -0,0 +1,20 @@ +apiVersion: nais.io/v1 +kind: PostgresAccess +metadata: + name: pending-access + namespace: someteamname +spec: + postgresInstance: foobar + username: user@usersen.com + accessLevel: read + expiresAt: "2099-09-17T12:00:00Z" + clientWireGuardPublicKey: client-public-key +status: + credentialSecretName: pending-access-credentials + serverName: pg-foobar-rw.someteamname.svc.cluster.local + conditions: + - type: Ready + status: "False" + tunnel: + endpoint: "1.2.3.4:12345" + gatewayPublicKey: gw-public-key diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_ready.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_ready.yaml new file mode 100644 index 000000000..0a611ad72 --- /dev/null +++ b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_ready.yaml @@ -0,0 +1,23 @@ +apiVersion: nais.io/v1 +kind: PostgresAccess +metadata: + name: ready-access + namespace: someteamname +spec: + postgresInstance: foobar + username: user@usersen.com + accessLevel: readwrite + expiresAt: "2099-09-17T12:00:00Z" + clientWireGuardPublicKey: client-public-key +status: + credentialSecretName: ready-access-credentials + serverName: pg-foobar-rw.someteamname.svc.cluster.local + conditions: + - type: Ready + status: "True" + reason: Ready + message: "Database role and tunnel are ready" + tunnel: + name: ready-access + endpoint: "1.2.3.4:12345" + gatewayPublicKey: "gw-public-key" diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_foobar.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_foobar.yaml new file mode 100644 index 000000000..6796d66e0 --- /dev/null +++ b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_foobar.yaml @@ -0,0 +1,15 @@ +--- +apiVersion: data.nais.io/v1 +kind: Postgres +metadata: + name: foobar + namespace: someteamname +spec: + cluster: + majorVersion: "17" + resources: + cpu: 100m + diskSize: 2Gi + memory: 2G + database: + collation: nb_NO diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_progressing.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_progressing.yaml new file mode 100644 index 000000000..8a926e827 --- /dev/null +++ b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_progressing.yaml @@ -0,0 +1,22 @@ +--- +apiVersion: data.nais.io/v1 +kind: Postgres +metadata: + name: progressing + namespace: someteamname +spec: + cluster: + majorVersion: "17" + resources: + cpu: 100m + diskSize: 2Gi + memory: 2G + database: + collation: nb_NO +status: + conditions: + - type: Progressing + status: "True" + reason: Reconciling + message: Creating Postgres cluster + lastTransitionTime: "2026-09-17T00:00:00Z" diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/secret_ready_access_credentials.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/secret_ready_access_credentials.yaml new file mode 100644 index 000000000..4a845780e --- /dev/null +++ b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/secret_ready_access_credentials.yaml @@ -0,0 +1,10 @@ +apiVersion: v1 +kind: Secret +metadata: + name: ready-access-credentials + namespace: someteamname +type: kubernetes.io/basic-auth +data: + username: YXBwLWZvb2Jhci1hYmMxMjM= + password: c3VwZXJzZWNyZXQ= + ca.crt: dGVzdC1jYS1jZXJ0aWZpY2F0ZQ== diff --git a/internal/auth/authz/queries.go b/internal/auth/authz/queries.go index e9df53b29..55bc53d5f 100644 --- a/internal/auth/authz/queries.go +++ b/internal/auth/authz/queries.go @@ -312,6 +312,10 @@ func CanDeleteOpenSearch(ctx context.Context, teamSlug slug.Slug) error { return requireTeamAuthorization(ctx, teamSlug, "opensearches:delete") } +func CanReadPostgresAccess(ctx context.Context, teamSlug slug.Slug) error { + return requireStrictTeamAuthorization(ctx, teamSlug, "postgres:access:read") +} + func CanGrantPostgresAccess(ctx context.Context, teamSlug slug.Slug) error { return requireStrictTeamAuthorization(ctx, teamSlug, "postgres:access:grant") } diff --git a/internal/database/migrations/0075_add_postgres_access_read_authorization.sql b/internal/database/migrations/0075_add_postgres_access_read_authorization.sql new file mode 100644 index 000000000..18a2aa221 --- /dev/null +++ b/internal/database/migrations/0075_add_postgres_access_read_authorization.sql @@ -0,0 +1,29 @@ +-- +goose Up +INSERT INTO + authorizations (name, description) +VALUES + ( + 'postgres:access:read', + 'Permission to read personal Postgres access status and credentials' + ) +ON CONFLICT (name) DO NOTHING +; + +INSERT INTO + role_authorizations (role_name, authorization_name) +VALUES + ('Team member', 'postgres:access:read'), + ('Team owner', 'postgres:access:read') +ON CONFLICT (role_name, authorization_name) DO NOTHING +; + +-- +goose Down +DELETE FROM role_authorizations +WHERE + authorization_name = 'postgres:access:read' +; + +DELETE FROM authorizations +WHERE + name = 'postgres:access:read' +; diff --git a/internal/graph/gengql/activitylog.generated.go b/internal/graph/gengql/activitylog.generated.go index 8152a69b2..dbdf65c8c 100644 --- a/internal/graph/gengql/activitylog.generated.go +++ b/internal/graph/gengql/activitylog.generated.go @@ -789,6 +789,20 @@ func (ec *executionContext) _ActivityLogEntry(ctx context.Context, sel ast.Selec return graphql.Null } return ec._ReconcilerConfiguredActivityLogEntry(ctx, sel, obj) + case postgres.PostgresPersonalAccessCreatedActivityLogEntry: + return ec._PostgresPersonalAccessCreatedActivityLogEntry(ctx, sel, &obj) + case *postgres.PostgresPersonalAccessCreatedActivityLogEntry: + if obj == nil { + return graphql.Null + } + return ec._PostgresPersonalAccessCreatedActivityLogEntry(ctx, sel, obj) + case postgres.PostgresPersonalAccessConnectionActivityLogEntry: + return ec._PostgresPersonalAccessConnectionActivityLogEntry(ctx, sel, &obj) + case *postgres.PostgresPersonalAccessConnectionActivityLogEntry: + if obj == nil { + return graphql.Null + } + return ec._PostgresPersonalAccessConnectionActivityLogEntry(ctx, sel, obj) case postgres.PostgresGrantAccessActivityLogEntry: return ec._PostgresGrantAccessActivityLogEntry(ctx, sel, &obj) case *postgres.PostgresGrantAccessActivityLogEntry: diff --git a/internal/graph/gengql/postgres.generated.go b/internal/graph/gengql/postgres.generated.go index fc1a3e91c..e19af967d 100644 --- a/internal/graph/gengql/postgres.generated.go +++ b/internal/graph/gengql/postgres.generated.go @@ -24,6 +24,11 @@ import ( // region ************************** generated!.gotpl ************************** +type PostgresAccessResolver interface { + Team(ctx context.Context, obj *postgres.PostgresAccess) (*team.Team, error) + TeamEnvironment(ctx context.Context, obj *postgres.PostgresAccess) (*team.TeamEnvironment, error) + PostgresInstance(ctx context.Context, obj *postgres.PostgresAccess) (*postgres.PostgresInstance, error) +} type PostgresInstanceResolver interface { Team(ctx context.Context, obj *postgres.PostgresInstance) (*team.Team, error) TeamEnvironment(ctx context.Context, obj *postgres.PostgresInstance) (*team.TeamEnvironment, error) @@ -86,6 +91,52 @@ func (ec *executionContext) field_PostgresInstance_workloads_args(ctx context.Co // region **************************** field.gotpl ***************************** +func (ec *executionContext) _CreatePostgresAccessPayload_name(ctx context.Context, field graphql.CollectedField, obj *postgres.CreatePostgresAccessPayload) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_CreatePostgresAccessPayload_name(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Name, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { + return ec.marshalNString2string(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_CreatePostgresAccessPayload_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("CreatePostgresAccessPayload", field, false, false, errors.New("field of type String does not have child fields")) +} + +func (ec *executionContext) _CreatePostgresAccessPayload_expiresAt(ctx context.Context, field graphql.CollectedField, obj *postgres.CreatePostgresAccessPayload) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_CreatePostgresAccessPayload_expiresAt(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.ExpiresAt, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v time.Time) graphql.Marshaler { + return ec.marshalNTime2timeᚐTime(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_CreatePostgresAccessPayload_expiresAt(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("CreatePostgresAccessPayload", field, false, false, errors.New("field of type Time does not have child fields")) +} + func (ec *executionContext) _DeletePostgresPayload_postgresDeleted(ctx context.Context, field graphql.CollectedField, obj *postgres.DeletePostgresPayload) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -132,13 +183,13 @@ func (ec *executionContext) fieldContext_GrantPostgresAccessPayload_error(_ cont return graphql.NewScalarFieldContext("GrantPostgresAccessPayload", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresDeletedActivityLogEntry_id(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresDeletedActivityLogEntry) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresAccess_id(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccess) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresDeletedActivityLogEntry_id(ctx, field) + return ec.fieldContext_PostgresAccess_id(ctx, field) }, func(ctx context.Context) (any, error) { return obj.ID(), nil @@ -151,20 +202,20 @@ func (ec *executionContext) _PostgresDeletedActivityLogEntry_id(ctx context.Cont true, ) } -func (ec *executionContext) fieldContext_PostgresDeletedActivityLogEntry_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresDeletedActivityLogEntry", field, true, false, errors.New("field of type ID does not have child fields")) +func (ec *executionContext) fieldContext_PostgresAccess_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresAccess", field, true, false, errors.New("field of type ID does not have child fields")) } -func (ec *executionContext) _PostgresDeletedActivityLogEntry_actor(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresDeletedActivityLogEntry) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresAccess_name(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccess) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresDeletedActivityLogEntry_actor(ctx, field) + return ec.fieldContext_PostgresAccess_name(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Actor, nil + return obj.Name, nil }, nil, func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { @@ -174,135 +225,185 @@ func (ec *executionContext) _PostgresDeletedActivityLogEntry_actor(ctx context.C true, ) } -func (ec *executionContext) fieldContext_PostgresDeletedActivityLogEntry_actor(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresDeletedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) +func (ec *executionContext) fieldContext_PostgresAccess_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresAccess", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresDeletedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresDeletedActivityLogEntry) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresAccess_team(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccess) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresDeletedActivityLogEntry_createdAt(ctx, field) + return ec.fieldContext_PostgresAccess_team(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.CreatedAt, nil + return ec.Resolvers.PostgresAccess().Team(ctx, obj) }, nil, - func(ctx context.Context, selections ast.SelectionSet, v time.Time) graphql.Marshaler { - return ec.marshalNTime2timeᚐTime(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *team.Team) graphql.Marshaler { + return ec.marshalNTeam2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋteamᚐTeam(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresDeletedActivityLogEntry_createdAt(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresDeletedActivityLogEntry", field, false, false, errors.New("field of type Time does not have child fields")) +func (ec *executionContext) fieldContext_PostgresAccess_team(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "PostgresAccess", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_Team(ctx, field) + }, + } + return fc, nil } -func (ec *executionContext) _PostgresDeletedActivityLogEntry_message(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresDeletedActivityLogEntry) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresAccess_teamEnvironment(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccess) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresDeletedActivityLogEntry_message(ctx, field) + return ec.fieldContext_PostgresAccess_teamEnvironment(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Message, nil + return ec.Resolvers.PostgresAccess().TeamEnvironment(ctx, obj) }, nil, - func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { - return ec.marshalNString2string(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *team.TeamEnvironment) graphql.Marshaler { + return ec.marshalNTeamEnvironment2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋteamᚐTeamEnvironment(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresDeletedActivityLogEntry_message(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresDeletedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) +func (ec *executionContext) fieldContext_PostgresAccess_teamEnvironment(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "PostgresAccess", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_TeamEnvironment(ctx, field) + }, + } + return fc, nil } -func (ec *executionContext) _PostgresDeletedActivityLogEntry_resourceType(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresDeletedActivityLogEntry) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresAccess_postgresInstance(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccess) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresDeletedActivityLogEntry_resourceType(ctx, field) + return ec.fieldContext_PostgresAccess_postgresInstance(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.ResourceType, nil + return ec.Resolvers.PostgresAccess().PostgresInstance(ctx, obj) }, nil, - func(ctx context.Context, selections ast.SelectionSet, v activitylog.ActivityLogEntryResourceType) graphql.Marshaler { - return ec.marshalNActivityLogEntryResourceType2githubᚗcomᚋnaisᚋapiᚋinternalᚋactivitylogᚐActivityLogEntryResourceType(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *postgres.PostgresInstance) graphql.Marshaler { + return ec.marshalNPostgresInstance2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstance(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresDeletedActivityLogEntry_resourceType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresDeletedActivityLogEntry", field, false, false, errors.New("field of type ActivityLogEntryResourceType does not have child fields")) +func (ec *executionContext) fieldContext_PostgresAccess_postgresInstance(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "PostgresAccess", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_PostgresInstance(ctx, field) + }, + } + return fc, nil } -func (ec *executionContext) _PostgresDeletedActivityLogEntry_resourceName(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresDeletedActivityLogEntry) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresAccess_accessLevel(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccess) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresDeletedActivityLogEntry_resourceName(ctx, field) + return ec.fieldContext_PostgresAccess_accessLevel(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.ResourceName, nil + return obj.AccessLevel, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { - return ec.marshalNString2string(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v postgres.PostgresAccessLevel) graphql.Marshaler { + return ec.marshalNPostgresAccessLevel2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccessLevel(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresDeletedActivityLogEntry_resourceName(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresDeletedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) +func (ec *executionContext) fieldContext_PostgresAccess_accessLevel(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresAccess", field, false, false, errors.New("field of type PostgresAccessLevel does not have child fields")) } -func (ec *executionContext) _PostgresDeletedActivityLogEntry_teamSlug(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresDeletedActivityLogEntry) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresAccess_expiresAt(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccess) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresDeletedActivityLogEntry_teamSlug(ctx, field) + return ec.fieldContext_PostgresAccess_expiresAt(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.TeamSlug, nil + return obj.ExpiresAt, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v *slug.Slug) graphql.Marshaler { - return ec.marshalNSlug2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋslugᚐSlug(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v time.Time) graphql.Marshaler { + return ec.marshalNTime2timeᚐTime(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresDeletedActivityLogEntry_teamSlug(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresDeletedActivityLogEntry", field, false, false, errors.New("field of type Slug does not have child fields")) +func (ec *executionContext) fieldContext_PostgresAccess_expiresAt(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresAccess", field, false, false, errors.New("field of type Time does not have child fields")) } -func (ec *executionContext) _PostgresDeletedActivityLogEntry_environmentName(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresDeletedActivityLogEntry) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresAccess_state(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccess) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresDeletedActivityLogEntry_environmentName(ctx, field) + return ec.fieldContext_PostgresAccess_state(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.EnvironmentName, nil + return obj.State, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v postgres.PostgresAccessState) graphql.Marshaler { + return ec.marshalNPostgresAccessState2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccessState(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_PostgresAccess_state(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresAccess", field, false, false, errors.New("field of type PostgresAccessState does not have child fields")) +} + +func (ec *executionContext) _PostgresAccess_message(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccess) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_PostgresAccess_message(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Message, nil }, nil, func(ctx context.Context, selections ast.SelectionSet, v *string) graphql.Marshaler { @@ -312,43 +413,52 @@ func (ec *executionContext) _PostgresDeletedActivityLogEntry_environmentName(ctx false, ) } -func (ec *executionContext) fieldContext_PostgresDeletedActivityLogEntry_environmentName(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresDeletedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) +func (ec *executionContext) fieldContext_PostgresAccess_message(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresAccess", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresGrantAccessActivityLogEntry_id(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresGrantAccessActivityLogEntry) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresAccess_tunnel(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccess) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresGrantAccessActivityLogEntry_id(ctx, field) + return ec.fieldContext_PostgresAccess_tunnel(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.ID(), nil + return obj.Tunnel, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v ident.Ident) graphql.Marshaler { - return ec.marshalNID2githubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋidentᚐIdent(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *postgres.PostgresAccessTunnel) graphql.Marshaler { + return ec.marshalOPostgresAccessTunnel2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccessTunnel(ctx, selections, v) }, true, - true, + false, ) } -func (ec *executionContext) fieldContext_PostgresGrantAccessActivityLogEntry_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresGrantAccessActivityLogEntry", field, true, false, errors.New("field of type ID does not have child fields")) +func (ec *executionContext) fieldContext_PostgresAccess_tunnel(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "PostgresAccess", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_PostgresAccessTunnel(ctx, field) + }, + } + return fc, nil } -func (ec *executionContext) _PostgresGrantAccessActivityLogEntry_actor(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresGrantAccessActivityLogEntry) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresAccessConnectionPayload_password(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccessConnectionPayload) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresGrantAccessActivityLogEntry_actor(ctx, field) + return ec.fieldContext_PostgresAccessConnectionPayload_password(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Actor, nil + return obj.Password, nil }, nil, func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { @@ -358,43 +468,43 @@ func (ec *executionContext) _PostgresGrantAccessActivityLogEntry_actor(ctx conte true, ) } -func (ec *executionContext) fieldContext_PostgresGrantAccessActivityLogEntry_actor(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresGrantAccessActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) +func (ec *executionContext) fieldContext_PostgresAccessConnectionPayload_password(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresAccessConnectionPayload", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresGrantAccessActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresGrantAccessActivityLogEntry) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresAccessConnectionPayload_caCertificate(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccessConnectionPayload) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresGrantAccessActivityLogEntry_createdAt(ctx, field) + return ec.fieldContext_PostgresAccessConnectionPayload_caCertificate(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.CreatedAt, nil + return obj.CACertificate, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v time.Time) graphql.Marshaler { - return ec.marshalNTime2timeᚐTime(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { + return ec.marshalNString2string(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresGrantAccessActivityLogEntry_createdAt(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresGrantAccessActivityLogEntry", field, false, false, errors.New("field of type Time does not have child fields")) +func (ec *executionContext) fieldContext_PostgresAccessConnectionPayload_caCertificate(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresAccessConnectionPayload", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresGrantAccessActivityLogEntry_message(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresGrantAccessActivityLogEntry) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresAccessConnectionPayload_serverName(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccessConnectionPayload) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresGrantAccessActivityLogEntry_message(ctx, field) + return ec.fieldContext_PostgresAccessConnectionPayload_serverName(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Message, nil + return obj.ServerName, nil }, nil, func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { @@ -404,43 +514,52 @@ func (ec *executionContext) _PostgresGrantAccessActivityLogEntry_message(ctx con true, ) } -func (ec *executionContext) fieldContext_PostgresGrantAccessActivityLogEntry_message(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresGrantAccessActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) +func (ec *executionContext) fieldContext_PostgresAccessConnectionPayload_serverName(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresAccessConnectionPayload", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresGrantAccessActivityLogEntry_resourceType(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresGrantAccessActivityLogEntry) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresAccessConnectionPayload_tunnel(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccessConnectionPayload) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresGrantAccessActivityLogEntry_resourceType(ctx, field) + return ec.fieldContext_PostgresAccessConnectionPayload_tunnel(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.ResourceType, nil + return obj.Tunnel, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v activitylog.ActivityLogEntryResourceType) graphql.Marshaler { - return ec.marshalNActivityLogEntryResourceType2githubᚗcomᚋnaisᚋapiᚋinternalᚋactivitylogᚐActivityLogEntryResourceType(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v postgres.PostgresAccessConnectionTunnel) graphql.Marshaler { + return ec.marshalNPostgresAccessConnectionTunnel2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccessConnectionTunnel(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresGrantAccessActivityLogEntry_resourceType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresGrantAccessActivityLogEntry", field, false, false, errors.New("field of type ActivityLogEntryResourceType does not have child fields")) +func (ec *executionContext) fieldContext_PostgresAccessConnectionPayload_tunnel(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "PostgresAccessConnectionPayload", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_PostgresAccessConnectionTunnel(ctx, field) + }, + } + return fc, nil } -func (ec *executionContext) _PostgresGrantAccessActivityLogEntry_resourceName(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresGrantAccessActivityLogEntry) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresAccessConnectionTunnel_endpoint(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccessConnectionTunnel) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresGrantAccessActivityLogEntry_resourceName(ctx, field) + return ec.fieldContext_PostgresAccessConnectionTunnel_endpoint(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.ResourceName, nil + return obj.Endpoint, nil }, nil, func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { @@ -450,1097 +569,2161 @@ func (ec *executionContext) _PostgresGrantAccessActivityLogEntry_resourceName(ct true, ) } -func (ec *executionContext) fieldContext_PostgresGrantAccessActivityLogEntry_resourceName(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresGrantAccessActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) +func (ec *executionContext) fieldContext_PostgresAccessConnectionTunnel_endpoint(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresAccessConnectionTunnel", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresGrantAccessActivityLogEntry_teamSlug(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresGrantAccessActivityLogEntry) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresAccessConnectionTunnel_gatewayPublicKey(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccessConnectionTunnel) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresGrantAccessActivityLogEntry_teamSlug(ctx, field) + return ec.fieldContext_PostgresAccessConnectionTunnel_gatewayPublicKey(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.TeamSlug, nil + return obj.GatewayPublicKey, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v *slug.Slug) graphql.Marshaler { - return ec.marshalNSlug2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋslugᚐSlug(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { + return ec.marshalNString2string(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresGrantAccessActivityLogEntry_teamSlug(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresGrantAccessActivityLogEntry", field, false, false, errors.New("field of type Slug does not have child fields")) +func (ec *executionContext) fieldContext_PostgresAccessConnectionTunnel_gatewayPublicKey(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresAccessConnectionTunnel", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresGrantAccessActivityLogEntry_environmentName(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresGrantAccessActivityLogEntry) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresAccessTunnel_name(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccessTunnel) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresGrantAccessActivityLogEntry_environmentName(ctx, field) + return ec.fieldContext_PostgresAccessTunnel_name(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.EnvironmentName, nil + return obj.Name, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v *string) graphql.Marshaler { - return ec.marshalOString2ᚖstring(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { + return ec.marshalNString2string(ctx, selections, v) }, true, - false, + true, ) } -func (ec *executionContext) fieldContext_PostgresGrantAccessActivityLogEntry_environmentName(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresGrantAccessActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) +func (ec *executionContext) fieldContext_PostgresAccessTunnel_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresAccessTunnel", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresGrantAccessActivityLogEntry_data(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresGrantAccessActivityLogEntry) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresAccessTunnel_endpoint(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccessTunnel) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresGrantAccessActivityLogEntry_data(ctx, field) + return ec.fieldContext_PostgresAccessTunnel_endpoint(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Data, nil + return obj.Endpoint, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v *postgres.PostgresGrantAccessActivityLogEntryData) graphql.Marshaler { - return ec.marshalNPostgresGrantAccessActivityLogEntryData2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresGrantAccessActivityLogEntryData(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *string) graphql.Marshaler { + return ec.marshalOString2ᚖstring(ctx, selections, v) }, true, - true, + false, ) } -func (ec *executionContext) fieldContext_PostgresGrantAccessActivityLogEntry_data(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "PostgresGrantAccessActivityLogEntry", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_PostgresGrantAccessActivityLogEntryData(ctx, field) - }, - } - return fc, nil +func (ec *executionContext) fieldContext_PostgresAccessTunnel_endpoint(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresAccessTunnel", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresGrantAccessActivityLogEntryData_grantee(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresGrantAccessActivityLogEntryData) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresAccessTunnel_gatewayPublicKey(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccessTunnel) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresGrantAccessActivityLogEntryData_grantee(ctx, field) + return ec.fieldContext_PostgresAccessTunnel_gatewayPublicKey(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Grantee, nil + return obj.GatewayPublicKey, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { - return ec.marshalNString2string(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *string) graphql.Marshaler { + return ec.marshalOString2ᚖstring(ctx, selections, v) }, true, - true, + false, ) } -func (ec *executionContext) fieldContext_PostgresGrantAccessActivityLogEntryData_grantee(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresGrantAccessActivityLogEntryData", field, false, false, errors.New("field of type String does not have child fields")) +func (ec *executionContext) fieldContext_PostgresAccessTunnel_gatewayPublicKey(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresAccessTunnel", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresGrantAccessActivityLogEntryData_until(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresGrantAccessActivityLogEntryData) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresDeletedActivityLogEntry_id(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresDeletedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresGrantAccessActivityLogEntryData_until(ctx, field) + return ec.fieldContext_PostgresDeletedActivityLogEntry_id(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Until, nil + return obj.ID(), nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v time.Time) graphql.Marshaler { - return ec.marshalNTime2timeᚐTime(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v ident.Ident) graphql.Marshaler { + return ec.marshalNID2githubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋidentᚐIdent(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresGrantAccessActivityLogEntryData_until(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresGrantAccessActivityLogEntryData", field, false, false, errors.New("field of type Time does not have child fields")) +func (ec *executionContext) fieldContext_PostgresDeletedActivityLogEntry_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresDeletedActivityLogEntry", field, true, false, errors.New("field of type ID does not have child fields")) } -func (ec *executionContext) _PostgresInstance_id(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstance) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresDeletedActivityLogEntry_actor(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresDeletedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstance_id(ctx, field) + return ec.fieldContext_PostgresDeletedActivityLogEntry_actor(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.ID(), nil + return obj.Actor, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v ident.Ident) graphql.Marshaler { - return ec.marshalNID2githubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋidentᚐIdent(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { + return ec.marshalNString2string(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresInstance_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresInstance", field, true, false, errors.New("field of type ID does not have child fields")) +func (ec *executionContext) fieldContext_PostgresDeletedActivityLogEntry_actor(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresDeletedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresInstance_name(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstance) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresDeletedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresDeletedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstance_name(ctx, field) + return ec.fieldContext_PostgresDeletedActivityLogEntry_createdAt(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Name, nil + return obj.CreatedAt, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { - return ec.marshalNString2string(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v time.Time) graphql.Marshaler { + return ec.marshalNTime2timeᚐTime(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresInstance_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresInstance", field, false, false, errors.New("field of type String does not have child fields")) +func (ec *executionContext) fieldContext_PostgresDeletedActivityLogEntry_createdAt(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresDeletedActivityLogEntry", field, false, false, errors.New("field of type Time does not have child fields")) } -func (ec *executionContext) _PostgresInstance_team(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstance) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresDeletedActivityLogEntry_message(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresDeletedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstance_team(ctx, field) + return ec.fieldContext_PostgresDeletedActivityLogEntry_message(ctx, field) }, func(ctx context.Context) (any, error) { - return ec.Resolvers.PostgresInstance().Team(ctx, obj) + return obj.Message, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v *team.Team) graphql.Marshaler { - return ec.marshalNTeam2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋteamᚐTeam(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { + return ec.marshalNString2string(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresInstance_team(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "PostgresInstance", - Field: field, - IsMethod: true, - IsResolver: true, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_Team(ctx, field) - }, - } - return fc, nil +func (ec *executionContext) fieldContext_PostgresDeletedActivityLogEntry_message(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresDeletedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresInstance_teamEnvironment(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstance) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresDeletedActivityLogEntry_resourceType(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresDeletedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstance_teamEnvironment(ctx, field) + return ec.fieldContext_PostgresDeletedActivityLogEntry_resourceType(ctx, field) }, func(ctx context.Context) (any, error) { - return ec.Resolvers.PostgresInstance().TeamEnvironment(ctx, obj) + return obj.ResourceType, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v *team.TeamEnvironment) graphql.Marshaler { - return ec.marshalNTeamEnvironment2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋteamᚐTeamEnvironment(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v activitylog.ActivityLogEntryResourceType) graphql.Marshaler { + return ec.marshalNActivityLogEntryResourceType2githubᚗcomᚋnaisᚋapiᚋinternalᚋactivitylogᚐActivityLogEntryResourceType(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresInstance_teamEnvironment(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "PostgresInstance", - Field: field, - IsMethod: true, - IsResolver: true, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_TeamEnvironment(ctx, field) - }, - } - return fc, nil +func (ec *executionContext) fieldContext_PostgresDeletedActivityLogEntry_resourceType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresDeletedActivityLogEntry", field, false, false, errors.New("field of type ActivityLogEntryResourceType does not have child fields")) } -func (ec *executionContext) _PostgresInstance_workloads(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstance) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresDeletedActivityLogEntry_resourceName(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresDeletedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstance_workloads(ctx, field) + return ec.fieldContext_PostgresDeletedActivityLogEntry_resourceName(ctx, field) }, func(ctx context.Context) (any, error) { - fc := graphql.GetFieldContext(ctx) - return ec.Resolvers.PostgresInstance().Workloads(ctx, obj, fc.Args["first"].(*int), fc.Args["after"].(*pagination.Cursor), fc.Args["last"].(*int), fc.Args["before"].(*pagination.Cursor)) + return obj.ResourceName, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v *pagination.Connection[workload.Workload]) graphql.Marshaler { - return ec.marshalNWorkloadConnection2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋpaginationᚐConnection(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { + return ec.marshalNString2string(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresInstance_workloads(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "PostgresInstance", - Field: field, - IsMethod: true, - IsResolver: true, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_WorkloadConnection(ctx, field) - }, - } - defer func() { - if r := recover(); r != nil { - err = ec.Recover(ctx, r) - ec.Error(ctx, err) - } - }() - ctx = graphql.WithFieldContext(ctx, fc) - if fc.Args, err = ec.field_PostgresInstance_workloads_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { - ec.Error(ctx, err) - return fc, err - } - return fc, nil +func (ec *executionContext) fieldContext_PostgresDeletedActivityLogEntry_resourceName(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresDeletedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresInstance_resources(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstance) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresDeletedActivityLogEntry_teamSlug(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresDeletedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstance_resources(ctx, field) + return ec.fieldContext_PostgresDeletedActivityLogEntry_teamSlug(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Resources, nil + return obj.TeamSlug, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v *postgres.PostgresInstanceResources) graphql.Marshaler { - return ec.marshalNPostgresInstanceResources2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceResources(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *slug.Slug) graphql.Marshaler { + return ec.marshalNSlug2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋslugᚐSlug(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresInstance_resources(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "PostgresInstance", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_PostgresInstanceResources(ctx, field) - }, - } - return fc, nil +func (ec *executionContext) fieldContext_PostgresDeletedActivityLogEntry_teamSlug(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresDeletedActivityLogEntry", field, false, false, errors.New("field of type Slug does not have child fields")) } -func (ec *executionContext) _PostgresInstance_majorVersion(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstance) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresDeletedActivityLogEntry_environmentName(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresDeletedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstance_majorVersion(ctx, field) + return ec.fieldContext_PostgresDeletedActivityLogEntry_environmentName(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.MajorVersion, nil + return obj.EnvironmentName, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { - return ec.marshalNString2string(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *string) graphql.Marshaler { + return ec.marshalOString2ᚖstring(ctx, selections, v) }, true, - true, + false, ) } -func (ec *executionContext) fieldContext_PostgresInstance_majorVersion(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresInstance", field, false, false, errors.New("field of type String does not have child fields")) +func (ec *executionContext) fieldContext_PostgresDeletedActivityLogEntry_environmentName(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresDeletedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresInstance_audit(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstance) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresGrantAccessActivityLogEntry_id(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresGrantAccessActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstance_audit(ctx, field) + return ec.fieldContext_PostgresGrantAccessActivityLogEntry_id(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Audit, nil + return obj.ID(), nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v postgres.PostgresInstanceAudit) graphql.Marshaler { - return ec.marshalNPostgresInstanceAudit2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceAudit(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v ident.Ident) graphql.Marshaler { + return ec.marshalNID2githubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋidentᚐIdent(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresInstance_audit(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "PostgresInstance", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_PostgresInstanceAudit(ctx, field) - }, - } - return fc, nil +func (ec *executionContext) fieldContext_PostgresGrantAccessActivityLogEntry_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresGrantAccessActivityLogEntry", field, true, false, errors.New("field of type ID does not have child fields")) } -func (ec *executionContext) _PostgresInstance_highAvailability(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstance) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresGrantAccessActivityLogEntry_actor(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresGrantAccessActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstance_highAvailability(ctx, field) + return ec.fieldContext_PostgresGrantAccessActivityLogEntry_actor(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.HighAvailability, nil + return obj.Actor, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v bool) graphql.Marshaler { - return ec.marshalNBoolean2bool(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { + return ec.marshalNString2string(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresInstance_highAvailability(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresInstance", field, false, false, errors.New("field of type Boolean does not have child fields")) +func (ec *executionContext) fieldContext_PostgresGrantAccessActivityLogEntry_actor(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresGrantAccessActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresInstance_state(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstance) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresGrantAccessActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresGrantAccessActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstance_state(ctx, field) + return ec.fieldContext_PostgresGrantAccessActivityLogEntry_createdAt(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.State, nil + return obj.CreatedAt, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v postgres.PostgresInstanceState) graphql.Marshaler { - return ec.marshalNPostgresInstanceState2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceState(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v time.Time) graphql.Marshaler { + return ec.marshalNTime2timeᚐTime(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresInstance_state(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresInstance", field, false, false, errors.New("field of type PostgresInstanceState does not have child fields")) +func (ec *executionContext) fieldContext_PostgresGrantAccessActivityLogEntry_createdAt(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresGrantAccessActivityLogEntry", field, false, false, errors.New("field of type Time does not have child fields")) } -func (ec *executionContext) _PostgresInstance_maintenanceWindow(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstance) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresGrantAccessActivityLogEntry_message(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresGrantAccessActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstance_maintenanceWindow(ctx, field) + return ec.fieldContext_PostgresGrantAccessActivityLogEntry_message(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.MaintenanceWindow, nil + return obj.Message, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v *postgres.PostgresInstanceMaintenanceWindow) graphql.Marshaler { - return ec.marshalOPostgresInstanceMaintenanceWindow2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceMaintenanceWindow(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { + return ec.marshalNString2string(ctx, selections, v) }, true, - false, + true, ) } -func (ec *executionContext) fieldContext_PostgresInstance_maintenanceWindow(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "PostgresInstance", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_PostgresInstanceMaintenanceWindow(ctx, field) - }, - } - return fc, nil +func (ec *executionContext) fieldContext_PostgresGrantAccessActivityLogEntry_message(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresGrantAccessActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresInstance_labels(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstance) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresGrantAccessActivityLogEntry_resourceType(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresGrantAccessActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstance_labels(ctx, field) + return ec.fieldContext_PostgresGrantAccessActivityLogEntry_resourceType(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Labels, nil + return obj.ResourceType, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v []*model.ResourceLabel) graphql.Marshaler { - return ec.marshalNResourceLabel2ᚕᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋmodelᚐResourceLabelᚄ(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v activitylog.ActivityLogEntryResourceType) graphql.Marshaler { + return ec.marshalNActivityLogEntryResourceType2githubᚗcomᚋnaisᚋapiᚋinternalᚋactivitylogᚐActivityLogEntryResourceType(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresInstance_labels(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "PostgresInstance", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_ResourceLabel(ctx, field) - }, - } - return fc, nil +func (ec *executionContext) fieldContext_PostgresGrantAccessActivityLogEntry_resourceType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresGrantAccessActivityLogEntry", field, false, false, errors.New("field of type ActivityLogEntryResourceType does not have child fields")) } -func (ec *executionContext) _PostgresInstanceAudit_enabled(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstanceAudit) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresGrantAccessActivityLogEntry_resourceName(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresGrantAccessActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstanceAudit_enabled(ctx, field) + return ec.fieldContext_PostgresGrantAccessActivityLogEntry_resourceName(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Enabled, nil + return obj.ResourceName, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v bool) graphql.Marshaler { - return ec.marshalNBoolean2bool(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { + return ec.marshalNString2string(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresInstanceAudit_enabled(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresInstanceAudit", field, false, false, errors.New("field of type Boolean does not have child fields")) +func (ec *executionContext) fieldContext_PostgresGrantAccessActivityLogEntry_resourceName(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresGrantAccessActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresInstanceAudit_url(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstanceAudit) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresGrantAccessActivityLogEntry_teamSlug(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresGrantAccessActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstanceAudit_url(ctx, field) + return ec.fieldContext_PostgresGrantAccessActivityLogEntry_teamSlug(ctx, field) }, func(ctx context.Context) (any, error) { - return ec.Resolvers.PostgresInstanceAudit().URL(ctx, obj) + return obj.TeamSlug, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v *string) graphql.Marshaler { - return ec.marshalOString2ᚖstring(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *slug.Slug) graphql.Marshaler { + return ec.marshalNSlug2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋslugᚐSlug(ctx, selections, v) }, true, - false, + true, ) } -func (ec *executionContext) fieldContext_PostgresInstanceAudit_url(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresInstanceAudit", field, true, true, errors.New("field of type String does not have child fields")) +func (ec *executionContext) fieldContext_PostgresGrantAccessActivityLogEntry_teamSlug(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresGrantAccessActivityLogEntry", field, false, false, errors.New("field of type Slug does not have child fields")) } -func (ec *executionContext) _PostgresInstanceAudit_statementClasses(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstanceAudit) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresGrantAccessActivityLogEntry_environmentName(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresGrantAccessActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstanceAudit_statementClasses(ctx, field) + return ec.fieldContext_PostgresGrantAccessActivityLogEntry_environmentName(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.StatementClasses, nil + return obj.EnvironmentName, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v []string) graphql.Marshaler { - return ec.marshalOString2ᚕstringᚄ(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *string) graphql.Marshaler { + return ec.marshalOString2ᚖstring(ctx, selections, v) }, true, false, ) } -func (ec *executionContext) fieldContext_PostgresInstanceAudit_statementClasses(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresInstanceAudit", field, false, false, errors.New("field of type String does not have child fields")) +func (ec *executionContext) fieldContext_PostgresGrantAccessActivityLogEntry_environmentName(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresGrantAccessActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresInstanceConnection_pageInfo(ctx context.Context, field graphql.CollectedField, obj *pagination.FacetableConnection[*postgres.PostgresInstance, *postgres.PostgresInstanceFilter]) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresGrantAccessActivityLogEntry_data(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresGrantAccessActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstanceConnection_pageInfo(ctx, field) + return ec.fieldContext_PostgresGrantAccessActivityLogEntry_data(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.PageInfo, nil + return obj.Data, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v pagination.PageInfo) graphql.Marshaler { - return ec.marshalNPageInfo2githubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋpaginationᚐPageInfo(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *postgres.PostgresGrantAccessActivityLogEntryData) graphql.Marshaler { + return ec.marshalNPostgresGrantAccessActivityLogEntryData2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresGrantAccessActivityLogEntryData(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresInstanceConnection_pageInfo(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_PostgresGrantAccessActivityLogEntry_data(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "PostgresInstanceConnection", + Object: "PostgresGrantAccessActivityLogEntry", Field: field, IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_PageInfo(ctx, field) + return ec.childFields_PostgresGrantAccessActivityLogEntryData(ctx, field) }, } return fc, nil } -func (ec *executionContext) _PostgresInstanceConnection_nodes(ctx context.Context, field graphql.CollectedField, obj *pagination.FacetableConnection[*postgres.PostgresInstance, *postgres.PostgresInstanceFilter]) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresGrantAccessActivityLogEntryData_grantee(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresGrantAccessActivityLogEntryData) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstanceConnection_nodes(ctx, field) + return ec.fieldContext_PostgresGrantAccessActivityLogEntryData_grantee(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Nodes(), nil + return obj.Grantee, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v []*postgres.PostgresInstance) graphql.Marshaler { - return ec.marshalNPostgresInstance2ᚕᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceᚄ(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { + return ec.marshalNString2string(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresInstanceConnection_nodes(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "PostgresInstanceConnection", - Field: field, - IsMethod: true, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_PostgresInstance(ctx, field) - }, - } - return fc, nil +func (ec *executionContext) fieldContext_PostgresGrantAccessActivityLogEntryData_grantee(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresGrantAccessActivityLogEntryData", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresInstanceConnection_edges(ctx context.Context, field graphql.CollectedField, obj *pagination.FacetableConnection[*postgres.PostgresInstance, *postgres.PostgresInstanceFilter]) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresGrantAccessActivityLogEntryData_until(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresGrantAccessActivityLogEntryData) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstanceConnection_edges(ctx, field) + return ec.fieldContext_PostgresGrantAccessActivityLogEntryData_until(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Edges, nil + return obj.Until, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v []pagination.Edge[*postgres.PostgresInstance]) graphql.Marshaler { - return ec.marshalNPostgresInstanceEdge2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋpaginationᚐEdgeᚄ(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v time.Time) graphql.Marshaler { + return ec.marshalNTime2timeᚐTime(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresInstanceConnection_edges(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "PostgresInstanceConnection", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_PostgresInstanceEdge(ctx, field) - }, - } - return fc, nil +func (ec *executionContext) fieldContext_PostgresGrantAccessActivityLogEntryData_until(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresGrantAccessActivityLogEntryData", field, false, false, errors.New("field of type Time does not have child fields")) } -func (ec *executionContext) _PostgresInstanceConnection_facets(ctx context.Context, field graphql.CollectedField, obj *pagination.FacetableConnection[*postgres.PostgresInstance, *postgres.PostgresInstanceFilter]) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresInstance_id(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstance) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstanceConnection_facets(ctx, field) + return ec.fieldContext_PostgresInstance_id(ctx, field) }, func(ctx context.Context) (any, error) { - return ec.Resolvers.PostgresInstanceConnection().Facets(ctx, obj) + return obj.ID(), nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v *postgres.PostgresInstanceFacets) graphql.Marshaler { - return ec.marshalOPostgresInstanceFacets2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceFacets(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v ident.Ident) graphql.Marshaler { + return ec.marshalNID2githubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋidentᚐIdent(ctx, selections, v) }, true, - false, + true, ) } -func (ec *executionContext) fieldContext_PostgresInstanceConnection_facets(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "PostgresInstanceConnection", - Field: field, - IsMethod: true, - IsResolver: true, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_PostgresInstanceFacets(ctx, field) - }, - } - return fc, nil +func (ec *executionContext) fieldContext_PostgresInstance_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresInstance", field, true, false, errors.New("field of type ID does not have child fields")) } -func (ec *executionContext) _PostgresInstanceEdge_cursor(ctx context.Context, field graphql.CollectedField, obj *pagination.Edge[*postgres.PostgresInstance]) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresInstance_name(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstance) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstanceEdge_cursor(ctx, field) + return ec.fieldContext_PostgresInstance_name(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Cursor, nil + return obj.Name, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v pagination.Cursor) graphql.Marshaler { - return ec.marshalNCursor2githubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋpaginationᚐCursor(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { + return ec.marshalNString2string(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresInstanceEdge_cursor(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresInstanceEdge", field, false, false, errors.New("field of type Cursor does not have child fields")) +func (ec *executionContext) fieldContext_PostgresInstance_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresInstance", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresInstanceEdge_node(ctx context.Context, field graphql.CollectedField, obj *pagination.Edge[*postgres.PostgresInstance]) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresInstance_team(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstance) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstanceEdge_node(ctx, field) + return ec.fieldContext_PostgresInstance_team(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Node, nil + return ec.Resolvers.PostgresInstance().Team(ctx, obj) }, nil, - func(ctx context.Context, selections ast.SelectionSet, v *postgres.PostgresInstance) graphql.Marshaler { - return ec.marshalNPostgresInstance2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstance(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *team.Team) graphql.Marshaler { + return ec.marshalNTeam2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋteamᚐTeam(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresInstanceEdge_node(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_PostgresInstance_team(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "PostgresInstanceEdge", + Object: "PostgresInstance", Field: field, - IsMethod: false, - IsResolver: false, + IsMethod: true, + IsResolver: true, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_PostgresInstance(ctx, field) + return ec.childFields_Team(ctx, field) }, } return fc, nil } -func (ec *executionContext) _PostgresInstanceFacets_environments(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstanceFacets) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresInstance_teamEnvironment(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstance) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstanceFacets_environments(ctx, field) + return ec.fieldContext_PostgresInstance_teamEnvironment(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Environments(ctx), nil + return ec.Resolvers.PostgresInstance().TeamEnvironment(ctx, obj) }, nil, - func(ctx context.Context, selections ast.SelectionSet, v []model.StringFacetItem) graphql.Marshaler { - return ec.marshalNStringFacetItem2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋmodelᚐStringFacetItemᚄ(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *team.TeamEnvironment) graphql.Marshaler { + return ec.marshalNTeamEnvironment2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋteamᚐTeamEnvironment(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresInstanceFacets_environments(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_PostgresInstance_teamEnvironment(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "PostgresInstanceFacets", + Object: "PostgresInstance", Field: field, IsMethod: true, - IsResolver: false, + IsResolver: true, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_StringFacetItem(ctx, field) + return ec.childFields_TeamEnvironment(ctx, field) }, } return fc, nil } -func (ec *executionContext) _PostgresInstanceFacets_states(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstanceFacets) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresInstance_workloads(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstance) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstanceFacets_states(ctx, field) + return ec.fieldContext_PostgresInstance_workloads(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.States(ctx), nil + fc := graphql.GetFieldContext(ctx) + return ec.Resolvers.PostgresInstance().Workloads(ctx, obj, fc.Args["first"].(*int), fc.Args["after"].(*pagination.Cursor), fc.Args["last"].(*int), fc.Args["before"].(*pagination.Cursor)) }, nil, - func(ctx context.Context, selections ast.SelectionSet, v []postgres.PostgresInstanceStateFacetItem) graphql.Marshaler { - return ec.marshalNPostgresInstanceStateFacetItem2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceStateFacetItemᚄ(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *pagination.Connection[workload.Workload]) graphql.Marshaler { + return ec.marshalNWorkloadConnection2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋpaginationᚐConnection(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresInstanceFacets_states(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_PostgresInstance_workloads(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "PostgresInstanceFacets", + Object: "PostgresInstance", Field: field, IsMethod: true, - IsResolver: false, + IsResolver: true, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_PostgresInstanceStateFacetItem(ctx, field) + return ec.childFields_WorkloadConnection(ctx, field) }, } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_PostgresInstance_workloads_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } return fc, nil } -func (ec *executionContext) _PostgresInstanceFacets_highAvailability(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstanceFacets) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresInstance_resources(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstance) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstanceFacets_highAvailability(ctx, field) + return ec.fieldContext_PostgresInstance_resources(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.HighAvailability(ctx), nil + return obj.Resources, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v []model.BooleanFacetItem) graphql.Marshaler { - return ec.marshalNBooleanFacetItem2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋmodelᚐBooleanFacetItemᚄ(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *postgres.PostgresInstanceResources) graphql.Marshaler { + return ec.marshalNPostgresInstanceResources2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceResources(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresInstanceFacets_highAvailability(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_PostgresInstance_resources(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "PostgresInstanceFacets", + Object: "PostgresInstance", Field: field, - IsMethod: true, + IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_BooleanFacetItem(ctx, field) + return ec.childFields_PostgresInstanceResources(ctx, field) }, } return fc, nil } -func (ec *executionContext) _PostgresInstanceFacets_majorVersions(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstanceFacets) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresInstance_majorVersion(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstance) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstanceFacets_majorVersions(ctx, field) + return ec.fieldContext_PostgresInstance_majorVersion(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.MajorVersions(ctx), nil + return obj.MajorVersion, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v []model.StringFacetItem) graphql.Marshaler { - return ec.marshalNStringFacetItem2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋmodelᚐStringFacetItemᚄ(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { + return ec.marshalNString2string(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresInstanceFacets_majorVersions(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "PostgresInstanceFacets", - Field: field, - IsMethod: true, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_StringFacetItem(ctx, field) - }, - } - return fc, nil +func (ec *executionContext) fieldContext_PostgresInstance_majorVersion(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresInstance", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresInstanceFacets_labels(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstanceFacets) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresInstance_audit(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstance) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstanceFacets_labels(ctx, field) + return ec.fieldContext_PostgresInstance_audit(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Labels(ctx), nil + return obj.Audit, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v []model.LabelFacetItem) graphql.Marshaler { - return ec.marshalNLabelFacetItem2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋmodelᚐLabelFacetItemᚄ(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v postgres.PostgresInstanceAudit) graphql.Marshaler { + return ec.marshalNPostgresInstanceAudit2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceAudit(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresInstanceFacets_labels(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_PostgresInstance_audit(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "PostgresInstanceFacets", + Object: "PostgresInstance", Field: field, - IsMethod: true, + IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_LabelFacetItem(ctx, field) + return ec.childFields_PostgresInstanceAudit(ctx, field) }, } return fc, nil } -func (ec *executionContext) _PostgresInstanceMaintenanceWindow_day(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstanceMaintenanceWindow) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresInstance_highAvailability(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstance) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstanceMaintenanceWindow_day(ctx, field) + return ec.fieldContext_PostgresInstance_highAvailability(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Day, nil + return obj.HighAvailability, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v int) graphql.Marshaler { - return ec.marshalNInt2int(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v bool) graphql.Marshaler { + return ec.marshalNBoolean2bool(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresInstanceMaintenanceWindow_day(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresInstanceMaintenanceWindow", field, false, false, errors.New("field of type Int does not have child fields")) +func (ec *executionContext) fieldContext_PostgresInstance_highAvailability(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresInstance", field, false, false, errors.New("field of type Boolean does not have child fields")) } -func (ec *executionContext) _PostgresInstanceMaintenanceWindow_hour(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstanceMaintenanceWindow) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresInstance_state(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstance) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstanceMaintenanceWindow_hour(ctx, field) + return ec.fieldContext_PostgresInstance_state(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Hour, nil + return obj.State, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v int) graphql.Marshaler { - return ec.marshalNInt2int(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v postgres.PostgresInstanceState) graphql.Marshaler { + return ec.marshalNPostgresInstanceState2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceState(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresInstanceMaintenanceWindow_hour(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresInstanceMaintenanceWindow", field, false, false, errors.New("field of type Int does not have child fields")) +func (ec *executionContext) fieldContext_PostgresInstance_state(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresInstance", field, false, false, errors.New("field of type PostgresInstanceState does not have child fields")) } -func (ec *executionContext) _PostgresInstanceResources_cpu(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstanceResources) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresInstance_maintenanceWindow(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstance) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstanceResources_cpu(ctx, field) + return ec.fieldContext_PostgresInstance_maintenanceWindow(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.CPU, nil + return obj.MaintenanceWindow, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { - return ec.marshalNString2string(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *postgres.PostgresInstanceMaintenanceWindow) graphql.Marshaler { + return ec.marshalOPostgresInstanceMaintenanceWindow2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceMaintenanceWindow(ctx, selections, v) }, true, - true, + false, ) } -func (ec *executionContext) fieldContext_PostgresInstanceResources_cpu(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresInstanceResources", field, false, false, errors.New("field of type String does not have child fields")) +func (ec *executionContext) fieldContext_PostgresInstance_maintenanceWindow(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "PostgresInstance", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_PostgresInstanceMaintenanceWindow(ctx, field) + }, + } + return fc, nil } -func (ec *executionContext) _PostgresInstanceResources_memory(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstanceResources) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresInstance_labels(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstance) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstanceResources_memory(ctx, field) + return ec.fieldContext_PostgresInstance_labels(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Memory, nil + return obj.Labels, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { - return ec.marshalNString2string(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v []*model.ResourceLabel) graphql.Marshaler { + return ec.marshalNResourceLabel2ᚕᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋmodelᚐResourceLabelᚄ(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresInstanceResources_memory(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresInstanceResources", field, false, false, errors.New("field of type String does not have child fields")) +func (ec *executionContext) fieldContext_PostgresInstance_labels(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "PostgresInstance", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_ResourceLabel(ctx, field) + }, + } + return fc, nil } -func (ec *executionContext) _PostgresInstanceResources_diskSize(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstanceResources) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresInstanceAudit_enabled(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstanceAudit) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstanceResources_diskSize(ctx, field) + return ec.fieldContext_PostgresInstanceAudit_enabled(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.DiskSize, nil + return obj.Enabled, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { - return ec.marshalNString2string(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v bool) graphql.Marshaler { + return ec.marshalNBoolean2bool(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresInstanceResources_diskSize(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresInstanceResources", field, false, false, errors.New("field of type String does not have child fields")) +func (ec *executionContext) fieldContext_PostgresInstanceAudit_enabled(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresInstanceAudit", field, false, false, errors.New("field of type Boolean does not have child fields")) } -func (ec *executionContext) _PostgresInstanceStateFacetItem_state(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstanceStateFacetItem) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresInstanceAudit_url(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstanceAudit) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstanceStateFacetItem_state(ctx, field) + return ec.fieldContext_PostgresInstanceAudit_url(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.State, nil + return ec.Resolvers.PostgresInstanceAudit().URL(ctx, obj) }, nil, - func(ctx context.Context, selections ast.SelectionSet, v postgres.PostgresInstanceState) graphql.Marshaler { - return ec.marshalNPostgresInstanceState2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceState(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *string) graphql.Marshaler { + return ec.marshalOString2ᚖstring(ctx, selections, v) }, true, + false, + ) +} +func (ec *executionContext) fieldContext_PostgresInstanceAudit_url(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresInstanceAudit", field, true, true, errors.New("field of type String does not have child fields")) +} + +func (ec *executionContext) _PostgresInstanceAudit_statementClasses(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstanceAudit) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_PostgresInstanceAudit_statementClasses(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.StatementClasses, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v []string) graphql.Marshaler { + return ec.marshalOString2ᚕstringᚄ(ctx, selections, v) + }, true, + false, ) } -func (ec *executionContext) fieldContext_PostgresInstanceStateFacetItem_state(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresInstanceStateFacetItem", field, false, false, errors.New("field of type PostgresInstanceState does not have child fields")) +func (ec *executionContext) fieldContext_PostgresInstanceAudit_statementClasses(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresInstanceAudit", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresInstanceStateFacetItem_count(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstanceStateFacetItem) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresInstanceConnection_pageInfo(ctx context.Context, field graphql.CollectedField, obj *pagination.FacetableConnection[*postgres.PostgresInstance, *postgres.PostgresInstanceFilter]) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstanceStateFacetItem_count(ctx, field) + return ec.fieldContext_PostgresInstanceConnection_pageInfo(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Count, nil + return obj.PageInfo, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v int) graphql.Marshaler { - return ec.marshalNInt2int(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v pagination.PageInfo) graphql.Marshaler { + return ec.marshalNPageInfo2githubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋpaginationᚐPageInfo(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresInstanceStateFacetItem_count(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresInstanceStateFacetItem", field, false, false, errors.New("field of type Int does not have child fields")) +func (ec *executionContext) fieldContext_PostgresInstanceConnection_pageInfo(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "PostgresInstanceConnection", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_PageInfo(ctx, field) + }, + } + return fc, nil } -func (ec *executionContext) _TeamInventoryCountPostgresInstances_total(ctx context.Context, field graphql.CollectedField, obj *postgres.TeamInventoryCountPostgresInstances) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresInstanceConnection_nodes(ctx context.Context, field graphql.CollectedField, obj *pagination.FacetableConnection[*postgres.PostgresInstance, *postgres.PostgresInstanceFilter]) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_TeamInventoryCountPostgresInstances_total(ctx, field) + return ec.fieldContext_PostgresInstanceConnection_nodes(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Total, nil + return obj.Nodes(), nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v int) graphql.Marshaler { - return ec.marshalNInt2int(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v []*postgres.PostgresInstance) graphql.Marshaler { + return ec.marshalNPostgresInstance2ᚕᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceᚄ(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_TeamInventoryCountPostgresInstances_total(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("TeamInventoryCountPostgresInstances", field, false, false, errors.New("field of type Int does not have child fields")) +func (ec *executionContext) fieldContext_PostgresInstanceConnection_nodes(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "PostgresInstanceConnection", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_PostgresInstance(ctx, field) + }, + } + return fc, nil } -// endregion **************************** field.gotpl ***************************** - -// region **************************** input.gotpl ***************************** - -func (ec *executionContext) unmarshalInputDeletePostgresInput(ctx context.Context, obj any) (postgres.DeletePostgresInput, error) { - var it postgres.DeletePostgresInput - if obj == nil { - return it, nil +func (ec *executionContext) _PostgresInstanceConnection_edges(ctx context.Context, field graphql.CollectedField, obj *pagination.FacetableConnection[*postgres.PostgresInstance, *postgres.PostgresInstanceFilter]) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_PostgresInstanceConnection_edges(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Edges, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v []pagination.Edge[*postgres.PostgresInstance]) graphql.Marshaler { + return ec.marshalNPostgresInstanceEdge2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋpaginationᚐEdgeᚄ(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_PostgresInstanceConnection_edges(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "PostgresInstanceConnection", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_PostgresInstanceEdge(ctx, field) + }, } + return fc, nil +} - asMap := map[string]any{} - for k, v := range obj.(map[string]any) { - asMap[k] = v +func (ec *executionContext) _PostgresInstanceConnection_facets(ctx context.Context, field graphql.CollectedField, obj *pagination.FacetableConnection[*postgres.PostgresInstance, *postgres.PostgresInstanceFilter]) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_PostgresInstanceConnection_facets(ctx, field) + }, + func(ctx context.Context) (any, error) { + return ec.Resolvers.PostgresInstanceConnection().Facets(ctx, obj) + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *postgres.PostgresInstanceFacets) graphql.Marshaler { + return ec.marshalOPostgresInstanceFacets2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceFacets(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_PostgresInstanceConnection_facets(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "PostgresInstanceConnection", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_PostgresInstanceFacets(ctx, field) + }, + } + return fc, nil +} + +func (ec *executionContext) _PostgresInstanceEdge_cursor(ctx context.Context, field graphql.CollectedField, obj *pagination.Edge[*postgres.PostgresInstance]) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_PostgresInstanceEdge_cursor(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Cursor, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v pagination.Cursor) graphql.Marshaler { + return ec.marshalNCursor2githubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋpaginationᚐCursor(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_PostgresInstanceEdge_cursor(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresInstanceEdge", field, false, false, errors.New("field of type Cursor does not have child fields")) +} + +func (ec *executionContext) _PostgresInstanceEdge_node(ctx context.Context, field graphql.CollectedField, obj *pagination.Edge[*postgres.PostgresInstance]) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_PostgresInstanceEdge_node(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Node, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *postgres.PostgresInstance) graphql.Marshaler { + return ec.marshalNPostgresInstance2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstance(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_PostgresInstanceEdge_node(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "PostgresInstanceEdge", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_PostgresInstance(ctx, field) + }, + } + return fc, nil +} + +func (ec *executionContext) _PostgresInstanceFacets_environments(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstanceFacets) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_PostgresInstanceFacets_environments(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Environments(ctx), nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v []model.StringFacetItem) graphql.Marshaler { + return ec.marshalNStringFacetItem2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋmodelᚐStringFacetItemᚄ(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_PostgresInstanceFacets_environments(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "PostgresInstanceFacets", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_StringFacetItem(ctx, field) + }, + } + return fc, nil +} + +func (ec *executionContext) _PostgresInstanceFacets_states(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstanceFacets) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_PostgresInstanceFacets_states(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.States(ctx), nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v []postgres.PostgresInstanceStateFacetItem) graphql.Marshaler { + return ec.marshalNPostgresInstanceStateFacetItem2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceStateFacetItemᚄ(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_PostgresInstanceFacets_states(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "PostgresInstanceFacets", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_PostgresInstanceStateFacetItem(ctx, field) + }, + } + return fc, nil +} + +func (ec *executionContext) _PostgresInstanceFacets_highAvailability(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstanceFacets) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_PostgresInstanceFacets_highAvailability(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.HighAvailability(ctx), nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v []model.BooleanFacetItem) graphql.Marshaler { + return ec.marshalNBooleanFacetItem2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋmodelᚐBooleanFacetItemᚄ(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_PostgresInstanceFacets_highAvailability(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "PostgresInstanceFacets", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_BooleanFacetItem(ctx, field) + }, + } + return fc, nil +} + +func (ec *executionContext) _PostgresInstanceFacets_majorVersions(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstanceFacets) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_PostgresInstanceFacets_majorVersions(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.MajorVersions(ctx), nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v []model.StringFacetItem) graphql.Marshaler { + return ec.marshalNStringFacetItem2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋmodelᚐStringFacetItemᚄ(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_PostgresInstanceFacets_majorVersions(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "PostgresInstanceFacets", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_StringFacetItem(ctx, field) + }, + } + return fc, nil +} + +func (ec *executionContext) _PostgresInstanceFacets_labels(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstanceFacets) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_PostgresInstanceFacets_labels(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Labels(ctx), nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v []model.LabelFacetItem) graphql.Marshaler { + return ec.marshalNLabelFacetItem2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋmodelᚐLabelFacetItemᚄ(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_PostgresInstanceFacets_labels(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "PostgresInstanceFacets", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_LabelFacetItem(ctx, field) + }, + } + return fc, nil +} + +func (ec *executionContext) _PostgresInstanceMaintenanceWindow_day(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstanceMaintenanceWindow) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_PostgresInstanceMaintenanceWindow_day(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Day, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v int) graphql.Marshaler { + return ec.marshalNInt2int(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_PostgresInstanceMaintenanceWindow_day(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresInstanceMaintenanceWindow", field, false, false, errors.New("field of type Int does not have child fields")) +} + +func (ec *executionContext) _PostgresInstanceMaintenanceWindow_hour(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstanceMaintenanceWindow) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_PostgresInstanceMaintenanceWindow_hour(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Hour, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v int) graphql.Marshaler { + return ec.marshalNInt2int(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_PostgresInstanceMaintenanceWindow_hour(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresInstanceMaintenanceWindow", field, false, false, errors.New("field of type Int does not have child fields")) +} + +func (ec *executionContext) _PostgresInstanceResources_cpu(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstanceResources) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_PostgresInstanceResources_cpu(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.CPU, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { + return ec.marshalNString2string(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_PostgresInstanceResources_cpu(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresInstanceResources", field, false, false, errors.New("field of type String does not have child fields")) +} + +func (ec *executionContext) _PostgresInstanceResources_memory(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstanceResources) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_PostgresInstanceResources_memory(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Memory, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { + return ec.marshalNString2string(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_PostgresInstanceResources_memory(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresInstanceResources", field, false, false, errors.New("field of type String does not have child fields")) +} + +func (ec *executionContext) _PostgresInstanceResources_diskSize(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstanceResources) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_PostgresInstanceResources_diskSize(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.DiskSize, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { + return ec.marshalNString2string(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_PostgresInstanceResources_diskSize(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresInstanceResources", field, false, false, errors.New("field of type String does not have child fields")) +} + +func (ec *executionContext) _PostgresInstanceStateFacetItem_state(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstanceStateFacetItem) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_PostgresInstanceStateFacetItem_state(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.State, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v postgres.PostgresInstanceState) graphql.Marshaler { + return ec.marshalNPostgresInstanceState2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceState(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_PostgresInstanceStateFacetItem_state(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresInstanceStateFacetItem", field, false, false, errors.New("field of type PostgresInstanceState does not have child fields")) +} + +func (ec *executionContext) _PostgresInstanceStateFacetItem_count(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstanceStateFacetItem) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_PostgresInstanceStateFacetItem_count(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Count, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v int) graphql.Marshaler { + return ec.marshalNInt2int(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_PostgresInstanceStateFacetItem_count(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresInstanceStateFacetItem", field, false, false, errors.New("field of type Int does not have child fields")) +} + +func (ec *executionContext) _PostgresPersonalAccessConnectionActivityLogEntry_id(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresPersonalAccessConnectionActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_PostgresPersonalAccessConnectionActivityLogEntry_id(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.ID(), nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v ident.Ident) graphql.Marshaler { + return ec.marshalNID2githubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋidentᚐIdent(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_PostgresPersonalAccessConnectionActivityLogEntry_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresPersonalAccessConnectionActivityLogEntry", field, true, false, errors.New("field of type ID does not have child fields")) +} + +func (ec *executionContext) _PostgresPersonalAccessConnectionActivityLogEntry_actor(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresPersonalAccessConnectionActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_PostgresPersonalAccessConnectionActivityLogEntry_actor(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Actor, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { + return ec.marshalNString2string(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_PostgresPersonalAccessConnectionActivityLogEntry_actor(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresPersonalAccessConnectionActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) +} + +func (ec *executionContext) _PostgresPersonalAccessConnectionActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresPersonalAccessConnectionActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_PostgresPersonalAccessConnectionActivityLogEntry_createdAt(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.CreatedAt, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v time.Time) graphql.Marshaler { + return ec.marshalNTime2timeᚐTime(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_PostgresPersonalAccessConnectionActivityLogEntry_createdAt(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresPersonalAccessConnectionActivityLogEntry", field, false, false, errors.New("field of type Time does not have child fields")) +} + +func (ec *executionContext) _PostgresPersonalAccessConnectionActivityLogEntry_message(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresPersonalAccessConnectionActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_PostgresPersonalAccessConnectionActivityLogEntry_message(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Message, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { + return ec.marshalNString2string(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_PostgresPersonalAccessConnectionActivityLogEntry_message(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresPersonalAccessConnectionActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) +} + +func (ec *executionContext) _PostgresPersonalAccessConnectionActivityLogEntry_resourceType(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresPersonalAccessConnectionActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_PostgresPersonalAccessConnectionActivityLogEntry_resourceType(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.ResourceType, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v activitylog.ActivityLogEntryResourceType) graphql.Marshaler { + return ec.marshalNActivityLogEntryResourceType2githubᚗcomᚋnaisᚋapiᚋinternalᚋactivitylogᚐActivityLogEntryResourceType(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_PostgresPersonalAccessConnectionActivityLogEntry_resourceType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresPersonalAccessConnectionActivityLogEntry", field, false, false, errors.New("field of type ActivityLogEntryResourceType does not have child fields")) +} + +func (ec *executionContext) _PostgresPersonalAccessConnectionActivityLogEntry_resourceName(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresPersonalAccessConnectionActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_PostgresPersonalAccessConnectionActivityLogEntry_resourceName(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.ResourceName, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { + return ec.marshalNString2string(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_PostgresPersonalAccessConnectionActivityLogEntry_resourceName(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresPersonalAccessConnectionActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) +} + +func (ec *executionContext) _PostgresPersonalAccessConnectionActivityLogEntry_teamSlug(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresPersonalAccessConnectionActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_PostgresPersonalAccessConnectionActivityLogEntry_teamSlug(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.TeamSlug, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *slug.Slug) graphql.Marshaler { + return ec.marshalNSlug2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋslugᚐSlug(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_PostgresPersonalAccessConnectionActivityLogEntry_teamSlug(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresPersonalAccessConnectionActivityLogEntry", field, false, false, errors.New("field of type Slug does not have child fields")) +} + +func (ec *executionContext) _PostgresPersonalAccessConnectionActivityLogEntry_environmentName(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresPersonalAccessConnectionActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_PostgresPersonalAccessConnectionActivityLogEntry_environmentName(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.EnvironmentName, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *string) graphql.Marshaler { + return ec.marshalOString2ᚖstring(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_PostgresPersonalAccessConnectionActivityLogEntry_environmentName(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresPersonalAccessConnectionActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) +} + +func (ec *executionContext) _PostgresPersonalAccessCreatedActivityLogEntry_id(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresPersonalAccessCreatedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_PostgresPersonalAccessCreatedActivityLogEntry_id(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.ID(), nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v ident.Ident) graphql.Marshaler { + return ec.marshalNID2githubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋidentᚐIdent(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_PostgresPersonalAccessCreatedActivityLogEntry_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresPersonalAccessCreatedActivityLogEntry", field, true, false, errors.New("field of type ID does not have child fields")) +} + +func (ec *executionContext) _PostgresPersonalAccessCreatedActivityLogEntry_actor(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresPersonalAccessCreatedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_PostgresPersonalAccessCreatedActivityLogEntry_actor(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Actor, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { + return ec.marshalNString2string(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_PostgresPersonalAccessCreatedActivityLogEntry_actor(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresPersonalAccessCreatedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) +} + +func (ec *executionContext) _PostgresPersonalAccessCreatedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresPersonalAccessCreatedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_PostgresPersonalAccessCreatedActivityLogEntry_createdAt(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.CreatedAt, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v time.Time) graphql.Marshaler { + return ec.marshalNTime2timeᚐTime(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_PostgresPersonalAccessCreatedActivityLogEntry_createdAt(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresPersonalAccessCreatedActivityLogEntry", field, false, false, errors.New("field of type Time does not have child fields")) +} + +func (ec *executionContext) _PostgresPersonalAccessCreatedActivityLogEntry_message(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresPersonalAccessCreatedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_PostgresPersonalAccessCreatedActivityLogEntry_message(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Message, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { + return ec.marshalNString2string(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_PostgresPersonalAccessCreatedActivityLogEntry_message(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresPersonalAccessCreatedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) +} + +func (ec *executionContext) _PostgresPersonalAccessCreatedActivityLogEntry_resourceType(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresPersonalAccessCreatedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_PostgresPersonalAccessCreatedActivityLogEntry_resourceType(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.ResourceType, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v activitylog.ActivityLogEntryResourceType) graphql.Marshaler { + return ec.marshalNActivityLogEntryResourceType2githubᚗcomᚋnaisᚋapiᚋinternalᚋactivitylogᚐActivityLogEntryResourceType(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_PostgresPersonalAccessCreatedActivityLogEntry_resourceType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresPersonalAccessCreatedActivityLogEntry", field, false, false, errors.New("field of type ActivityLogEntryResourceType does not have child fields")) +} + +func (ec *executionContext) _PostgresPersonalAccessCreatedActivityLogEntry_resourceName(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresPersonalAccessCreatedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_PostgresPersonalAccessCreatedActivityLogEntry_resourceName(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.ResourceName, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { + return ec.marshalNString2string(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_PostgresPersonalAccessCreatedActivityLogEntry_resourceName(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresPersonalAccessCreatedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) +} + +func (ec *executionContext) _PostgresPersonalAccessCreatedActivityLogEntry_teamSlug(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresPersonalAccessCreatedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_PostgresPersonalAccessCreatedActivityLogEntry_teamSlug(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.TeamSlug, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *slug.Slug) graphql.Marshaler { + return ec.marshalNSlug2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋslugᚐSlug(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_PostgresPersonalAccessCreatedActivityLogEntry_teamSlug(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresPersonalAccessCreatedActivityLogEntry", field, false, false, errors.New("field of type Slug does not have child fields")) +} + +func (ec *executionContext) _PostgresPersonalAccessCreatedActivityLogEntry_environmentName(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresPersonalAccessCreatedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_PostgresPersonalAccessCreatedActivityLogEntry_environmentName(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.EnvironmentName, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *string) graphql.Marshaler { + return ec.marshalOString2ᚖstring(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_PostgresPersonalAccessCreatedActivityLogEntry_environmentName(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresPersonalAccessCreatedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) +} + +func (ec *executionContext) _PostgresPersonalAccessCreatedActivityLogEntry_data(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresPersonalAccessCreatedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_PostgresPersonalAccessCreatedActivityLogEntry_data(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Data, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *postgres.PostgresPersonalAccessCreatedActivityLogEntryData) graphql.Marshaler { + return ec.marshalNPostgresPersonalAccessCreatedActivityLogEntryData2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresPersonalAccessCreatedActivityLogEntryData(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_PostgresPersonalAccessCreatedActivityLogEntry_data(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "PostgresPersonalAccessCreatedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_PostgresPersonalAccessCreatedActivityLogEntryData(ctx, field) + }, + } + return fc, nil +} + +func (ec *executionContext) _PostgresPersonalAccessCreatedActivityLogEntryData_username(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresPersonalAccessCreatedActivityLogEntryData) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_PostgresPersonalAccessCreatedActivityLogEntryData_username(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Username, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { + return ec.marshalNString2string(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_PostgresPersonalAccessCreatedActivityLogEntryData_username(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresPersonalAccessCreatedActivityLogEntryData", field, false, false, errors.New("field of type String does not have child fields")) +} + +func (ec *executionContext) _PostgresPersonalAccessCreatedActivityLogEntryData_expiresAt(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresPersonalAccessCreatedActivityLogEntryData) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_PostgresPersonalAccessCreatedActivityLogEntryData_expiresAt(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.ExpiresAt, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v time.Time) graphql.Marshaler { + return ec.marshalNTime2timeᚐTime(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_PostgresPersonalAccessCreatedActivityLogEntryData_expiresAt(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresPersonalAccessCreatedActivityLogEntryData", field, false, false, errors.New("field of type Time does not have child fields")) +} + +func (ec *executionContext) _TeamInventoryCountPostgresInstances_total(ctx context.Context, field graphql.CollectedField, obj *postgres.TeamInventoryCountPostgresInstances) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_TeamInventoryCountPostgresInstances_total(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Total, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v int) graphql.Marshaler { + return ec.marshalNInt2int(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_TeamInventoryCountPostgresInstances_total(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("TeamInventoryCountPostgresInstances", field, false, false, errors.New("field of type Int does not have child fields")) +} + +// endregion **************************** field.gotpl ***************************** + +// region **************************** input.gotpl ***************************** + +func (ec *executionContext) unmarshalInputCreatePostgresAccessInput(ctx context.Context, obj any) (postgres.CreatePostgresAccessInput, error) { + var it postgres.CreatePostgresAccessInput + if obj == nil { + return it, nil + } + + asMap := map[string]any{} + for k, v := range obj.(map[string]any) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"postgresInstance", "teamSlug", "environmentName", "accessLevel", "clientWireGuardPublicKey"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "postgresInstance": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("postgresInstance")) + data, err := ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + it.PostgresInstance = data + case "teamSlug": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("teamSlug")) + data, err := ec.unmarshalNSlug2githubᚗcomᚋnaisᚋapiᚋinternalᚋslugᚐSlug(ctx, v) + if err != nil { + return it, err + } + it.TeamSlug = data + case "environmentName": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("environmentName")) + data, err := ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + it.EnvironmentName = data + case "accessLevel": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("accessLevel")) + data, err := ec.unmarshalNPostgresAccessLevel2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccessLevel(ctx, v) + if err != nil { + return it, err + } + it.AccessLevel = data + case "clientWireGuardPublicKey": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("clientWireGuardPublicKey")) + data, err := ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + it.ClientWireGuardPublicKey = data + } + } + return it, nil +} + +func (ec *executionContext) unmarshalInputDeletePostgresInput(ctx context.Context, obj any) (postgres.DeletePostgresInput, error) { + var it postgres.DeletePostgresInput + if obj == nil { + return it, nil + } + + asMap := map[string]any{} + for k, v := range obj.(map[string]any) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"name", "environmentName", "teamSlug"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "name": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("name")) + data, err := ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + it.Name = data + case "environmentName": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("environmentName")) + data, err := ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + it.EnvironmentName = data + case "teamSlug": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("teamSlug")) + data, err := ec.unmarshalNSlug2githubᚗcomᚋnaisᚋapiᚋinternalᚋslugᚐSlug(ctx, v) + if err != nil { + return it, err + } + it.TeamSlug = data + } + } + return it, nil +} + +func (ec *executionContext) unmarshalInputGrantPostgresAccessInput(ctx context.Context, obj any) (postgres.GrantPostgresAccessInput, error) { + var it postgres.GrantPostgresAccessInput + if obj == nil { + return it, nil + } + + asMap := map[string]any{} + for k, v := range obj.(map[string]any) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"clusterName", "teamSlug", "environmentName", "grantee", "duration"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "clusterName": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("clusterName")) + data, err := ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + it.ClusterName = data + case "teamSlug": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("teamSlug")) + data, err := ec.unmarshalNSlug2githubᚗcomᚋnaisᚋapiᚋinternalᚋslugᚐSlug(ctx, v) + if err != nil { + return it, err + } + it.TeamSlug = data + case "environmentName": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("environmentName")) + data, err := ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + it.EnvironmentName = data + case "grantee": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("grantee")) + data, err := ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + it.Grantee = data + case "duration": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("duration")) + data, err := ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + it.Duration = data + } + } + return it, nil +} + +func (ec *executionContext) unmarshalInputPostgresAccessConnectionInput(ctx context.Context, obj any) (postgres.PostgresAccessConnectionInput, error) { + var it postgres.PostgresAccessConnectionInput + if obj == nil { + return it, nil + } + + asMap := map[string]any{} + for k, v := range obj.(map[string]any) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"name", "teamSlug", "environmentName"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "name": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("name")) + data, err := ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + it.Name = data + case "teamSlug": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("teamSlug")) + data, err := ec.unmarshalNSlug2githubᚗcomᚋnaisᚋapiᚋinternalᚋslugᚐSlug(ctx, v) + if err != nil { + return it, err + } + it.TeamSlug = data + case "environmentName": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("environmentName")) + data, err := ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + it.EnvironmentName = data + } + } + return it, nil +} + +func (ec *executionContext) unmarshalInputPostgresInstanceFilter(ctx context.Context, obj any) (postgres.PostgresInstanceFilter, error) { + var it postgres.PostgresInstanceFilter + if obj == nil { + return it, nil } - fieldsInOrder := [...]string{"name", "environmentName", "teamSlug"} + asMap := map[string]any{} + for k, v := range obj.(map[string]any) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"name", "environments", "states", "highAvailability", "majorVersions", "labels"} for _, k := range fieldsInOrder { v, ok := asMap[k] if !ok { @@ -1549,211 +2732,458 @@ func (ec *executionContext) unmarshalInputDeletePostgresInput(ctx context.Contex switch k { case "name": ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("name")) - data, err := ec.unmarshalNString2string(ctx, v) + data, err := ec.unmarshalOString2string(ctx, v) if err != nil { return it, err } it.Name = data - case "environmentName": - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("environmentName")) - data, err := ec.unmarshalNString2string(ctx, v) + case "environments": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("environments")) + data, err := ec.unmarshalOString2ᚕstringᚄ(ctx, v) if err != nil { return it, err } - it.EnvironmentName = data - case "teamSlug": - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("teamSlug")) - data, err := ec.unmarshalNSlug2githubᚗcomᚋnaisᚋapiᚋinternalᚋslugᚐSlug(ctx, v) + it.Environments = data + case "states": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("states")) + data, err := ec.unmarshalOPostgresInstanceState2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceStateᚄ(ctx, v) + if err != nil { + return it, err + } + it.States = data + case "highAvailability": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("highAvailability")) + data, err := ec.unmarshalOBoolean2ᚖbool(ctx, v) + if err != nil { + return it, err + } + it.HighAvailability = data + case "majorVersions": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("majorVersions")) + data, err := ec.unmarshalOString2ᚕstringᚄ(ctx, v) + if err != nil { + return it, err + } + it.MajorVersions = data + case "labels": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("labels")) + data, err := ec.unmarshalOLabelFilter2githubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋmodelᚐLabelFiltersᚄ(ctx, v) + if err != nil { + return it, err + } + it.Labels = data + } + } + return it, nil +} + +func (ec *executionContext) unmarshalInputPostgresInstanceOrder(ctx context.Context, obj any) (postgres.PostgresInstanceOrder, error) { + var it postgres.PostgresInstanceOrder + if obj == nil { + return it, nil + } + + asMap := map[string]any{} + for k, v := range obj.(map[string]any) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"field", "direction"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "field": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("field")) + data, err := ec.unmarshalNPostgresInstanceOrderField2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceOrderField(ctx, v) + if err != nil { + return it, err + } + it.Field = data + case "direction": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("direction")) + data, err := ec.unmarshalNOrderDirection2githubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋmodelᚐOrderDirection(ctx, v) if err != nil { return it, err } - it.TeamSlug = data - } - } - return it, nil -} + it.Direction = data + } + } + return it, nil +} + +// endregion **************************** input.gotpl ***************************** + +// region ************************** interface.gotpl *************************** + +// endregion ************************** interface.gotpl *************************** + +// region **************************** object.gotpl **************************** + +var createPostgresAccessPayloadImplementors = []string{"CreatePostgresAccessPayload"} + +func (ec *executionContext) _CreatePostgresAccessPayload(ctx context.Context, sel ast.SelectionSet, obj *postgres.CreatePostgresAccessPayload) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, createPostgresAccessPayloadImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("CreatePostgresAccessPayload") + case "name": + out.Values[i] = ec._CreatePostgresAccessPayload_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "expiresAt": + out.Values[i] = ec._CreatePostgresAccessPayload_expiresAt(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.Deferred, int32(min(len(deferred), math.MaxInt32))) + + for label, dfs := range deferred { + ec.ProcessDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var deletePostgresPayloadImplementors = []string{"DeletePostgresPayload"} + +func (ec *executionContext) _DeletePostgresPayload(ctx context.Context, sel ast.SelectionSet, obj *postgres.DeletePostgresPayload) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, deletePostgresPayloadImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("DeletePostgresPayload") + case "postgresDeleted": + out.Values[i] = ec._DeletePostgresPayload_postgresDeleted(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.Deferred, int32(min(len(deferred), math.MaxInt32))) + + for label, dfs := range deferred { + ec.ProcessDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var grantPostgresAccessPayloadImplementors = []string{"GrantPostgresAccessPayload"} + +func (ec *executionContext) _GrantPostgresAccessPayload(ctx context.Context, sel ast.SelectionSet, obj *postgres.GrantPostgresAccessPayload) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, grantPostgresAccessPayloadImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("GrantPostgresAccessPayload") + case "error": + out.Values[i] = ec._GrantPostgresAccessPayload_error(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.Deferred, int32(min(len(deferred), math.MaxInt32))) + + for label, dfs := range deferred { + ec.ProcessDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var postgresAccessImplementors = []string{"PostgresAccess", "Node"} + +func (ec *executionContext) _PostgresAccess(ctx context.Context, sel ast.SelectionSet, obj *postgres.PostgresAccess) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, postgresAccessImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("PostgresAccess") + case "id": + out.Values[i] = ec._PostgresAccess_id(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "name": + out.Values[i] = ec._PostgresAccess_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "team": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._PostgresAccess_team(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + if field.Deferrable != nil { + dfs, ok := deferred[field.Deferrable.Label] + di := 0 + if ok { + dfs.AddField(field) + di = len(dfs.Values) - 1 + } else { + dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) + deferred[field.Deferrable.Label] = dfs + } + dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { + return innerFunc(ctx, dfs) + }) + + // don't run the out.Concurrently() call below + out.Values[i] = graphql.Null + continue + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + case "teamEnvironment": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._PostgresAccess_teamEnvironment(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } -func (ec *executionContext) unmarshalInputGrantPostgresAccessInput(ctx context.Context, obj any) (postgres.GrantPostgresAccessInput, error) { - var it postgres.GrantPostgresAccessInput - if obj == nil { - return it, nil - } + if field.Deferrable != nil { + dfs, ok := deferred[field.Deferrable.Label] + di := 0 + if ok { + dfs.AddField(field) + di = len(dfs.Values) - 1 + } else { + dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) + deferred[field.Deferrable.Label] = dfs + } + dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { + return innerFunc(ctx, dfs) + }) - asMap := map[string]any{} - for k, v := range obj.(map[string]any) { - asMap[k] = v - } + // don't run the out.Concurrently() call below + out.Values[i] = graphql.Null + continue + } - fieldsInOrder := [...]string{"clusterName", "teamSlug", "environmentName", "grantee", "duration"} - for _, k := range fieldsInOrder { - v, ok := asMap[k] - if !ok { - continue - } - switch k { - case "clusterName": - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("clusterName")) - data, err := ec.unmarshalNString2string(ctx, v) - if err != nil { - return it, err + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + case "postgresInstance": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._PostgresAccess_postgresInstance(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res } - it.ClusterName = data - case "teamSlug": - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("teamSlug")) - data, err := ec.unmarshalNSlug2githubᚗcomᚋnaisᚋapiᚋinternalᚋslugᚐSlug(ctx, v) - if err != nil { - return it, err + + if field.Deferrable != nil { + dfs, ok := deferred[field.Deferrable.Label] + di := 0 + if ok { + dfs.AddField(field) + di = len(dfs.Values) - 1 + } else { + dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) + deferred[field.Deferrable.Label] = dfs + } + dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { + return innerFunc(ctx, dfs) + }) + + // don't run the out.Concurrently() call below + out.Values[i] = graphql.Null + continue } - it.TeamSlug = data - case "environmentName": - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("environmentName")) - data, err := ec.unmarshalNString2string(ctx, v) - if err != nil { - return it, err + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + case "accessLevel": + out.Values[i] = ec._PostgresAccess_accessLevel(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) } - it.EnvironmentName = data - case "grantee": - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("grantee")) - data, err := ec.unmarshalNString2string(ctx, v) - if err != nil { - return it, err + case "expiresAt": + out.Values[i] = ec._PostgresAccess_expiresAt(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) } - it.Grantee = data - case "duration": - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("duration")) - data, err := ec.unmarshalNString2string(ctx, v) - if err != nil { - return it, err + case "state": + out.Values[i] = ec._PostgresAccess_state(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) } - it.Duration = data + case "message": + out.Values[i] = ec._PostgresAccess_message(ctx, field, obj) + case "tunnel": + out.Values[i] = ec._PostgresAccess_tunnel(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) } } - return it, nil -} - -func (ec *executionContext) unmarshalInputPostgresInstanceFilter(ctx context.Context, obj any) (postgres.PostgresInstanceFilter, error) { - var it postgres.PostgresInstanceFilter - if obj == nil { - return it, nil + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null } - asMap := map[string]any{} - for k, v := range obj.(map[string]any) { - asMap[k] = v + atomic.AddInt32(&ec.Deferred, int32(min(len(deferred), math.MaxInt32))) + + for label, dfs := range deferred { + ec.ProcessDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) } - fieldsInOrder := [...]string{"name", "environments", "states", "highAvailability", "majorVersions", "labels"} - for _, k := range fieldsInOrder { - v, ok := asMap[k] - if !ok { - continue - } - switch k { - case "name": - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("name")) - data, err := ec.unmarshalOString2string(ctx, v) - if err != nil { - return it, err - } - it.Name = data - case "environments": - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("environments")) - data, err := ec.unmarshalOString2ᚕstringᚄ(ctx, v) - if err != nil { - return it, err - } - it.Environments = data - case "states": - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("states")) - data, err := ec.unmarshalOPostgresInstanceState2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceStateᚄ(ctx, v) - if err != nil { - return it, err + return out +} + +var postgresAccessConnectionPayloadImplementors = []string{"PostgresAccessConnectionPayload"} + +func (ec *executionContext) _PostgresAccessConnectionPayload(ctx context.Context, sel ast.SelectionSet, obj *postgres.PostgresAccessConnectionPayload) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, postgresAccessConnectionPayloadImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("PostgresAccessConnectionPayload") + case "password": + out.Values[i] = ec._PostgresAccessConnectionPayload_password(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ } - it.States = data - case "highAvailability": - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("highAvailability")) - data, err := ec.unmarshalOBoolean2ᚖbool(ctx, v) - if err != nil { - return it, err + case "caCertificate": + out.Values[i] = ec._PostgresAccessConnectionPayload_caCertificate(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ } - it.HighAvailability = data - case "majorVersions": - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("majorVersions")) - data, err := ec.unmarshalOString2ᚕstringᚄ(ctx, v) - if err != nil { - return it, err + case "serverName": + out.Values[i] = ec._PostgresAccessConnectionPayload_serverName(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ } - it.MajorVersions = data - case "labels": - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("labels")) - data, err := ec.unmarshalOLabelFilter2githubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋmodelᚐLabelFiltersᚄ(ctx, v) - if err != nil { - return it, err + case "tunnel": + out.Values[i] = ec._PostgresAccessConnectionPayload_tunnel(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ } - it.Labels = data + default: + panic("unknown field " + strconv.Quote(field.Name)) } } - return it, nil -} - -func (ec *executionContext) unmarshalInputPostgresInstanceOrder(ctx context.Context, obj any) (postgres.PostgresInstanceOrder, error) { - var it postgres.PostgresInstanceOrder - if obj == nil { - return it, nil + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null } - asMap := map[string]any{} - for k, v := range obj.(map[string]any) { - asMap[k] = v - } + atomic.AddInt32(&ec.Deferred, int32(min(len(deferred), math.MaxInt32))) - fieldsInOrder := [...]string{"field", "direction"} - for _, k := range fieldsInOrder { - v, ok := asMap[k] - if !ok { - continue - } - switch k { - case "field": - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("field")) - data, err := ec.unmarshalNPostgresInstanceOrderField2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceOrderField(ctx, v) - if err != nil { - return it, err - } - it.Field = data - case "direction": - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("direction")) - data, err := ec.unmarshalNOrderDirection2githubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋmodelᚐOrderDirection(ctx, v) - if err != nil { - return it, err - } - it.Direction = data - } + for label, dfs := range deferred { + ec.ProcessDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) } - return it, nil -} - -// endregion **************************** input.gotpl ***************************** - -// region ************************** interface.gotpl *************************** - -// endregion ************************** interface.gotpl *************************** -// region **************************** object.gotpl **************************** + return out +} -var deletePostgresPayloadImplementors = []string{"DeletePostgresPayload"} +var postgresAccessConnectionTunnelImplementors = []string{"PostgresAccessConnectionTunnel"} -func (ec *executionContext) _DeletePostgresPayload(ctx context.Context, sel ast.SelectionSet, obj *postgres.DeletePostgresPayload) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, deletePostgresPayloadImplementors) +func (ec *executionContext) _PostgresAccessConnectionTunnel(ctx context.Context, sel ast.SelectionSet, obj *postgres.PostgresAccessConnectionTunnel) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, postgresAccessConnectionTunnelImplementors) out := graphql.NewFieldSet(fields) deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": - out.Values[i] = graphql.MarshalString("DeletePostgresPayload") - case "postgresDeleted": - out.Values[i] = ec._DeletePostgresPayload_postgresDeleted(ctx, field, obj) + out.Values[i] = graphql.MarshalString("PostgresAccessConnectionTunnel") + case "endpoint": + out.Values[i] = ec._PostgresAccessConnectionTunnel_endpoint(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "gatewayPublicKey": + out.Values[i] = ec._PostgresAccessConnectionTunnel_gatewayPublicKey(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -1777,19 +3207,26 @@ func (ec *executionContext) _DeletePostgresPayload(ctx context.Context, sel ast. return out } -var grantPostgresAccessPayloadImplementors = []string{"GrantPostgresAccessPayload"} +var postgresAccessTunnelImplementors = []string{"PostgresAccessTunnel"} -func (ec *executionContext) _GrantPostgresAccessPayload(ctx context.Context, sel ast.SelectionSet, obj *postgres.GrantPostgresAccessPayload) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, grantPostgresAccessPayloadImplementors) +func (ec *executionContext) _PostgresAccessTunnel(ctx context.Context, sel ast.SelectionSet, obj *postgres.PostgresAccessTunnel) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, postgresAccessTunnelImplementors) out := graphql.NewFieldSet(fields) deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": - out.Values[i] = graphql.MarshalString("GrantPostgresAccessPayload") - case "error": - out.Values[i] = ec._GrantPostgresAccessPayload_error(ctx, field, obj) + out.Values[i] = graphql.MarshalString("PostgresAccessTunnel") + case "name": + out.Values[i] = ec._PostgresAccessTunnel_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "endpoint": + out.Values[i] = ec._PostgresAccessTunnel_endpoint(ctx, field, obj) + case "gatewayPublicKey": + out.Values[i] = ec._PostgresAccessTunnel_gatewayPublicKey(ctx, field, obj) default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2739,6 +4176,197 @@ func (ec *executionContext) _PostgresInstanceStateFacetItem(ctx context.Context, return out } +var postgresPersonalAccessConnectionActivityLogEntryImplementors = []string{"PostgresPersonalAccessConnectionActivityLogEntry", "ActivityLogEntry", "Node"} + +func (ec *executionContext) _PostgresPersonalAccessConnectionActivityLogEntry(ctx context.Context, sel ast.SelectionSet, obj *postgres.PostgresPersonalAccessConnectionActivityLogEntry) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, postgresPersonalAccessConnectionActivityLogEntryImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("PostgresPersonalAccessConnectionActivityLogEntry") + case "id": + out.Values[i] = ec._PostgresPersonalAccessConnectionActivityLogEntry_id(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "actor": + out.Values[i] = ec._PostgresPersonalAccessConnectionActivityLogEntry_actor(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "createdAt": + out.Values[i] = ec._PostgresPersonalAccessConnectionActivityLogEntry_createdAt(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "message": + out.Values[i] = ec._PostgresPersonalAccessConnectionActivityLogEntry_message(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "resourceType": + out.Values[i] = ec._PostgresPersonalAccessConnectionActivityLogEntry_resourceType(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "resourceName": + out.Values[i] = ec._PostgresPersonalAccessConnectionActivityLogEntry_resourceName(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "teamSlug": + out.Values[i] = ec._PostgresPersonalAccessConnectionActivityLogEntry_teamSlug(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "environmentName": + out.Values[i] = ec._PostgresPersonalAccessConnectionActivityLogEntry_environmentName(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.Deferred, int32(min(len(deferred), math.MaxInt32))) + + for label, dfs := range deferred { + ec.ProcessDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var postgresPersonalAccessCreatedActivityLogEntryImplementors = []string{"PostgresPersonalAccessCreatedActivityLogEntry", "ActivityLogEntry", "Node"} + +func (ec *executionContext) _PostgresPersonalAccessCreatedActivityLogEntry(ctx context.Context, sel ast.SelectionSet, obj *postgres.PostgresPersonalAccessCreatedActivityLogEntry) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, postgresPersonalAccessCreatedActivityLogEntryImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("PostgresPersonalAccessCreatedActivityLogEntry") + case "id": + out.Values[i] = ec._PostgresPersonalAccessCreatedActivityLogEntry_id(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "actor": + out.Values[i] = ec._PostgresPersonalAccessCreatedActivityLogEntry_actor(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "createdAt": + out.Values[i] = ec._PostgresPersonalAccessCreatedActivityLogEntry_createdAt(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "message": + out.Values[i] = ec._PostgresPersonalAccessCreatedActivityLogEntry_message(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "resourceType": + out.Values[i] = ec._PostgresPersonalAccessCreatedActivityLogEntry_resourceType(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "resourceName": + out.Values[i] = ec._PostgresPersonalAccessCreatedActivityLogEntry_resourceName(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "teamSlug": + out.Values[i] = ec._PostgresPersonalAccessCreatedActivityLogEntry_teamSlug(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "environmentName": + out.Values[i] = ec._PostgresPersonalAccessCreatedActivityLogEntry_environmentName(ctx, field, obj) + case "data": + out.Values[i] = ec._PostgresPersonalAccessCreatedActivityLogEntry_data(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.Deferred, int32(min(len(deferred), math.MaxInt32))) + + for label, dfs := range deferred { + ec.ProcessDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var postgresPersonalAccessCreatedActivityLogEntryDataImplementors = []string{"PostgresPersonalAccessCreatedActivityLogEntryData"} + +func (ec *executionContext) _PostgresPersonalAccessCreatedActivityLogEntryData(ctx context.Context, sel ast.SelectionSet, obj *postgres.PostgresPersonalAccessCreatedActivityLogEntryData) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, postgresPersonalAccessCreatedActivityLogEntryDataImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("PostgresPersonalAccessCreatedActivityLogEntryData") + case "username": + out.Values[i] = ec._PostgresPersonalAccessCreatedActivityLogEntryData_username(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "expiresAt": + out.Values[i] = ec._PostgresPersonalAccessCreatedActivityLogEntryData_expiresAt(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.Deferred, int32(min(len(deferred), math.MaxInt32))) + + for label, dfs := range deferred { + ec.ProcessDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + var teamInventoryCountPostgresInstancesImplementors = []string{"TeamInventoryCountPostgresInstances"} func (ec *executionContext) _TeamInventoryCountPostgresInstances(ctx context.Context, sel ast.SelectionSet, obj *postgres.TeamInventoryCountPostgresInstances) graphql.Marshaler { @@ -2782,6 +4410,25 @@ func (ec *executionContext) _TeamInventoryCountPostgresInstances(ctx context.Con // region ***************************** type.gotpl ***************************** +func (ec *executionContext) unmarshalNCreatePostgresAccessInput2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐCreatePostgresAccessInput(ctx context.Context, v any) (postgres.CreatePostgresAccessInput, error) { + res, err := ec.unmarshalInputCreatePostgresAccessInput(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNCreatePostgresAccessPayload2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐCreatePostgresAccessPayload(ctx context.Context, sel ast.SelectionSet, v postgres.CreatePostgresAccessPayload) graphql.Marshaler { + return ec._CreatePostgresAccessPayload(ctx, sel, &v) +} + +func (ec *executionContext) marshalNCreatePostgresAccessPayload2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐCreatePostgresAccessPayload(ctx context.Context, sel ast.SelectionSet, v *postgres.CreatePostgresAccessPayload) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + graphql.AddErrorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._CreatePostgresAccessPayload(ctx, sel, v) +} + func (ec *executionContext) unmarshalNDeletePostgresInput2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐDeletePostgresInput(ctx context.Context, v any) (postgres.DeletePostgresInput, error) { res, err := ec.unmarshalInputDeletePostgresInput(ctx, v) return res, graphql.ErrorOnPath(ctx, err) @@ -2820,6 +4467,63 @@ func (ec *executionContext) marshalNGrantPostgresAccessPayload2ᚖgithubᚗcom return ec._GrantPostgresAccessPayload(ctx, sel, v) } +func (ec *executionContext) marshalNPostgresAccess2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccess(ctx context.Context, sel ast.SelectionSet, v postgres.PostgresAccess) graphql.Marshaler { + return ec._PostgresAccess(ctx, sel, &v) +} + +func (ec *executionContext) marshalNPostgresAccess2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccess(ctx context.Context, sel ast.SelectionSet, v *postgres.PostgresAccess) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + graphql.AddErrorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._PostgresAccess(ctx, sel, v) +} + +func (ec *executionContext) unmarshalNPostgresAccessConnectionInput2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccessConnectionInput(ctx context.Context, v any) (postgres.PostgresAccessConnectionInput, error) { + res, err := ec.unmarshalInputPostgresAccessConnectionInput(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNPostgresAccessConnectionPayload2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccessConnectionPayload(ctx context.Context, sel ast.SelectionSet, v postgres.PostgresAccessConnectionPayload) graphql.Marshaler { + return ec._PostgresAccessConnectionPayload(ctx, sel, &v) +} + +func (ec *executionContext) marshalNPostgresAccessConnectionPayload2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccessConnectionPayload(ctx context.Context, sel ast.SelectionSet, v *postgres.PostgresAccessConnectionPayload) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + graphql.AddErrorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._PostgresAccessConnectionPayload(ctx, sel, v) +} + +func (ec *executionContext) marshalNPostgresAccessConnectionTunnel2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccessConnectionTunnel(ctx context.Context, sel ast.SelectionSet, v postgres.PostgresAccessConnectionTunnel) graphql.Marshaler { + return ec._PostgresAccessConnectionTunnel(ctx, sel, &v) +} + +func (ec *executionContext) unmarshalNPostgresAccessLevel2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccessLevel(ctx context.Context, v any) (postgres.PostgresAccessLevel, error) { + var res postgres.PostgresAccessLevel + err := res.UnmarshalGQL(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNPostgresAccessLevel2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccessLevel(ctx context.Context, sel ast.SelectionSet, v postgres.PostgresAccessLevel) graphql.Marshaler { + return v +} + +func (ec *executionContext) unmarshalNPostgresAccessState2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccessState(ctx context.Context, v any) (postgres.PostgresAccessState, error) { + var res postgres.PostgresAccessState + err := res.UnmarshalGQL(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalNPostgresAccessState2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccessState(ctx context.Context, sel ast.SelectionSet, v postgres.PostgresAccessState) graphql.Marshaler { + return v +} + func (ec *executionContext) marshalNPostgresGrantAccessActivityLogEntryData2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresGrantAccessActivityLogEntryData(ctx context.Context, sel ast.SelectionSet, v *postgres.PostgresGrantAccessActivityLogEntryData) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { @@ -2948,6 +4652,16 @@ func (ec *executionContext) marshalNPostgresInstanceStateFacetItem2ᚕgithubᚗc return ret } +func (ec *executionContext) marshalNPostgresPersonalAccessCreatedActivityLogEntryData2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresPersonalAccessCreatedActivityLogEntryData(ctx context.Context, sel ast.SelectionSet, v *postgres.PostgresPersonalAccessCreatedActivityLogEntryData) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + graphql.AddErrorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._PostgresPersonalAccessCreatedActivityLogEntryData(ctx, sel, v) +} + func (ec *executionContext) marshalNTeamInventoryCountPostgresInstances2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐTeamInventoryCountPostgresInstances(ctx context.Context, sel ast.SelectionSet, v postgres.TeamInventoryCountPostgresInstances) graphql.Marshaler { return ec._TeamInventoryCountPostgresInstances(ctx, sel, &v) } @@ -2962,6 +4676,13 @@ func (ec *executionContext) marshalNTeamInventoryCountPostgresInstances2ᚖgithu return ec._TeamInventoryCountPostgresInstances(ctx, sel, v) } +func (ec *executionContext) marshalOPostgresAccessTunnel2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccessTunnel(ctx context.Context, sel ast.SelectionSet, v *postgres.PostgresAccessTunnel) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._PostgresAccessTunnel(ctx, sel, v) +} + func (ec *executionContext) marshalOPostgresInstanceFacets2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceFacets(ctx context.Context, sel ast.SelectionSet, v *postgres.PostgresInstanceFacets) graphql.Marshaler { if v == nil { return graphql.Null diff --git a/internal/graph/gengql/root_.generated.go b/internal/graph/gengql/root_.generated.go index ad96f7900..f7039e068 100644 --- a/internal/graph/gengql/root_.generated.go +++ b/internal/graph/gengql/root_.generated.go @@ -105,6 +105,7 @@ type ResolverRoot interface { OpenSearchConnection() OpenSearchConnectionResolver OpenSearchIssue() OpenSearchIssueResolver OpenSearchMaintenance() OpenSearchMaintenanceResolver + PostgresAccess() PostgresAccessResolver PostgresInstance() PostgresInstanceResolver PostgresInstanceAudit() PostgresInstanceAuditResolver PostgresInstanceConnection() PostgresInstanceConnectionResolver @@ -722,6 +723,11 @@ type ComplexityRoot struct { OpenSearch func(childComplexity int) int } + CreatePostgresAccessPayload struct { + ExpiresAt func(childComplexity int) int + Name func(childComplexity int) int + } + CreateSecretPayload struct { Secret func(childComplexity int) int } @@ -1589,6 +1595,7 @@ type ComplexityRoot struct { CreateKafkaCredentials func(childComplexity int, input kafkatopic.CreateKafkaCredentialsInput) int CreateOpenSearch func(childComplexity int, input opensearch.CreateOpenSearchInput) int CreateOpenSearchCredentials func(childComplexity int, input opensearch.CreateOpenSearchCredentialsInput) int + CreatePostgresAccess func(childComplexity int, input postgres.CreatePostgresAccessInput) int CreateSecret func(childComplexity int, input secret.CreateSecretInput) int CreateServiceAccount func(childComplexity int, input serviceaccount.CreateServiceAccountInput) int CreateServiceAccountToken func(childComplexity int, input serviceaccount.CreateServiceAccountTokenInput) int @@ -1852,6 +1859,37 @@ type ComplexityRoot struct { TotalCount func(childComplexity int) int } + PostgresAccess struct { + AccessLevel func(childComplexity int) int + ExpiresAt func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + Name func(childComplexity int) int + PostgresInstance func(childComplexity int) int + State func(childComplexity int) int + Team func(childComplexity int) int + TeamEnvironment func(childComplexity int) int + Tunnel func(childComplexity int) int + } + + PostgresAccessConnectionPayload struct { + CACertificate func(childComplexity int) int + Password func(childComplexity int) int + ServerName func(childComplexity int) int + Tunnel func(childComplexity int) int + } + + PostgresAccessConnectionTunnel struct { + Endpoint func(childComplexity int) int + GatewayPublicKey func(childComplexity int) int + } + + PostgresAccessTunnel struct { + Endpoint func(childComplexity int) int + GatewayPublicKey func(childComplexity int) int + Name func(childComplexity int) int + } + PostgresDeletedActivityLogEntry struct { Actor func(childComplexity int) int CreatedAt func(childComplexity int) int @@ -1937,6 +1975,34 @@ type ComplexityRoot struct { State func(childComplexity int) int } + PostgresPersonalAccessConnectionActivityLogEntry struct { + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + EnvironmentName func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int + } + + PostgresPersonalAccessCreatedActivityLogEntry struct { + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + Data func(childComplexity int) int + EnvironmentName func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int + } + + PostgresPersonalAccessCreatedActivityLogEntryData struct { + ExpiresAt func(childComplexity int) int + Username func(childComplexity int) int + } + Price struct { Value func(childComplexity int) int } @@ -1975,6 +2041,8 @@ type ComplexityRoot struct { ImageVulnerabilityHistory func(childComplexity int, from scalar.Date) int Me func(childComplexity int) int Node func(childComplexity int, id ident.Ident) int + PostgresAccess func(childComplexity int, name string, teamSlug slug.Slug, environmentName string) int + PostgresAccessConnection func(childComplexity int, input postgres.PostgresAccessConnectionInput) int Reconcilers func(childComplexity int, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor) int Roles func(childComplexity int, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, filter *authz.RoleFilter) int Search func(childComplexity int, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, filter search.SearchFilter) int @@ -6172,6 +6240,20 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.CreateOpenSearchPayload.OpenSearch(childComplexity), true + case "CreatePostgresAccessPayload.expiresAt": + if e.ComplexityRoot.CreatePostgresAccessPayload.ExpiresAt == nil { + break + } + + return e.ComplexityRoot.CreatePostgresAccessPayload.ExpiresAt(childComplexity), true + + case "CreatePostgresAccessPayload.name": + if e.ComplexityRoot.CreatePostgresAccessPayload.Name == nil { + break + } + + return e.ComplexityRoot.CreatePostgresAccessPayload.Name(childComplexity), true + case "CreateSecretPayload.secret": if e.ComplexityRoot.CreateSecretPayload.Secret == nil { break @@ -9716,6 +9798,18 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.Mutation.CreateOpenSearchCredentials(childComplexity, args["input"].(opensearch.CreateOpenSearchCredentialsInput)), true + case "Mutation.createPostgresAccess": + if e.ComplexityRoot.Mutation.CreatePostgresAccess == nil { + break + } + + args, err := ec.field_Mutation_createPostgresAccess_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.ComplexityRoot.Mutation.CreatePostgresAccess(childComplexity, args["input"].(postgres.CreatePostgresAccessInput)), true + case "Mutation.createSecret": if e.ComplexityRoot.Mutation.CreateSecret == nil { break @@ -11235,6 +11329,139 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.PageInfo.TotalCount(childComplexity), true + case "PostgresAccess.accessLevel": + if e.ComplexityRoot.PostgresAccess.AccessLevel == nil { + break + } + + return e.ComplexityRoot.PostgresAccess.AccessLevel(childComplexity), true + + case "PostgresAccess.expiresAt": + if e.ComplexityRoot.PostgresAccess.ExpiresAt == nil { + break + } + + return e.ComplexityRoot.PostgresAccess.ExpiresAt(childComplexity), true + + case "PostgresAccess.id": + if e.ComplexityRoot.PostgresAccess.ID == nil { + break + } + + return e.ComplexityRoot.PostgresAccess.ID(childComplexity), true + + case "PostgresAccess.message": + if e.ComplexityRoot.PostgresAccess.Message == nil { + break + } + + return e.ComplexityRoot.PostgresAccess.Message(childComplexity), true + + case "PostgresAccess.name": + if e.ComplexityRoot.PostgresAccess.Name == nil { + break + } + + return e.ComplexityRoot.PostgresAccess.Name(childComplexity), true + + case "PostgresAccess.postgresInstance": + if e.ComplexityRoot.PostgresAccess.PostgresInstance == nil { + break + } + + return e.ComplexityRoot.PostgresAccess.PostgresInstance(childComplexity), true + + case "PostgresAccess.state": + if e.ComplexityRoot.PostgresAccess.State == nil { + break + } + + return e.ComplexityRoot.PostgresAccess.State(childComplexity), true + + case "PostgresAccess.team": + if e.ComplexityRoot.PostgresAccess.Team == nil { + break + } + + return e.ComplexityRoot.PostgresAccess.Team(childComplexity), true + + case "PostgresAccess.teamEnvironment": + if e.ComplexityRoot.PostgresAccess.TeamEnvironment == nil { + break + } + + return e.ComplexityRoot.PostgresAccess.TeamEnvironment(childComplexity), true + + case "PostgresAccess.tunnel": + if e.ComplexityRoot.PostgresAccess.Tunnel == nil { + break + } + + return e.ComplexityRoot.PostgresAccess.Tunnel(childComplexity), true + + case "PostgresAccessConnectionPayload.caCertificate": + if e.ComplexityRoot.PostgresAccessConnectionPayload.CACertificate == nil { + break + } + + return e.ComplexityRoot.PostgresAccessConnectionPayload.CACertificate(childComplexity), true + + case "PostgresAccessConnectionPayload.password": + if e.ComplexityRoot.PostgresAccessConnectionPayload.Password == nil { + break + } + + return e.ComplexityRoot.PostgresAccessConnectionPayload.Password(childComplexity), true + + case "PostgresAccessConnectionPayload.serverName": + if e.ComplexityRoot.PostgresAccessConnectionPayload.ServerName == nil { + break + } + + return e.ComplexityRoot.PostgresAccessConnectionPayload.ServerName(childComplexity), true + + case "PostgresAccessConnectionPayload.tunnel": + if e.ComplexityRoot.PostgresAccessConnectionPayload.Tunnel == nil { + break + } + + return e.ComplexityRoot.PostgresAccessConnectionPayload.Tunnel(childComplexity), true + + case "PostgresAccessConnectionTunnel.endpoint": + if e.ComplexityRoot.PostgresAccessConnectionTunnel.Endpoint == nil { + break + } + + return e.ComplexityRoot.PostgresAccessConnectionTunnel.Endpoint(childComplexity), true + + case "PostgresAccessConnectionTunnel.gatewayPublicKey": + if e.ComplexityRoot.PostgresAccessConnectionTunnel.GatewayPublicKey == nil { + break + } + + return e.ComplexityRoot.PostgresAccessConnectionTunnel.GatewayPublicKey(childComplexity), true + + case "PostgresAccessTunnel.endpoint": + if e.ComplexityRoot.PostgresAccessTunnel.Endpoint == nil { + break + } + + return e.ComplexityRoot.PostgresAccessTunnel.Endpoint(childComplexity), true + + case "PostgresAccessTunnel.gatewayPublicKey": + if e.ComplexityRoot.PostgresAccessTunnel.GatewayPublicKey == nil { + break + } + + return e.ComplexityRoot.PostgresAccessTunnel.GatewayPublicKey(childComplexity), true + + case "PostgresAccessTunnel.name": + if e.ComplexityRoot.PostgresAccessTunnel.Name == nil { + break + } + + return e.ComplexityRoot.PostgresAccessTunnel.Name(childComplexity), true + case "PostgresDeletedActivityLogEntry.actor": if e.ComplexityRoot.PostgresDeletedActivityLogEntry.Actor == nil { break @@ -11604,6 +11831,139 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.PostgresInstanceStateFacetItem.State(childComplexity), true + case "PostgresPersonalAccessConnectionActivityLogEntry.actor": + if e.ComplexityRoot.PostgresPersonalAccessConnectionActivityLogEntry.Actor == nil { + break + } + + return e.ComplexityRoot.PostgresPersonalAccessConnectionActivityLogEntry.Actor(childComplexity), true + + case "PostgresPersonalAccessConnectionActivityLogEntry.createdAt": + if e.ComplexityRoot.PostgresPersonalAccessConnectionActivityLogEntry.CreatedAt == nil { + break + } + + return e.ComplexityRoot.PostgresPersonalAccessConnectionActivityLogEntry.CreatedAt(childComplexity), true + + case "PostgresPersonalAccessConnectionActivityLogEntry.environmentName": + if e.ComplexityRoot.PostgresPersonalAccessConnectionActivityLogEntry.EnvironmentName == nil { + break + } + + return e.ComplexityRoot.PostgresPersonalAccessConnectionActivityLogEntry.EnvironmentName(childComplexity), true + + case "PostgresPersonalAccessConnectionActivityLogEntry.id": + if e.ComplexityRoot.PostgresPersonalAccessConnectionActivityLogEntry.ID == nil { + break + } + + return e.ComplexityRoot.PostgresPersonalAccessConnectionActivityLogEntry.ID(childComplexity), true + + case "PostgresPersonalAccessConnectionActivityLogEntry.message": + if e.ComplexityRoot.PostgresPersonalAccessConnectionActivityLogEntry.Message == nil { + break + } + + return e.ComplexityRoot.PostgresPersonalAccessConnectionActivityLogEntry.Message(childComplexity), true + + case "PostgresPersonalAccessConnectionActivityLogEntry.resourceName": + if e.ComplexityRoot.PostgresPersonalAccessConnectionActivityLogEntry.ResourceName == nil { + break + } + + return e.ComplexityRoot.PostgresPersonalAccessConnectionActivityLogEntry.ResourceName(childComplexity), true + + case "PostgresPersonalAccessConnectionActivityLogEntry.resourceType": + if e.ComplexityRoot.PostgresPersonalAccessConnectionActivityLogEntry.ResourceType == nil { + break + } + + return e.ComplexityRoot.PostgresPersonalAccessConnectionActivityLogEntry.ResourceType(childComplexity), true + + case "PostgresPersonalAccessConnectionActivityLogEntry.teamSlug": + if e.ComplexityRoot.PostgresPersonalAccessConnectionActivityLogEntry.TeamSlug == nil { + break + } + + return e.ComplexityRoot.PostgresPersonalAccessConnectionActivityLogEntry.TeamSlug(childComplexity), true + + case "PostgresPersonalAccessCreatedActivityLogEntry.actor": + if e.ComplexityRoot.PostgresPersonalAccessCreatedActivityLogEntry.Actor == nil { + break + } + + return e.ComplexityRoot.PostgresPersonalAccessCreatedActivityLogEntry.Actor(childComplexity), true + + case "PostgresPersonalAccessCreatedActivityLogEntry.createdAt": + if e.ComplexityRoot.PostgresPersonalAccessCreatedActivityLogEntry.CreatedAt == nil { + break + } + + return e.ComplexityRoot.PostgresPersonalAccessCreatedActivityLogEntry.CreatedAt(childComplexity), true + + case "PostgresPersonalAccessCreatedActivityLogEntry.data": + if e.ComplexityRoot.PostgresPersonalAccessCreatedActivityLogEntry.Data == nil { + break + } + + return e.ComplexityRoot.PostgresPersonalAccessCreatedActivityLogEntry.Data(childComplexity), true + + case "PostgresPersonalAccessCreatedActivityLogEntry.environmentName": + if e.ComplexityRoot.PostgresPersonalAccessCreatedActivityLogEntry.EnvironmentName == nil { + break + } + + return e.ComplexityRoot.PostgresPersonalAccessCreatedActivityLogEntry.EnvironmentName(childComplexity), true + + case "PostgresPersonalAccessCreatedActivityLogEntry.id": + if e.ComplexityRoot.PostgresPersonalAccessCreatedActivityLogEntry.ID == nil { + break + } + + return e.ComplexityRoot.PostgresPersonalAccessCreatedActivityLogEntry.ID(childComplexity), true + + case "PostgresPersonalAccessCreatedActivityLogEntry.message": + if e.ComplexityRoot.PostgresPersonalAccessCreatedActivityLogEntry.Message == nil { + break + } + + return e.ComplexityRoot.PostgresPersonalAccessCreatedActivityLogEntry.Message(childComplexity), true + + case "PostgresPersonalAccessCreatedActivityLogEntry.resourceName": + if e.ComplexityRoot.PostgresPersonalAccessCreatedActivityLogEntry.ResourceName == nil { + break + } + + return e.ComplexityRoot.PostgresPersonalAccessCreatedActivityLogEntry.ResourceName(childComplexity), true + + case "PostgresPersonalAccessCreatedActivityLogEntry.resourceType": + if e.ComplexityRoot.PostgresPersonalAccessCreatedActivityLogEntry.ResourceType == nil { + break + } + + return e.ComplexityRoot.PostgresPersonalAccessCreatedActivityLogEntry.ResourceType(childComplexity), true + + case "PostgresPersonalAccessCreatedActivityLogEntry.teamSlug": + if e.ComplexityRoot.PostgresPersonalAccessCreatedActivityLogEntry.TeamSlug == nil { + break + } + + return e.ComplexityRoot.PostgresPersonalAccessCreatedActivityLogEntry.TeamSlug(childComplexity), true + + case "PostgresPersonalAccessCreatedActivityLogEntryData.expiresAt": + if e.ComplexityRoot.PostgresPersonalAccessCreatedActivityLogEntryData.ExpiresAt == nil { + break + } + + return e.ComplexityRoot.PostgresPersonalAccessCreatedActivityLogEntryData.ExpiresAt(childComplexity), true + + case "PostgresPersonalAccessCreatedActivityLogEntryData.username": + if e.ComplexityRoot.PostgresPersonalAccessCreatedActivityLogEntryData.Username == nil { + break + } + + return e.ComplexityRoot.PostgresPersonalAccessCreatedActivityLogEntryData.Username(childComplexity), true + case "Price.value": if e.ComplexityRoot.Price.Value == nil { break @@ -11845,6 +12205,30 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.Query.Node(childComplexity, args["id"].(ident.Ident)), true + case "Query.postgresAccess": + if e.ComplexityRoot.Query.PostgresAccess == nil { + break + } + + args, err := ec.field_Query_postgresAccess_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.ComplexityRoot.Query.PostgresAccess(childComplexity, args["name"].(string), args["teamSlug"].(slug.Slug), args["environmentName"].(string)), true + + case "Query.postgresAccessConnection": + if e.ComplexityRoot.Query.PostgresAccessConnection == nil { + break + } + + args, err := ec.field_Query_postgresAccessConnection_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.ComplexityRoot.Query.PostgresAccessConnection(childComplexity, args["input"].(postgres.PostgresAccessConnectionInput)), true + case "Query.reconcilers": if e.ComplexityRoot.Query.Reconcilers == nil { break @@ -19890,6 +20274,7 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { ec.unmarshalInputCreateKafkaCredentialsInput, ec.unmarshalInputCreateOpenSearchCredentialsInput, ec.unmarshalInputCreateOpenSearchInput, + ec.unmarshalInputCreatePostgresAccessInput, ec.unmarshalInputCreateSecretInput, ec.unmarshalInputCreateServiceAccountInput, ec.unmarshalInputCreateServiceAccountTokenInput, @@ -19935,6 +20320,7 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { ec.unmarshalInputOpenSearchAccessOrder, ec.unmarshalInputOpenSearchFilter, ec.unmarshalInputOpenSearchOrder, + ec.unmarshalInputPostgresAccessConnectionInput, ec.unmarshalInputPostgresInstanceFilter, ec.unmarshalInputPostgresInstanceOrder, ec.unmarshalInputReconcilerConfigInput, @@ -26543,6 +26929,43 @@ type PostgresGrantAccessActivityLogEntryData { until: Time! } +type PostgresPersonalAccessCreatedActivityLogEntry implements ActivityLogEntry & Node { + "ID of the entry." + id: ID! + "The identity of the actor who created the personal access." + actor: String! + "Creation time of the entry." + createdAt: Time! + "Message that summarizes the entry." + message: String! + "Type of the affected resource." + resourceType: ActivityLogEntryResourceType! + "Name of the affected Postgres instance." + resourceName: String! + "The team slug that the entry belongs to." + teamSlug: Slug! + "The environment name that the entry belongs to." + environmentName: String + "Personal-access specific audit data." + data: PostgresPersonalAccessCreatedActivityLogEntryData! +} + +type PostgresPersonalAccessCreatedActivityLogEntryData { + username: String! + expiresAt: Time! +} + +type PostgresPersonalAccessConnectionActivityLogEntry implements ActivityLogEntry & Node { + id: ID! + actor: String! + createdAt: Time! + message: String! + resourceType: ActivityLogEntryResourceType! + resourceName: String! + teamSlug: Slug! + environmentName: String +} + type PostgresDeletedActivityLogEntry implements ActivityLogEntry & Node { "ID of the entry." id: ID! @@ -26575,18 +26998,49 @@ extend enum ActivityLogActivityType { """ POSTGRES_GRANT_ACCESS """ + A personal Postgres access was created through the API broker + """ + POSTGRES_PERSONAL_ACCESS_CREATED + """ + Personal Postgres connection materials were retrieved + """ + POSTGRES_PERSONAL_ACCESS_CONNECTION + """ A Postgres instance was deleted """ POSTGRES_DELETED } extend type Mutation { + "Create a time-limited personal Postgres access through the API broker." + createPostgresAccess(input: CreatePostgresAccessInput!): CreatePostgresAccessPayload! "Grant temporary access to a Postgres cluster." grantPostgresAccess(input: GrantPostgresAccessInput!): GrantPostgresAccessPayload! "Delete an existing Postgres instance." deletePostgres(input: DeletePostgresInput!): DeletePostgresPayload! } +type CreatePostgresAccessPayload { + "Name of the newly created PostgresAccess resource." + name: String! + "Server-controlled expiry for this personal access." + expiresAt: Time! +} + +input CreatePostgresAccessInput { + postgresInstance: String! + teamSlug: Slug! + environmentName: String! + accessLevel: PostgresAccessLevel! + clientWireGuardPublicKey: String! +} + +enum PostgresAccessLevel { + READ + READWRITE + READWRITECREATE +} + type GrantPostgresAccessPayload { error: String } @@ -26622,6 +27076,78 @@ type TeamInventoryCountPostgresInstances { "Total number of Postgres instances." total: Int! } + +extend type Query { + "Get connection materials for a ready personal Postgres access owned by the caller." + postgresAccessConnection(input: PostgresAccessConnectionInput!): PostgresAccessConnectionPayload! + + "Get a personal PostgresAccess resource and its ready state." + postgresAccess( + "Name of the PostgresAccess resource." + name: String! + + "Team slug that owns the Postgres instance." + teamSlug: Slug! + + "Environment name that the Postgres instance belongs to." + environmentName: String! + ): PostgresAccess! +} + +type PostgresAccess implements Node { + id: ID! + name: String! + "Team that owns the access." + team: Team! + "Environment for the access." + teamEnvironment: TeamEnvironment! + "Postgres instance this access is for." + postgresInstance: PostgresInstance! + "Requested access level." + accessLevel: PostgresAccessLevel! + "Server-controlled expiry for this personal access." + expiresAt: Time! + "High-level state of the access." + state: PostgresAccessState! + "Human-readable message for the current state." + message: String + "Tunnel connection details, once the controller has created them." + tunnel: PostgresAccessTunnel +} + +enum PostgresAccessState { + PENDING + READY + FAILED + EXPIRED +} + +type PostgresAccessTunnel { + "Name of the Tunnel resource owned by this access." + name: String! + "Gateway endpoint the client should connect to." + endpoint: String + "Gateway's WireGuard public key." + gatewayPublicKey: String +} + +input PostgresAccessConnectionInput { + name: String! + teamSlug: Slug! + environmentName: String! +} + +type PostgresAccessConnectionPayload { + password: String! + caCertificate: String! + serverName: String! + tunnel: PostgresAccessConnectionTunnel! +} + +type PostgresAccessConnectionTunnel { + endpoint: String! + gatewayPublicKey: String! +} `, BuiltIn: false}, {Name: "../schema/price.graphqls", Input: `extend type Query { """ @@ -34717,6 +35243,16 @@ func (ec *executionContext) childFields_CreateOpenSearchPayload(ctx context.Cont return nil, fmt.Errorf("no field named %q was found under type CreateOpenSearchPayload", field.Name) } +func (ec *executionContext) childFields_CreatePostgresAccessPayload(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext_CreatePostgresAccessPayload_name(ctx, field) + case "expiresAt": + return ec.fieldContext_CreatePostgresAccessPayload_expiresAt(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type CreatePostgresAccessPayload", field.Name) +} + func (ec *executionContext) childFields_CreateSecretPayload(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { switch field.Name { case "secret": @@ -36279,6 +36815,68 @@ func (ec *executionContext) childFields_PageInfo(ctx context.Context, field grap return nil, fmt.Errorf("no field named %q was found under type PageInfo", field.Name) } +func (ec *executionContext) childFields_PostgresAccess(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_PostgresAccess_id(ctx, field) + case "name": + return ec.fieldContext_PostgresAccess_name(ctx, field) + case "team": + return ec.fieldContext_PostgresAccess_team(ctx, field) + case "teamEnvironment": + return ec.fieldContext_PostgresAccess_teamEnvironment(ctx, field) + case "postgresInstance": + return ec.fieldContext_PostgresAccess_postgresInstance(ctx, field) + case "accessLevel": + return ec.fieldContext_PostgresAccess_accessLevel(ctx, field) + case "expiresAt": + return ec.fieldContext_PostgresAccess_expiresAt(ctx, field) + case "state": + return ec.fieldContext_PostgresAccess_state(ctx, field) + case "message": + return ec.fieldContext_PostgresAccess_message(ctx, field) + case "tunnel": + return ec.fieldContext_PostgresAccess_tunnel(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type PostgresAccess", field.Name) +} + +func (ec *executionContext) childFields_PostgresAccessConnectionPayload(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "password": + return ec.fieldContext_PostgresAccessConnectionPayload_password(ctx, field) + case "caCertificate": + return ec.fieldContext_PostgresAccessConnectionPayload_caCertificate(ctx, field) + case "serverName": + return ec.fieldContext_PostgresAccessConnectionPayload_serverName(ctx, field) + case "tunnel": + return ec.fieldContext_PostgresAccessConnectionPayload_tunnel(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type PostgresAccessConnectionPayload", field.Name) +} + +func (ec *executionContext) childFields_PostgresAccessConnectionTunnel(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "endpoint": + return ec.fieldContext_PostgresAccessConnectionTunnel_endpoint(ctx, field) + case "gatewayPublicKey": + return ec.fieldContext_PostgresAccessConnectionTunnel_gatewayPublicKey(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type PostgresAccessConnectionTunnel", field.Name) +} + +func (ec *executionContext) childFields_PostgresAccessTunnel(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "name": + return ec.fieldContext_PostgresAccessTunnel_name(ctx, field) + case "endpoint": + return ec.fieldContext_PostgresAccessTunnel_endpoint(ctx, field) + case "gatewayPublicKey": + return ec.fieldContext_PostgresAccessTunnel_gatewayPublicKey(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type PostgresAccessTunnel", field.Name) +} + func (ec *executionContext) childFields_PostgresGrantAccessActivityLogEntryData(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { switch field.Name { case "grantee": @@ -36403,6 +37001,16 @@ func (ec *executionContext) childFields_PostgresInstanceStateFacetItem(ctx conte return nil, fmt.Errorf("no field named %q was found under type PostgresInstanceStateFacetItem", field.Name) } +func (ec *executionContext) childFields_PostgresPersonalAccessCreatedActivityLogEntryData(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "username": + return ec.fieldContext_PostgresPersonalAccessCreatedActivityLogEntryData_username(ctx, field) + case "expiresAt": + return ec.fieldContext_PostgresPersonalAccessCreatedActivityLogEntryData_expiresAt(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type PostgresPersonalAccessCreatedActivityLogEntryData", field.Name) +} + func (ec *executionContext) childFields_Price(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { switch field.Name { case "value": diff --git a/internal/graph/gengql/schema.generated.go b/internal/graph/gengql/schema.generated.go index b250f46cd..0c8dd0c0f 100644 --- a/internal/graph/gengql/schema.generated.go +++ b/internal/graph/gengql/schema.generated.go @@ -84,6 +84,7 @@ type MutationResolver interface { UpdateOpenSearch(ctx context.Context, input opensearch.UpdateOpenSearchInput) (*opensearch.UpdateOpenSearchPayload, error) DeleteOpenSearch(ctx context.Context, input opensearch.DeleteOpenSearchInput) (*opensearch.DeleteOpenSearchPayload, error) CreateOpenSearchCredentials(ctx context.Context, input opensearch.CreateOpenSearchCredentialsInput) (*opensearch.CreateOpenSearchCredentialsPayload, error) + CreatePostgresAccess(ctx context.Context, input postgres.CreatePostgresAccessInput) (*postgres.CreatePostgresAccessPayload, error) GrantPostgresAccess(ctx context.Context, input postgres.GrantPostgresAccessInput) (*postgres.GrantPostgresAccessPayload, error) DeletePostgres(ctx context.Context, input postgres.DeletePostgresInput) (*postgres.DeletePostgresPayload, error) EnableReconciler(ctx context.Context, input reconciler.EnableReconcilerInput) (*reconciler.Reconciler, error) @@ -140,6 +141,8 @@ type QueryResolver interface { Environments(ctx context.Context, orderBy *environment.EnvironmentOrder) (*pagination.Connection[*environment.Environment], error) Environment(ctx context.Context, name string) (*environment.Environment, error) Features(ctx context.Context) (*feature.Features, error) + PostgresAccessConnection(ctx context.Context, input postgres.PostgresAccessConnectionInput) (*postgres.PostgresAccessConnectionPayload, error) + PostgresAccess(ctx context.Context, name string, teamSlug slug.Slug, environmentName string) (*postgres.PostgresAccess, error) CurrentUnitPrices(ctx context.Context) (*price.CurrentUnitPrices, error) Reconcilers(ctx context.Context, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor) (*pagination.Connection[*reconciler.Reconciler], error) Search(ctx context.Context, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, filter search.SearchFilter) (*pagination.Connection[search.SearchNode], error) @@ -364,6 +367,20 @@ func (ec *executionContext) field_Mutation_createOpenSearch_args(ctx context.Con return args, nil } +func (ec *executionContext) field_Mutation_createPostgresAccess_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := graphql.ProcessArgField(ctx, rawArgs, "input", + func(ctx context.Context, v any) (postgres.CreatePostgresAccessInput, error) { + return ec.unmarshalNCreatePostgresAccessInput2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐCreatePostgresAccessInput(ctx, v) + }) + if err != nil { + return nil, err + } + args["input"] = arg0 + return args, nil +} + func (ec *executionContext) field_Mutation_createSecret_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} @@ -1344,6 +1361,50 @@ func (ec *executionContext) field_Query_node_args(ctx context.Context, rawArgs m return args, nil } +func (ec *executionContext) field_Query_postgresAccessConnection_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := graphql.ProcessArgField(ctx, rawArgs, "input", + func(ctx context.Context, v any) (postgres.PostgresAccessConnectionInput, error) { + return ec.unmarshalNPostgresAccessConnectionInput2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccessConnectionInput(ctx, v) + }) + if err != nil { + return nil, err + } + args["input"] = arg0 + return args, nil +} + +func (ec *executionContext) field_Query_postgresAccess_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := graphql.ProcessArgField(ctx, rawArgs, "name", + func(ctx context.Context, v any) (string, error) { + return ec.unmarshalNString2string(ctx, v) + }) + if err != nil { + return nil, err + } + args["name"] = arg0 + arg1, err := graphql.ProcessArgField(ctx, rawArgs, "teamSlug", + func(ctx context.Context, v any) (slug.Slug, error) { + return ec.unmarshalNSlug2githubᚗcomᚋnaisᚋapiᚋinternalᚋslugᚐSlug(ctx, v) + }) + if err != nil { + return nil, err + } + args["teamSlug"] = arg1 + arg2, err := graphql.ProcessArgField(ctx, rawArgs, "environmentName", + func(ctx context.Context, v any) (string, error) { + return ec.unmarshalNString2string(ctx, v) + }) + if err != nil { + return nil, err + } + args["environmentName"] = arg2 + return args, nil +} + func (ec *executionContext) field_Query_reconcilers_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} @@ -2636,6 +2697,50 @@ func (ec *executionContext) fieldContext_Mutation_createOpenSearchCredentials(ct return fc, nil } +func (ec *executionContext) _Mutation_createPostgresAccess(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_Mutation_createPostgresAccess(ctx, field) + }, + func(ctx context.Context) (any, error) { + fc := graphql.GetFieldContext(ctx) + return ec.Resolvers.Mutation().CreatePostgresAccess(ctx, fc.Args["input"].(postgres.CreatePostgresAccessInput)) + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *postgres.CreatePostgresAccessPayload) graphql.Marshaler { + return ec.marshalNCreatePostgresAccessPayload2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐCreatePostgresAccessPayload(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_Mutation_createPostgresAccess(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Mutation", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_CreatePostgresAccessPayload(ctx, field) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_Mutation_createPostgresAccess_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + func (ec *executionContext) _Mutation_grantPostgresAccess(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -5161,6 +5266,94 @@ func (ec *executionContext) fieldContext_Query_features(_ context.Context, field return fc, nil } +func (ec *executionContext) _Query_postgresAccessConnection(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_Query_postgresAccessConnection(ctx, field) + }, + func(ctx context.Context) (any, error) { + fc := graphql.GetFieldContext(ctx) + return ec.Resolvers.Query().PostgresAccessConnection(ctx, fc.Args["input"].(postgres.PostgresAccessConnectionInput)) + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *postgres.PostgresAccessConnectionPayload) graphql.Marshaler { + return ec.marshalNPostgresAccessConnectionPayload2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccessConnectionPayload(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_Query_postgresAccessConnection(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_PostgresAccessConnectionPayload(ctx, field) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_Query_postgresAccessConnection_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + +func (ec *executionContext) _Query_postgresAccess(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_Query_postgresAccess(ctx, field) + }, + func(ctx context.Context) (any, error) { + fc := graphql.GetFieldContext(ctx) + return ec.Resolvers.Query().PostgresAccess(ctx, fc.Args["name"].(string), fc.Args["teamSlug"].(slug.Slug), fc.Args["environmentName"].(string)) + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *postgres.PostgresAccess) graphql.Marshaler { + return ec.marshalNPostgresAccess2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccess(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_Query_postgresAccess(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Query", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_PostgresAccess(ctx, field) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_Query_postgresAccess_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + func (ec *executionContext) _Query_currentUnitPrices(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -6525,6 +6718,20 @@ func (ec *executionContext) _Node(ctx context.Context, sel ast.SelectionSet, obj return graphql.Null } return ec._PrometheusAlert(ctx, sel, obj) + case postgres.PostgresPersonalAccessCreatedActivityLogEntry: + return ec._PostgresPersonalAccessCreatedActivityLogEntry(ctx, sel, &obj) + case *postgres.PostgresPersonalAccessCreatedActivityLogEntry: + if obj == nil { + return graphql.Null + } + return ec._PostgresPersonalAccessCreatedActivityLogEntry(ctx, sel, obj) + case postgres.PostgresPersonalAccessConnectionActivityLogEntry: + return ec._PostgresPersonalAccessConnectionActivityLogEntry(ctx, sel, &obj) + case *postgres.PostgresPersonalAccessConnectionActivityLogEntry: + if obj == nil { + return graphql.Null + } + return ec._PostgresPersonalAccessConnectionActivityLogEntry(ctx, sel, obj) case postgres.PostgresInstance: return ec._PostgresInstance(ctx, sel, &obj) case *postgres.PostgresInstance: @@ -6913,6 +7120,13 @@ func (ec *executionContext) _Node(ctx context.Context, sel ast.SelectionSet, obj return graphql.Null } return ec._ReconcilerError(ctx, sel, obj) + case postgres.PostgresAccess: + return ec._PostgresAccess(ctx, sel, &obj) + case *postgres.PostgresAccess: + if obj == nil { + return graphql.Null + } + return ec._PostgresAccess(ctx, sel, obj) case persistence.Persistence: if obj == nil { return graphql.Null @@ -7234,6 +7448,13 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) if out.Values[i] == graphql.Null { out.Invalids++ } + case "createPostgresAccess": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Mutation_createPostgresAccess(ctx, field) + }) + if out.Values[i] == graphql.Null { + out.Invalids++ + } case "grantPostgresAccess": out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { return ec._Mutation_grantPostgresAccess(ctx, field) @@ -7827,6 +8048,50 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) } + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "postgresAccessConnection": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_postgresAccessConnection(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) + case "postgresAccess": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._Query_postgresAccess(ctx, field) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + rrm := func(ctx context.Context) graphql.Marshaler { + return ec.OperationContext.RootResolverMiddleware(ctx, + func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + } + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) case "currentUnitPrices": field := field diff --git a/internal/graph/postgres.resolvers.go b/internal/graph/postgres.resolvers.go index ae99730ab..004235484 100644 --- a/internal/graph/postgres.resolvers.go +++ b/internal/graph/postgres.resolvers.go @@ -7,6 +7,7 @@ import ( "github.com/nais/api/internal/graph/gengql" "github.com/nais/api/internal/graph/pagination" "github.com/nais/api/internal/persistence/postgres" + "github.com/nais/api/internal/slug" "github.com/nais/api/internal/team" "github.com/nais/api/internal/workload" "github.com/nais/api/internal/workload/application" @@ -49,6 +50,14 @@ func (r *jobResolver) PostgresInstances(ctx context.Context, obj *job.Job, order return pagination.NewFacetableConnection(pagination.NewConnectionWithoutPagination(instances), instances, (*postgres.PostgresInstanceFilter)(nil)), nil } +func (r *mutationResolver) CreatePostgresAccess(ctx context.Context, input postgres.CreatePostgresAccessInput) (*postgres.CreatePostgresAccessPayload, error) { + if err := authz.CanGrantPostgresAccess(ctx, input.TeamSlug); err != nil { + return nil, err + } + + return postgres.CreatePostgresAccess(ctx, input) +} + func (r *mutationResolver) GrantPostgresAccess(ctx context.Context, input postgres.GrantPostgresAccessInput) (*postgres.GrantPostgresAccessPayload, error) { if err := authz.CanGrantPostgresAccess(ctx, input.TeamSlug); err != nil { return nil, err @@ -70,6 +79,18 @@ func (r *mutationResolver) DeletePostgres(ctx context.Context, input postgres.De return postgres.Delete(ctx, input) } +func (r *postgresAccessResolver) Team(ctx context.Context, obj *postgres.PostgresAccess) (*team.Team, error) { + return team.Get(ctx, obj.TeamSlug) +} + +func (r *postgresAccessResolver) TeamEnvironment(ctx context.Context, obj *postgres.PostgresAccess) (*team.TeamEnvironment, error) { + return team.GetTeamEnvironment(ctx, obj.TeamSlug, obj.EnvironmentName) +} + +func (r *postgresAccessResolver) PostgresInstance(ctx context.Context, obj *postgres.PostgresAccess) (*postgres.PostgresInstance, error) { + return postgres.GetZalandoPostgres(ctx, obj.TeamSlug, obj.EnvironmentName, obj.PostgresInstanceName) +} + func (r *postgresInstanceResolver) Team(ctx context.Context, obj *postgres.PostgresInstance) (*team.Team, error) { return team.Get(ctx, obj.TeamSlug) } @@ -100,6 +121,14 @@ func (r *postgresInstanceConnectionResolver) Facets(ctx context.Context, obj *pa }, nil } +func (r *queryResolver) PostgresAccessConnection(ctx context.Context, input postgres.PostgresAccessConnectionInput) (*postgres.PostgresAccessConnectionPayload, error) { + return postgres.GetPostgresAccessConnection(ctx, input) +} + +func (r *queryResolver) PostgresAccess(ctx context.Context, name string, teamSlug slug.Slug, environmentName string) (*postgres.PostgresAccess, error) { + return postgres.GetPostgresAccess(ctx, name, teamSlug, environmentName) +} + func (r *teamResolver) PostgresInstances(ctx context.Context, obj *team.Team, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *postgres.PostgresInstanceOrder, filter *postgres.PostgresInstanceFilter) (*pagination.FacetableConnection[*postgres.PostgresInstance, *postgres.PostgresInstanceFilter], error) { page, err := pagination.ParsePage(first, after, last, before) if err != nil { @@ -119,6 +148,8 @@ func (r *teamInventoryCountsResolver) PostgresInstances(ctx context.Context, obj }, nil } +func (r *Resolver) PostgresAccess() gengql.PostgresAccessResolver { return &postgresAccessResolver{r} } + func (r *Resolver) PostgresInstance() gengql.PostgresInstanceResolver { return &postgresInstanceResolver{r} } @@ -132,6 +163,7 @@ func (r *Resolver) PostgresInstanceConnection() gengql.PostgresInstanceConnectio } type ( + postgresAccessResolver struct{ *Resolver } postgresInstanceResolver struct{ *Resolver } postgresInstanceAuditResolver struct{ *Resolver } postgresInstanceConnectionResolver struct{ *Resolver } diff --git a/internal/graph/schema/postgres.graphqls b/internal/graph/schema/postgres.graphqls index 1e9c5ceec..35ea313a0 100644 --- a/internal/graph/schema/postgres.graphqls +++ b/internal/graph/schema/postgres.graphqls @@ -239,6 +239,43 @@ type PostgresGrantAccessActivityLogEntryData { until: Time! } +type PostgresPersonalAccessCreatedActivityLogEntry implements ActivityLogEntry & Node { + "ID of the entry." + id: ID! + "The identity of the actor who created the personal access." + actor: String! + "Creation time of the entry." + createdAt: Time! + "Message that summarizes the entry." + message: String! + "Type of the affected resource." + resourceType: ActivityLogEntryResourceType! + "Name of the affected Postgres instance." + resourceName: String! + "The team slug that the entry belongs to." + teamSlug: Slug! + "The environment name that the entry belongs to." + environmentName: String + "Personal-access specific audit data." + data: PostgresPersonalAccessCreatedActivityLogEntryData! +} + +type PostgresPersonalAccessCreatedActivityLogEntryData { + username: String! + expiresAt: Time! +} + +type PostgresPersonalAccessConnectionActivityLogEntry implements ActivityLogEntry & Node { + id: ID! + actor: String! + createdAt: Time! + message: String! + resourceType: ActivityLogEntryResourceType! + resourceName: String! + teamSlug: Slug! + environmentName: String +} + type PostgresDeletedActivityLogEntry implements ActivityLogEntry & Node { "ID of the entry." id: ID! @@ -271,18 +308,49 @@ extend enum ActivityLogActivityType { """ POSTGRES_GRANT_ACCESS """ + A personal Postgres access was created through the API broker + """ + POSTGRES_PERSONAL_ACCESS_CREATED + """ + Personal Postgres connection materials were retrieved + """ + POSTGRES_PERSONAL_ACCESS_CONNECTION + """ A Postgres instance was deleted """ POSTGRES_DELETED } extend type Mutation { + "Create a time-limited personal Postgres access through the API broker." + createPostgresAccess(input: CreatePostgresAccessInput!): CreatePostgresAccessPayload! "Grant temporary access to a Postgres cluster." grantPostgresAccess(input: GrantPostgresAccessInput!): GrantPostgresAccessPayload! "Delete an existing Postgres instance." deletePostgres(input: DeletePostgresInput!): DeletePostgresPayload! } +type CreatePostgresAccessPayload { + "Name of the newly created PostgresAccess resource." + name: String! + "Server-controlled expiry for this personal access." + expiresAt: Time! +} + +input CreatePostgresAccessInput { + postgresInstance: String! + teamSlug: Slug! + environmentName: String! + accessLevel: PostgresAccessLevel! + clientWireGuardPublicKey: String! +} + +enum PostgresAccessLevel { + READ + READWRITE + READWRITECREATE +} + type GrantPostgresAccessPayload { error: String } @@ -318,3 +386,75 @@ type TeamInventoryCountPostgresInstances { "Total number of Postgres instances." total: Int! } + +extend type Query { + "Get connection materials for a ready personal Postgres access owned by the caller." + postgresAccessConnection(input: PostgresAccessConnectionInput!): PostgresAccessConnectionPayload! + + "Get a personal PostgresAccess resource and its ready state." + postgresAccess( + "Name of the PostgresAccess resource." + name: String! + + "Team slug that owns the Postgres instance." + teamSlug: Slug! + + "Environment name that the Postgres instance belongs to." + environmentName: String! + ): PostgresAccess! +} + +type PostgresAccess implements Node { + id: ID! + name: String! + "Team that owns the access." + team: Team! + "Environment for the access." + teamEnvironment: TeamEnvironment! + "Postgres instance this access is for." + postgresInstance: PostgresInstance! + "Requested access level." + accessLevel: PostgresAccessLevel! + "Server-controlled expiry for this personal access." + expiresAt: Time! + "High-level state of the access." + state: PostgresAccessState! + "Human-readable message for the current state." + message: String + "Tunnel connection details, once the controller has created them." + tunnel: PostgresAccessTunnel +} + +enum PostgresAccessState { + PENDING + READY + FAILED + EXPIRED +} + +type PostgresAccessTunnel { + "Name of the Tunnel resource owned by this access." + name: String! + "Gateway endpoint the client should connect to." + endpoint: String + "Gateway's WireGuard public key." + gatewayPublicKey: String +} + +input PostgresAccessConnectionInput { + name: String! + teamSlug: Slug! + environmentName: String! +} + +type PostgresAccessConnectionPayload { + password: String! + caCertificate: String! + serverName: String! + tunnel: PostgresAccessConnectionTunnel! +} + +type PostgresAccessConnectionTunnel { + endpoint: String! + gatewayPublicKey: String! +} diff --git a/internal/persistence/postgres/activitylog.go b/internal/persistence/postgres/activitylog.go index 44371b3b6..986d8fcdf 100644 --- a/internal/persistence/postgres/activitylog.go +++ b/internal/persistence/postgres/activitylog.go @@ -8,7 +8,9 @@ import ( ) const ( - activityLogEntryActionGrantAccess activitylog.ActivityLogEntryAction = "GRANT_ACCESS" + activityLogEntryActionGrantAccess activitylog.ActivityLogEntryAction = "GRANT_ACCESS" + activityLogEntryActionCreatePersonalAccess activitylog.ActivityLogEntryAction = "CREATE_PERSONAL_ACCESS" + activityLogEntryActionGetPersonalAccessConnection activitylog.ActivityLogEntryAction = "GET_PERSONAL_ACCESS_CONNECTION" activityLogEntryResourceTypePostgres activitylog.ActivityLogEntryResourceType = "POSTGRES" ) @@ -35,12 +37,27 @@ func init() { GenericActivityLogEntry: entry.WithMessage(fmt.Sprintf("Granted access to %s until %s", data.Grantee, data.Until)), Data: data, }, nil + case activityLogEntryActionCreatePersonalAccess: + data, err := activitylog.UnmarshalData[PostgresPersonalAccessCreatedActivityLogEntryData](entry) + if err != nil { + return nil, fmt.Errorf("transforming postgres personal access activity log entry data: %w", err) + } + return PostgresPersonalAccessCreatedActivityLogEntry{ + GenericActivityLogEntry: entry.WithMessage(fmt.Sprintf("Created personal Postgres access for %s until %s", data.Username, data.ExpiresAt)), + Data: data, + }, nil + case activityLogEntryActionGetPersonalAccessConnection: + return PostgresPersonalAccessConnectionActivityLogEntry{ + GenericActivityLogEntry: entry.WithMessage("Retrieved personal Postgres connection materials"), + }, nil default: return nil, fmt.Errorf("unsupported postgres activity log entry action: %q", entry.Action) } }) activitylog.RegisterFilter("POSTGRES_GRANT_ACCESS", activityLogEntryActionGrantAccess, activityLogEntryResourceTypePostgres) + activitylog.RegisterFilter("POSTGRES_PERSONAL_ACCESS_CREATED", activityLogEntryActionCreatePersonalAccess, activityLogEntryResourceTypePostgres) + activitylog.RegisterFilter("POSTGRES_PERSONAL_ACCESS_CONNECTION", activityLogEntryActionGetPersonalAccessConnection, activityLogEntryResourceTypePostgres) activitylog.RegisterFilter("POSTGRES_DELETED", activitylog.ActivityLogEntryActionDeleted, activityLogEntryResourceTypePostgres) } @@ -58,3 +75,20 @@ type PostgresGrantAccessActivityLogEntryData struct { Grantee string `json:"grantee,string"` Until time.Time `json:"until"` } + +type PostgresPersonalAccessCreatedActivityLogEntry struct { + activitylog.GenericActivityLogEntry + + Data *PostgresPersonalAccessCreatedActivityLogEntryData `json:"data"` +} + +type PostgresPersonalAccessCreatedActivityLogEntryData struct { + Username string `json:"username"` + ExpiresAt time.Time `json:"expiresAt"` +} + +type PostgresPersonalAccessConnectionActivityLogEntry struct { + activitylog.GenericActivityLogEntry +} + +type PostgresPersonalAccessConnectionActivityLogEntryData struct{} diff --git a/internal/persistence/postgres/models.go b/internal/persistence/postgres/models.go index 2a6ea10fc..67a32bd92 100644 --- a/internal/persistence/postgres/models.go +++ b/internal/persistence/postgres/models.go @@ -236,6 +236,101 @@ type GrantPostgresAccessPayload struct { Error *string `json:"error,omitempty"` } +// CreatePostgresAccessInput requests a new, time-limited personal database access. +// The authenticated actor and access lifetime are deliberately not caller-controlled. +type CreatePostgresAccessInput struct { + PostgresInstance string `json:"postgresInstance"` + TeamSlug slug.Slug `json:"teamSlug"` + EnvironmentName string `json:"environmentName"` + AccessLevel PostgresAccessLevel `json:"accessLevel"` + ClientWireGuardPublicKey string `json:"clientWireGuardPublicKey"` +} + +func (i *CreatePostgresAccessInput) Validate(ctx context.Context) error { + return i.ValidationErrors(ctx).NilIfEmpty() +} + +func (i *CreatePostgresAccessInput) ValidationErrors(ctx context.Context) *validate.ValidationErrors { + verr := validate.New() + i.PostgresInstance = strings.TrimSpace(i.PostgresInstance) + i.EnvironmentName = strings.TrimSpace(i.EnvironmentName) + i.ClientWireGuardPublicKey = strings.TrimSpace(i.ClientWireGuardPublicKey) + + if i.PostgresInstance == "" { + verr.Add("postgresInstance", "Postgres instance must not be empty.") + } + if i.EnvironmentName == "" { + verr.Add("environmentName", "Environment name must not be empty.") + } + if i.TeamSlug == "" { + verr.Add("teamSlug", "Team slug must not be empty.") + } + if !i.AccessLevel.IsValid() { + verr.Add("accessLevel", "Access level %q is not valid.", i.AccessLevel) + } + if i.ClientWireGuardPublicKey == "" { + verr.Add("clientWireGuardPublicKey", "Client WireGuard public key must not be empty.") + } + + if i.PostgresInstance == "" || i.EnvironmentName == "" || i.TeamSlug == "" { + return verr + } + + instance, err := GetZalandoPostgres(ctx, i.TeamSlug, i.EnvironmentName, i.PostgresInstance) + if err != nil { + if errors.Is(err, &watcher.ErrorNotFound{}) { + verr.Add("postgresInstance", "Could not find postgres cluster named %q", i.PostgresInstance) + } else { + verr.Add("postgresInstance", "%s", err) + } + } else if instance.State != PostgresInstanceStateAvailable { + verr.Add("postgresInstance", "Postgres instance %q is not available.", i.PostgresInstance) + } + + return verr +} + +type CreatePostgresAccessPayload struct { + Name string `json:"name"` + ExpiresAt time.Time `json:"expiresAt"` +} + +type PostgresAccessLevel string + +const ( + PostgresAccessLevelRead PostgresAccessLevel = "READ" + PostgresAccessLevelReadWrite PostgresAccessLevel = "READWRITE" + PostgresAccessLevelReadWriteCreate PostgresAccessLevel = "READWRITECREATE" +) + +func (e PostgresAccessLevel) IsValid() bool { + switch e { + case PostgresAccessLevelRead, PostgresAccessLevelReadWrite, PostgresAccessLevelReadWriteCreate: + return true + } + return false +} + +func (e PostgresAccessLevel) String() string { return string(e) } + +func (e PostgresAccessLevel) CRDValue() string { return strings.ToLower(string(e)) } + +func (e *PostgresAccessLevel) UnmarshalGQL(v any) error { + str, ok := v.(string) + if !ok { + return fmt.Errorf("enums must be strings") + } + *e = PostgresAccessLevel(str) + if !e.IsValid() { + return fmt.Errorf("%s is not a valid PostgresAccessLevel", str) + } + return nil +} + +func (e PostgresAccessLevel) MarshalGQL(w io.Writer) { + fmt.Fprint(w, strconv.Quote(e.String())) +} + func (p *PostgresInstance) GetObjectKind() schema.ObjectKind { return schema.EmptyObjectKind } @@ -396,3 +491,128 @@ func (e PostgresInstanceOrderField) MarshalJSON() ([]byte, error) { type TeamInventoryCountPostgresInstances struct { Total int `json:"total"` } + +// PostgresAccess exposes the API/CLI-facing state of a controller-owned personal +// database access. Credentials are read from the controller-owned Secret on +// demand; they are never cached by the watcher. +type PostgresAccess struct { + Name string `json:"name"` + TeamSlug slug.Slug `json:"-"` + EnvironmentName string `json:"-"` + PostgresInstanceName string `json:"postgresInstance"` + Username string `json:"username"` + AccessLevel PostgresAccessLevel `json:"accessLevel"` + ExpiresAt time.Time `json:"expiresAt"` + State PostgresAccessState `json:"state"` + Message *string `json:"message,omitempty"` + Tunnel *PostgresAccessTunnel `json:"tunnel,omitempty"` +} + +func (PostgresAccess) IsNode() {} + +func (p *PostgresAccess) ID() ident.Ident { + return newAccessIdent(p.TeamSlug, p.EnvironmentName, p.Name) +} + +type PostgresAccessState string + +const ( + PostgresAccessStatePending PostgresAccessState = "PENDING" + PostgresAccessStateReady PostgresAccessState = "READY" + PostgresAccessStateFailed PostgresAccessState = "FAILED" + PostgresAccessStateExpired PostgresAccessState = "EXPIRED" +) + +var AllPostgresAccessState = []PostgresAccessState{ + PostgresAccessStatePending, + PostgresAccessStateReady, + PostgresAccessStateFailed, + PostgresAccessStateExpired, +} + +func (e PostgresAccessState) IsValid() bool { + switch e { + case PostgresAccessStatePending, PostgresAccessStateReady, PostgresAccessStateFailed, PostgresAccessStateExpired: + return true + } + return false +} + +func (e PostgresAccessState) String() string { + return string(e) +} + +func (e *PostgresAccessState) UnmarshalGQL(v any) error { + str, ok := v.(string) + if !ok { + return fmt.Errorf("enums must be strings") + } + + *e = PostgresAccessState(str) + if !e.IsValid() { + return fmt.Errorf("%s is not a valid PostgresAccessState", str) + } + return nil +} + +func (e PostgresAccessState) MarshalGQL(w io.Writer) { + fmt.Fprint(w, strconv.Quote(e.String())) +} + +func (e *PostgresAccessState) UnmarshalJSON(b []byte) error { + s, err := strconv.Unquote(string(b)) + if err != nil { + return err + } + return e.UnmarshalGQL(s) +} + +func (e PostgresAccessState) MarshalJSON() ([]byte, error) { + var buf bytes.Buffer + e.MarshalGQL(&buf) + return buf.Bytes(), nil +} + +type PostgresAccessTunnel struct { + Name string `json:"name"` + Endpoint *string `json:"endpoint,omitempty"` + GatewayPublicKey *string `json:"gatewayPublicKey,omitempty"` +} + +type PostgresAccessConnectionInput struct { + Name string `json:"name"` + TeamSlug slug.Slug `json:"teamSlug"` + EnvironmentName string `json:"environmentName"` +} + +func (i *PostgresAccessConnectionInput) Validate(ctx context.Context) error { + return i.ValidationErrors(ctx).NilIfEmpty() +} + +func (i *PostgresAccessConnectionInput) ValidationErrors(_ context.Context) *validate.ValidationErrors { + verr := validate.New() + i.Name = strings.TrimSpace(i.Name) + i.EnvironmentName = strings.TrimSpace(i.EnvironmentName) + if i.Name == "" { + verr.Add("name", "Name must not be empty.") + } + if i.TeamSlug == "" { + verr.Add("teamSlug", "Team slug must not be empty.") + } + if i.EnvironmentName == "" { + verr.Add("environmentName", "Environment name must not be empty.") + } + return verr +} + +type PostgresAccessConnectionPayload struct { + Password string `json:"password"` + CACertificate string `json:"caCertificate"` + ServerName string `json:"serverName"` + Tunnel PostgresAccessConnectionTunnel `json:"tunnel"` +} + +type PostgresAccessConnectionTunnel struct { + Endpoint string `json:"endpoint"` + GatewayPublicKey string `json:"gatewayPublicKey"` +} diff --git a/internal/persistence/postgres/node.go b/internal/persistence/postgres/node.go index 1c7a49ffb..a22572ae5 100644 --- a/internal/persistence/postgres/node.go +++ b/internal/persistence/postgres/node.go @@ -11,13 +11,15 @@ type identType int const ( identZalandoPostgres identType = iota + identPostgresAccess ) func init() { ident.RegisterIdentType(identZalandoPostgres, "PP", GetZalandoPostgresByIdent) + ident.RegisterIdentType(identPostgresAccess, "PA", GetPostgresAccessByIdent) } -func parseIdent(id ident.Ident) (teamSlug slug.Slug, environmentName, postgresInstanceName string, err error) { +func parsePostgresInstanceIdent(id ident.Ident) (teamSlug slug.Slug, environmentName, postgresInstanceName string, err error) { parts := id.Parts() if len(parts) != 3 { return "", "", "", fmt.Errorf("invalid ident") @@ -29,3 +31,16 @@ func parseIdent(id ident.Ident) (teamSlug slug.Slug, environmentName, postgresIn func newIdent(teamSlug slug.Slug, environmentName, postgresInstanceName string) ident.Ident { return ident.NewIdent(identZalandoPostgres, teamSlug.String(), environmentName, postgresInstanceName) } + +func parseAccessIdent(id ident.Ident) (teamSlug slug.Slug, environmentName, name string, err error) { + parts := id.Parts() + if len(parts) != 3 { + return "", "", "", fmt.Errorf("invalid ident") + } + + return slug.Slug(parts[0]), parts[1], parts[2], nil +} + +func newAccessIdent(teamSlug slug.Slug, environmentName, name string) ident.Ident { + return ident.NewIdent(identPostgresAccess, teamSlug.String(), environmentName, name) +} diff --git a/internal/persistence/postgres/queries.go b/internal/persistence/postgres/queries.go index a401c4376..316989765 100644 --- a/internal/persistence/postgres/queries.go +++ b/internal/persistence/postgres/queries.go @@ -8,10 +8,13 @@ import ( "net/url" "slices" "strconv" + "strings" "time" + "github.com/google/uuid" "github.com/nais/api/internal/activitylog" "github.com/nais/api/internal/auth/authz" + "github.com/nais/api/internal/graph/apierror" "github.com/nais/api/internal/graph/ident" "github.com/nais/api/internal/graph/model" "github.com/nais/api/internal/graph/pagination" @@ -22,9 +25,11 @@ import ( "github.com/nais/api/internal/workload" "github.com/nais/api/internal/workload/application" "github.com/nais/api/internal/workload/job" + corev1 "k8s.io/api/core/v1" k8serrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/client-go/dynamic" ) @@ -106,7 +111,7 @@ func CountForTeam(ctx context.Context, teamSlug slug.Slug) int { } func GetZalandoPostgresByIdent(ctx context.Context, id ident.Ident) (*PostgresInstance, error) { - teamSlug, environmentName, clusterName, err := parseIdent(id) + teamSlug, environmentName, clusterName, err := parsePostgresInstanceIdent(id) if err != nil { return nil, err } @@ -114,6 +119,284 @@ func GetZalandoPostgresByIdent(ctx context.Context, id ident.Ident) (*PostgresIn return GetZalandoPostgres(ctx, teamSlug, environmentName, clusterName) } +func GetPostgresAccessByIdent(ctx context.Context, id ident.Ident) (*PostgresAccess, error) { + teamSlug, environmentName, name, err := parseAccessIdent(id) + if err != nil { + return nil, err + } + + return GetPostgresAccess(ctx, name, teamSlug, environmentName) +} + +const ( + postgresAccessResource = "postgresaccesses" + postgresAccessGroup = "nais.io" +) + +// GetPostgresAccess returns a personal PostgresAccess status. Connection +// credentials are deliberately available only through GetPostgresAccessConnection. +func GetPostgresAccess(ctx context.Context, name string, teamSlug slug.Slug, environmentName string) (*PostgresAccess, error) { + if err := authz.CanReadPostgresAccess(ctx, teamSlug); err != nil { + return nil, err + } + + u, err := getPostgresAccessResource(ctx, name, teamSlug, environmentName) + if err != nil { + return nil, err + } + + access, err := toPostgresAccess(u, teamSlug, environmentName) + if err != nil { + return nil, err + } + + actor := authz.ActorFromContext(ctx) + if actor == nil || access.Username != actor.User.Identity() { + return nil, apierror.Errorf("PostgresAccess %q not found", name) + } + + return access, nil +} + +func GetPostgresAccessConnection(ctx context.Context, input PostgresAccessConnectionInput) (*PostgresAccessConnectionPayload, error) { + if err := input.Validate(ctx); err != nil { + return nil, err + } + if err := authz.CanReadPostgresAccess(ctx, input.TeamSlug); err != nil { + return nil, err + } + + access, err := getPostgresAccessResource(ctx, input.Name, input.TeamSlug, input.EnvironmentName) + if err != nil { + return nil, err + } + + username, _, err := unstructured.NestedString(access.Object, "spec", "username") + if err != nil { + return nil, fmt.Errorf("reading PostgresAccess %q username: %w", input.Name, err) + } + actor := authz.ActorFromContext(ctx) + if actor == nil || username == "" || actor.User.Identity() != username { + return nil, authz.ErrUnauthorized + } + + connection, credentialSecretName, err := postgresAccessConnectionDetails(access, time.Now()) + if err != nil { + return nil, err + } + + secretClient, err := fromContext(ctx).zalandoPostgresWatcher.SystemAuthenticatedClient(ctx, input.EnvironmentName, watcher.WithImpersonatedClientGVR(schema.GroupVersionResource{ + Version: "v1", + Resource: "secrets", + })) + if err != nil { + return nil, fmt.Errorf("creating credential Secret client: %w", err) + } + secret, err := secretClient.Namespace(input.TeamSlug.String()).Get(ctx, credentialSecretName, metav1.GetOptions{}) + if err != nil { + if k8serrors.IsNotFound(err) { + return nil, apierror.Errorf("credentials for PostgresAccess %q are not available", input.Name) + } + return nil, fmt.Errorf("getting credential Secret for PostgresAccess %q: %w", input.Name, err) + } + + password, caCertificate, err := postgresAccessConnectionSecret(secret) + if err != nil { + return nil, err + } + connection.Password = password + connection.CACertificate = caCertificate + + if err := activitylog.Create(ctx, activitylog.CreateInput{ + Action: activityLogEntryActionGetPersonalAccessConnection, + Actor: actor.User, + ResourceType: activityLogEntryResourceTypePostgres, + ResourceName: input.Name, + EnvironmentName: new(input.EnvironmentName), + TeamSlug: new(input.TeamSlug), + Data: PostgresPersonalAccessConnectionActivityLogEntryData{}, + }); err != nil { + return nil, err + } + + return connection, nil +} + +func getPostgresAccessResource(ctx context.Context, name string, teamSlug slug.Slug, environmentName string) (*unstructured.Unstructured, error) { + accessClient, err := fromContext(ctx).zalandoPostgresWatcher.SystemAuthenticatedClient(ctx, environmentName, watcher.WithImpersonatedClientGVR(schema.GroupVersionResource{ + Group: postgresAccessGroup, + Version: "v1", + Resource: postgresAccessResource, + })) + if err != nil { + return nil, fmt.Errorf("creating postgresaccess client: %w", err) + } + u, err := accessClient.Namespace(teamSlug.String()).Get(ctx, name, metav1.GetOptions{}) + if err != nil { + if k8serrors.IsNotFound(err) { + return nil, apierror.Errorf("PostgresAccess %q not found", name) + } + return nil, fmt.Errorf("getting PostgresAccess %q: %w", name, err) + } + return u, nil +} + +func postgresAccessConnectionDetails(access *unstructured.Unstructured, now time.Time) (*PostgresAccessConnectionPayload, string, error) { + expiresAt, _, err := unstructured.NestedString(access.Object, "spec", "expiresAt") + if err != nil { + return nil, "", fmt.Errorf("reading PostgresAccess %q expiry: %w", access.GetName(), err) + } + expires, err := time.Parse(time.RFC3339, expiresAt) + if err != nil { + return nil, "", apierror.Errorf("PostgresAccess %q has an invalid expiry", access.GetName()) + } + if !expires.After(now) { + return nil, "", apierror.Errorf("PostgresAccess %q has expired", access.GetName()) + } + if !postgresAccessIsReady(access.Object) { + return nil, "", apierror.Errorf("PostgresAccess %q is not ready", access.GetName()) + } + + credentialSecretName, _, err := unstructured.NestedString(access.Object, "status", "credentialSecretName") + if err != nil || credentialSecretName == "" { + return nil, "", apierror.Errorf("PostgresAccess %q is not ready", access.GetName()) + } + serverName, _, err := unstructured.NestedString(access.Object, "status", "serverName") + if err != nil || serverName == "" { + return nil, "", apierror.Errorf("PostgresAccess %q is not ready", access.GetName()) + } + endpoint, _, err := unstructured.NestedString(access.Object, "status", "tunnel", "endpoint") + if err != nil || endpoint == "" { + return nil, "", apierror.Errorf("PostgresAccess %q is not ready", access.GetName()) + } + gatewayPublicKey, _, err := unstructured.NestedString(access.Object, "status", "tunnel", "gatewayPublicKey") + if err != nil || gatewayPublicKey == "" { + return nil, "", apierror.Errorf("PostgresAccess %q is not ready", access.GetName()) + } + + return &PostgresAccessConnectionPayload{ + ServerName: serverName, + Tunnel: PostgresAccessConnectionTunnel{ + Endpoint: endpoint, GatewayPublicKey: gatewayPublicKey, + }, + }, credentialSecretName, nil +} + +func postgresAccessIsReady(obj map[string]any) bool { + conditions, found, err := unstructured.NestedSlice(obj, "status", "conditions") + if err != nil || !found { + return false + } + for _, c := range conditions { + condition, ok := c.(map[string]any) + if !ok { + continue + } + if condition["type"] == "Ready" && condition["status"] == string(metav1.ConditionTrue) { + return true + } + } + return false +} + +func postgresAccessConnectionSecret(secret *unstructured.Unstructured) (password, caCertificate string, err error) { + var typed corev1.Secret + if err := runtime.DefaultUnstructuredConverter.FromUnstructured(secret.Object, &typed); err != nil { + return "", "", fmt.Errorf("converting credential Secret %q: %w", secret.GetName(), err) + } + password = string(typed.Data[corev1.BasicAuthPasswordKey]) + caCertificate = string(typed.Data["ca.crt"]) + if password == "" || caCertificate == "" { + return "", "", apierror.Errorf("credentials for PostgresAccess are incomplete") + } + return password, caCertificate, nil +} + +func toPostgresAccess(u *unstructured.Unstructured, teamSlug slug.Slug, environmentName string) (*PostgresAccess, error) { + name := u.GetName() + postgresInstance, _, _ := unstructured.NestedString(u.Object, "spec", "postgresInstance") + username, _, _ := unstructured.NestedString(u.Object, "spec", "username") + levelStr, _, _ := unstructured.NestedString(u.Object, "spec", "accessLevel") + expiresStr, _, _ := unstructured.NestedString(u.Object, "spec", "expiresAt") + + expiresAt, err := time.Parse(time.RFC3339, expiresStr) + if err != nil { + return nil, fmt.Errorf("parsing expiresAt for PostgresAccess %q: %w", name, err) + } + + level := PostgresAccessLevel(strings.ToUpper(levelStr)) + if !level.IsValid() { + return nil, fmt.Errorf("invalid accessLevel %q for PostgresAccess %q", levelStr, name) + } + + state, message := postgresAccessState(u.Object, expiresAt) + + var tunnel *PostgresAccessTunnel + if t, ok, _ := unstructured.NestedStringMap(u.Object, "status", "tunnel"); ok && t["name"] != "" { + tunnel = &PostgresAccessTunnel{ + Name: t["name"], + Endpoint: strPtr(t["endpoint"]), + GatewayPublicKey: strPtr(t["gatewayPublicKey"]), + } + } + + return &PostgresAccess{ + Name: name, + TeamSlug: teamSlug, + EnvironmentName: environmentName, + PostgresInstanceName: postgresInstance, + Username: username, + AccessLevel: level, + ExpiresAt: expiresAt, + State: state, + Message: strPtr(message), + Tunnel: tunnel, + }, nil +} + +func strPtr(s string) *string { + if s == "" { + return nil + } + return &s +} + +func postgresAccessState(obj map[string]any, expiresAt time.Time) (PostgresAccessState, string) { + if !expiresAt.IsZero() && expiresAt.Before(time.Now()) { + return PostgresAccessStateExpired, "access has expired" + } + + conditions, found, err := unstructured.NestedSlice(obj, "status", "conditions") + if err != nil || !found { + return PostgresAccessStatePending, "waiting for controller" + } + + for _, c := range conditions { + condition, ok := c.(map[string]any) + if !ok { + continue + } + condType, _ := condition["type"].(string) + if condType != "Ready" { + continue + } + + status, _ := condition["status"].(string) + reason, _ := condition["reason"].(string) + message, _ := condition["message"].(string) + + if status == string(metav1.ConditionTrue) { + return PostgresAccessStateReady, message + } + if reason == "UnsupportedAccessLevel" { + return PostgresAccessStateFailed, message + } + return PostgresAccessStatePending, message + } + + return PostgresAccessStatePending, "waiting for controller" +} + func GetZalandoPostgres(ctx context.Context, teamSlug slug.Slug, environmentName string, clusterName string) (*PostgresInstance, error) { return fromContext(ctx).zalandoPostgresWatcher.Get(environmentName, teamSlug.String(), clusterName) } @@ -148,6 +431,67 @@ func GetAuditURL(ctx context.Context, audit *PostgresInstanceAudit) (*string, er return &logURL, nil } +const postgresAccessAPIVersion = "nais.io/v1" + +func CreatePostgresAccess(ctx context.Context, input CreatePostgresAccessInput) (*CreatePostgresAccessPayload, error) { + if err := input.Validate(ctx); err != nil { + return nil, err + } + + gvr := schema.GroupVersionResource{ + Group: "nais.io", + Version: "v1", + Resource: "postgresaccesses", + } + client, err := fromContext(ctx).zalandoPostgresWatcher.SystemAuthenticatedClient(ctx, input.EnvironmentName, watcher.WithImpersonatedClientGVR(gvr)) + if err != nil { + return nil, err + } + + expiresAt := time.Now().Add(time.Hour) + name := fmt.Sprintf("postgres-access-%s", uuid.NewString()[:8]) + res := newPostgresAccessResource(input, authz.ActorFromContext(ctx).User.Identity(), name, expiresAt) + + if _, err := client.Namespace(input.TeamSlug.String()).Create(ctx, res, metav1.CreateOptions{}); err != nil { + return nil, err + } + + if err := activitylog.Create(ctx, activitylog.CreateInput{ + Action: activityLogEntryActionCreatePersonalAccess, + Actor: authz.ActorFromContext(ctx).User, + ResourceType: activityLogEntryResourceTypePostgres, + ResourceName: input.PostgresInstance, + EnvironmentName: new(input.EnvironmentName), + TeamSlug: new(input.TeamSlug), + Data: PostgresPersonalAccessCreatedActivityLogEntryData{ + Username: authz.ActorFromContext(ctx).User.Identity(), + ExpiresAt: expiresAt, + }, + }); err != nil { + return nil, err + } + + return &CreatePostgresAccessPayload{Name: name, ExpiresAt: expiresAt}, nil +} + +func newPostgresAccessResource(input CreatePostgresAccessInput, username, name string, expiresAt time.Time) *unstructured.Unstructured { + res := &unstructured.Unstructured{} + res.SetAPIVersion(postgresAccessAPIVersion) + res.SetKind("PostgresAccess") + res.SetName(name) + res.SetNamespace(input.TeamSlug.String()) + res.SetAnnotations(kubernetes.WithCommonAnnotations(nil, username)) + kubernetes.SetManagedByConsoleLabel(res) + res.Object["spec"] = map[string]any{ + "postgresInstance": input.PostgresInstance, + "username": username, + "accessLevel": input.AccessLevel.CRDValue(), + "expiresAt": expiresAt.Format(time.RFC3339), + "clientWireGuardPublicKey": input.ClientWireGuardPublicKey, + } + return res +} + func GrantZalandoPostgresAccess(ctx context.Context, input GrantPostgresAccessInput) error { err := input.Validate(ctx) if err != nil { diff --git a/internal/persistence/postgres/queries_test.go b/internal/persistence/postgres/queries_test.go new file mode 100644 index 000000000..c7cfbb43a --- /dev/null +++ b/internal/persistence/postgres/queries_test.go @@ -0,0 +1,224 @@ +package postgres + +import ( + "reflect" + "strings" + "testing" + "time" + + "github.com/nais/api/internal/slug" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" +) + +func TestNewPostgresAccessResource(t *testing.T) { + expiresAt := time.Date(2026, time.September, 17, 12, 0, 0, 0, time.UTC) + resource := newPostgresAccessResource(CreatePostgresAccessInput{ + PostgresInstance: "orders", + TeamSlug: slug.Slug("team-a"), + EnvironmentName: "dev", + AccessLevel: PostgresAccessLevelReadWrite, + ClientWireGuardPublicKey: "client-public-key", + }, "user@example.com", "postgres-access-12345678", expiresAt) + + if got, want := resource.GetAPIVersion(), "nais.io/v1"; got != want { + t.Errorf("apiVersion = %q, want %q", got, want) + } + if got, want := resource.GetKind(), "PostgresAccess"; got != want { + t.Errorf("kind = %q, want %q", got, want) + } + if got, want := resource.GetName(), "postgres-access-12345678"; got != want { + t.Errorf("name = %q, want %q", got, want) + } + if got, want := resource.GetNamespace(), "team-a"; got != want { + t.Errorf("namespace = %q, want %q", got, want) + } + + spec, found, err := unstructured.NestedMap(resource.Object, "spec") + if err != nil || !found { + t.Fatalf("spec = (%v, %t, %v), want a spec", spec, found, err) + } + wantSpec := map[string]any{ + "postgresInstance": "orders", + "username": "user@example.com", + "accessLevel": "readwrite", + "expiresAt": "2026-09-17T12:00:00Z", + "clientWireGuardPublicKey": "client-public-key", + } + if !reflect.DeepEqual(wantSpec, spec) { + t.Errorf("spec = %#v, want %#v", spec, wantSpec) + } +} + +func TestPostgresAccessState(t *testing.T) { + future := time.Now().Add(time.Hour) + past := time.Now().Add(-time.Hour) + + tests := []struct { + name string + expiresAt time.Time + status map[string]any + wantState PostgresAccessState + wantMsg string + }{ + { + name: "expired", + expiresAt: past, + wantState: PostgresAccessStateExpired, + wantMsg: "access has expired", + }, + { + name: "pending without status", + expiresAt: future, + wantState: PostgresAccessStatePending, + wantMsg: "waiting for controller", + }, + { + name: "ready", + expiresAt: future, + status: map[string]any{ + "conditions": []any{ + map[string]any{ + "type": "Ready", + "status": "True", + "message": "Database role and tunnel are ready", + }, + }, + }, + wantState: PostgresAccessStateReady, + wantMsg: "Database role and tunnel are ready", + }, + { + name: "failed unsupported access level", + expiresAt: future, + status: map[string]any{ + "conditions": []any{ + map[string]any{ + "type": "Ready", + "status": "False", + "reason": "UnsupportedAccessLevel", + "message": "readwritecreate requires an instance initialized with the app_readwritecreate group role", + }, + }, + }, + wantState: PostgresAccessStateFailed, + wantMsg: "readwritecreate requires an instance initialized with the app_readwritecreate group role", + }, + { + name: "pending waiting on tunnel", + expiresAt: future, + status: map[string]any{ + "conditions": []any{ + map[string]any{ + "type": "Ready", + "status": "False", + "message": "waiting for tunnel", + }, + }, + }, + wantState: PostgresAccessStatePending, + wantMsg: "waiting for tunnel", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + obj := map[string]any{} + if tt.status != nil { + obj["status"] = tt.status + } + gotState, gotMsg := postgresAccessState(obj, tt.expiresAt) + if gotState != tt.wantState { + t.Errorf("state = %q, want %q", gotState, tt.wantState) + } + if gotMsg != tt.wantMsg { + t.Errorf("message = %q, want %q", gotMsg, tt.wantMsg) + } + }) + } +} + +func TestPostgresAccessConnectionDetails(t *testing.T) { + now := time.Date(2026, time.September, 17, 12, 0, 0, 0, time.UTC) + ready := func() *unstructured.Unstructured { + return &unstructured.Unstructured{Object: map[string]any{ + "metadata": map[string]any{"name": "access"}, + "spec": map[string]any{"expiresAt": "2026-09-17T13:00:00Z"}, + "status": map[string]any{ + "credentialSecretName": "access-credentials", + "serverName": "postgres.example", + "conditions": []any{map[string]any{"type": "Ready", "status": "True"}}, + "tunnel": map[string]any{"endpoint": "endpoint:1234", "gatewayPublicKey": "gateway-key"}, + }, + }} + } + + tests := []struct { + name string + edit func(*unstructured.Unstructured) + want string + }{ + {name: "ready"}, + {name: "expired", edit: func(u *unstructured.Unstructured) { + _ = unstructured.SetNestedField(u.Object, "2026-09-17T12:00:00Z", "spec", "expiresAt") + }, want: "expired"}, + {name: "not ready", edit: func(u *unstructured.Unstructured) { + _ = unstructured.SetNestedField(u.Object, []any{map[string]any{"type": "Ready", "status": "False"}}, "status", "conditions") + }, want: "not ready"}, + {name: "missing secret name", edit: func(u *unstructured.Unstructured) { + unstructured.RemoveNestedField(u.Object, "status", "credentialSecretName") + }, want: "not ready"}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + u := ready() + if tt.edit != nil { + tt.edit(u) + } + got, secretName, err := postgresAccessConnectionDetails(u, now) + if tt.want != "" { + if err == nil || !strings.Contains(err.Error(), tt.want) { + t.Fatalf("error = %v, want %q", err, tt.want) + } + return + } + if err != nil { + t.Fatalf("postgresAccessConnectionDetails: %v", err) + } + if secretName != "access-credentials" { + t.Errorf("secret name = %q", secretName) + } + if got.ServerName != "postgres.example" || got.Tunnel.Endpoint != "endpoint:1234" || got.Tunnel.GatewayPublicKey != "gateway-key" { + t.Errorf("connection = %#v", got) + } + }) + } +} + +func TestPostgresAccessConnectionSecret(t *testing.T) { + secret := &corev1.Secret{Data: map[string][]byte{ + corev1.BasicAuthPasswordKey: []byte("supersecret"), + "ca.crt": []byte("test-ca-certificate"), + }} + u, err := runtime.DefaultUnstructuredConverter.ToUnstructured(secret) + if err != nil { + t.Fatalf("ToUnstructured: %v", err) + } + password, ca, err := postgresAccessConnectionSecret(&unstructured.Unstructured{Object: u}) + if err != nil { + t.Fatalf("postgresAccessConnectionSecret: %v", err) + } + if password != "supersecret" || ca != "test-ca-certificate" { + t.Errorf("got password=%q ca=%q", password, ca) + } + + delete(secret.Data, "ca.crt") + u, err = runtime.DefaultUnstructuredConverter.ToUnstructured(secret) + if err != nil { + t.Fatalf("ToUnstructured: %v", err) + } + if _, _, err := postgresAccessConnectionSecret(&unstructured.Unstructured{Object: u}); err == nil { + t.Fatal("missing ca.crt did not fail") + } +} From 7faef84f8974e90216e838c4246bb241d5f27f80 Mon Sep 17 00:00:00 2001 From: Johnny Fredheim Horvi Date: Thu, 17 Sep 2026 14:51:07 +0200 Subject: [PATCH 02/19] fix: add reason --- integration_tests/create_postgres_access.lua | 35 ++++++++++++++++++ internal/graph/gengql/postgres.generated.go | 37 +++++++++++++++++++- internal/graph/gengql/root_.generated.go | 13 +++++++ internal/graph/schema/postgres.graphqls | 3 ++ internal/persistence/postgres/activitylog.go | 1 + internal/persistence/postgres/models.go | 5 +++ internal/persistence/postgres/queries.go | 1 + 7 files changed, 94 insertions(+), 1 deletion(-) diff --git a/integration_tests/create_postgres_access.lua b/integration_tests/create_postgres_access.lua index 181113683..0aa5d3c41 100644 --- a/integration_tests/create_postgres_access.lua +++ b/integration_tests/create_postgres_access.lua @@ -18,6 +18,7 @@ Test.gql("Create personal postgres access without authorization", function(t) teamSlug: "someteamname" accessLevel: READ clientWireGuardPublicKey: "client-public-key" + reason: "Testing personal database access" }) { name expiresAt @@ -37,6 +38,35 @@ Test.gql("Create personal postgres access without authorization", function(t) } end) +Test.gql("Create personal postgres access requires an audit reason", function(t) + t.addHeader("x-user-email", user:email()) + t.query [[ + mutation CreatePostgresAccess { + createPostgresAccess(input: { + postgresInstance: "foobar" + environmentName: "dev" + teamSlug: "someteamname" + accessLevel: READ + clientWireGuardPublicKey: "client-public-key" + reason: "short" + }) { + name + } + } + ]] + + t.check { + errors = { + { + extensions = { field = "reason" }, + message = Contains("Reason must be at least 10 characters"), + path = { "createPostgresAccess" }, + }, + }, + data = Null, + } +end) + Test.gql("Create personal postgres access rejects an unknown instance", function(t) t.addHeader("x-user-email", user:email()) t.query [[ @@ -47,6 +77,7 @@ Test.gql("Create personal postgres access rejects an unknown instance", function teamSlug: "someteamname" accessLevel: READ clientWireGuardPublicKey: "client-public-key" + reason: "Testing personal database access" }) { name expiresAt @@ -76,6 +107,7 @@ Test.gql("Create personal postgres access rejects an unavailable instance", func teamSlug: "someteamname" accessLevel: READ clientWireGuardPublicKey: "client-public-key" + reason: "Testing personal database access" }) { name expiresAt @@ -105,6 +137,7 @@ Test.gql("Create personal postgres access", function(t) teamSlug: "someteamname" accessLevel: READWRITE clientWireGuardPublicKey: "client-public-key" + reason: "Testing personal database access" }) { name expiresAt @@ -134,6 +167,7 @@ Test.gql("Personal postgres access is audited as a self-grant", function(t) data { username expiresAt + reason } } } @@ -152,6 +186,7 @@ Test.gql("Personal postgres access is audited as a self-grant", function(t) data = { username = "user@usersen.com", expiresAt = NotNull(), + reason = "Testing personal database access", }, }, }, diff --git a/internal/graph/gengql/postgres.generated.go b/internal/graph/gengql/postgres.generated.go index e19af967d..da3af728f 100644 --- a/internal/graph/gengql/postgres.generated.go +++ b/internal/graph/gengql/postgres.generated.go @@ -2481,6 +2481,29 @@ func (ec *executionContext) fieldContext_PostgresPersonalAccessCreatedActivityLo return graphql.NewScalarFieldContext("PostgresPersonalAccessCreatedActivityLogEntryData", field, false, false, errors.New("field of type Time does not have child fields")) } +func (ec *executionContext) _PostgresPersonalAccessCreatedActivityLogEntryData_reason(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresPersonalAccessCreatedActivityLogEntryData) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_PostgresPersonalAccessCreatedActivityLogEntryData_reason(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Reason, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { + return ec.marshalNString2string(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_PostgresPersonalAccessCreatedActivityLogEntryData_reason(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresPersonalAccessCreatedActivityLogEntryData", field, false, false, errors.New("field of type String does not have child fields")) +} + func (ec *executionContext) _TeamInventoryCountPostgresInstances_total(ctx context.Context, field graphql.CollectedField, obj *postgres.TeamInventoryCountPostgresInstances) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -2519,7 +2542,7 @@ func (ec *executionContext) unmarshalInputCreatePostgresAccessInput(ctx context. asMap[k] = v } - fieldsInOrder := [...]string{"postgresInstance", "teamSlug", "environmentName", "accessLevel", "clientWireGuardPublicKey"} + fieldsInOrder := [...]string{"postgresInstance", "teamSlug", "environmentName", "accessLevel", "clientWireGuardPublicKey", "reason"} for _, k := range fieldsInOrder { v, ok := asMap[k] if !ok { @@ -2561,6 +2584,13 @@ func (ec *executionContext) unmarshalInputCreatePostgresAccessInput(ctx context. return it, err } it.ClientWireGuardPublicKey = data + case "reason": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("reason")) + data, err := ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + it.Reason = data } } return it, nil @@ -4344,6 +4374,11 @@ func (ec *executionContext) _PostgresPersonalAccessCreatedActivityLogEntryData(c if out.Values[i] == graphql.Null { out.Invalids++ } + case "reason": + out.Values[i] = ec._PostgresPersonalAccessCreatedActivityLogEntryData_reason(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } default: panic("unknown field " + strconv.Quote(field.Name)) } diff --git a/internal/graph/gengql/root_.generated.go b/internal/graph/gengql/root_.generated.go index f7039e068..afe29cf6f 100644 --- a/internal/graph/gengql/root_.generated.go +++ b/internal/graph/gengql/root_.generated.go @@ -2000,6 +2000,7 @@ type ComplexityRoot struct { PostgresPersonalAccessCreatedActivityLogEntryData struct { ExpiresAt func(childComplexity int) int + Reason func(childComplexity int) int Username func(childComplexity int) int } @@ -11957,6 +11958,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.PostgresPersonalAccessCreatedActivityLogEntryData.ExpiresAt(childComplexity), true + case "PostgresPersonalAccessCreatedActivityLogEntryData.reason": + if e.ComplexityRoot.PostgresPersonalAccessCreatedActivityLogEntryData.Reason == nil { + break + } + + return e.ComplexityRoot.PostgresPersonalAccessCreatedActivityLogEntryData.Reason(childComplexity), true + case "PostgresPersonalAccessCreatedActivityLogEntryData.username": if e.ComplexityRoot.PostgresPersonalAccessCreatedActivityLogEntryData.Username == nil { break @@ -26953,6 +26961,7 @@ type PostgresPersonalAccessCreatedActivityLogEntry implements ActivityLogEntry & type PostgresPersonalAccessCreatedActivityLogEntryData { username: String! expiresAt: Time! + reason: String! } type PostgresPersonalAccessConnectionActivityLogEntry implements ActivityLogEntry & Node { @@ -27033,6 +27042,8 @@ input CreatePostgresAccessInput { environmentName: String! accessLevel: PostgresAccessLevel! clientWireGuardPublicKey: String! + "Reason for personal database access. Must be at least 10 characters." + reason: String! } enum PostgresAccessLevel { @@ -37007,6 +37018,8 @@ func (ec *executionContext) childFields_PostgresPersonalAccessCreatedActivityLog return ec.fieldContext_PostgresPersonalAccessCreatedActivityLogEntryData_username(ctx, field) case "expiresAt": return ec.fieldContext_PostgresPersonalAccessCreatedActivityLogEntryData_expiresAt(ctx, field) + case "reason": + return ec.fieldContext_PostgresPersonalAccessCreatedActivityLogEntryData_reason(ctx, field) } return nil, fmt.Errorf("no field named %q was found under type PostgresPersonalAccessCreatedActivityLogEntryData", field.Name) } diff --git a/internal/graph/schema/postgres.graphqls b/internal/graph/schema/postgres.graphqls index 35ea313a0..357727fa2 100644 --- a/internal/graph/schema/postgres.graphqls +++ b/internal/graph/schema/postgres.graphqls @@ -263,6 +263,7 @@ type PostgresPersonalAccessCreatedActivityLogEntry implements ActivityLogEntry & type PostgresPersonalAccessCreatedActivityLogEntryData { username: String! expiresAt: Time! + reason: String! } type PostgresPersonalAccessConnectionActivityLogEntry implements ActivityLogEntry & Node { @@ -343,6 +344,8 @@ input CreatePostgresAccessInput { environmentName: String! accessLevel: PostgresAccessLevel! clientWireGuardPublicKey: String! + "Reason for personal database access. Must be at least 10 characters." + reason: String! } enum PostgresAccessLevel { diff --git a/internal/persistence/postgres/activitylog.go b/internal/persistence/postgres/activitylog.go index 986d8fcdf..0d4b9e21c 100644 --- a/internal/persistence/postgres/activitylog.go +++ b/internal/persistence/postgres/activitylog.go @@ -85,6 +85,7 @@ type PostgresPersonalAccessCreatedActivityLogEntry struct { type PostgresPersonalAccessCreatedActivityLogEntryData struct { Username string `json:"username"` ExpiresAt time.Time `json:"expiresAt"` + Reason string `json:"reason"` } type PostgresPersonalAccessConnectionActivityLogEntry struct { diff --git a/internal/persistence/postgres/models.go b/internal/persistence/postgres/models.go index 67a32bd92..d5e8f2f46 100644 --- a/internal/persistence/postgres/models.go +++ b/internal/persistence/postgres/models.go @@ -244,6 +244,7 @@ type CreatePostgresAccessInput struct { EnvironmentName string `json:"environmentName"` AccessLevel PostgresAccessLevel `json:"accessLevel"` ClientWireGuardPublicKey string `json:"clientWireGuardPublicKey"` + Reason string `json:"reason"` } func (i *CreatePostgresAccessInput) Validate(ctx context.Context) error { @@ -255,6 +256,7 @@ func (i *CreatePostgresAccessInput) ValidationErrors(ctx context.Context) *valid i.PostgresInstance = strings.TrimSpace(i.PostgresInstance) i.EnvironmentName = strings.TrimSpace(i.EnvironmentName) i.ClientWireGuardPublicKey = strings.TrimSpace(i.ClientWireGuardPublicKey) + i.Reason = strings.TrimSpace(i.Reason) if i.PostgresInstance == "" { verr.Add("postgresInstance", "Postgres instance must not be empty.") @@ -271,6 +273,9 @@ func (i *CreatePostgresAccessInput) ValidationErrors(ctx context.Context) *valid if i.ClientWireGuardPublicKey == "" { verr.Add("clientWireGuardPublicKey", "Client WireGuard public key must not be empty.") } + if len(i.Reason) < 10 { + verr.Add("reason", "Reason must be at least 10 characters.") + } if i.PostgresInstance == "" || i.EnvironmentName == "" || i.TeamSlug == "" { return verr diff --git a/internal/persistence/postgres/queries.go b/internal/persistence/postgres/queries.go index 316989765..961591c76 100644 --- a/internal/persistence/postgres/queries.go +++ b/internal/persistence/postgres/queries.go @@ -466,6 +466,7 @@ func CreatePostgresAccess(ctx context.Context, input CreatePostgresAccessInput) Data: PostgresPersonalAccessCreatedActivityLogEntryData{ Username: authz.ActorFromContext(ctx).User.Identity(), ExpiresAt: expiresAt, + Reason: input.Reason, }, }); err != nil { return nil, err From ff4b3d6a23b492485dc1f9cc9ecfd18da0a64f13 Mon Sep 17 00:00:00 2001 From: Johnny Fredheim Horvi Date: Thu, 17 Sep 2026 15:05:06 +0200 Subject: [PATCH 03/19] refactor(postgres): address personal access review comments --- internal/auth/authz/queries.go | 4 - internal/cmd/api/api.go | 2 +- internal/cmd/api/http.go | 4 +- ...add_postgres_access_read_authorization.sql | 29 ---- internal/graph/postgres.resolvers.go | 6 +- internal/grpc/grpc.go | 4 +- internal/grpc/grpcdatabase/server.go | 12 +- internal/grpc/grpcdatabase/server_test.go | 4 +- internal/kubernetes/watchers/watchers.go | 124 +++++++++--------- internal/persistence/postgres/dataloader.go | 20 +-- internal/persistence/postgres/models.go | 4 +- internal/persistence/postgres/node.go | 6 +- internal/persistence/postgres/queries.go | 34 ++--- internal/persistence/postgres/search.go | 4 +- 14 files changed, 112 insertions(+), 145 deletions(-) delete mode 100644 internal/database/migrations/0075_add_postgres_access_read_authorization.sql diff --git a/internal/auth/authz/queries.go b/internal/auth/authz/queries.go index 55bc53d5f..e9df53b29 100644 --- a/internal/auth/authz/queries.go +++ b/internal/auth/authz/queries.go @@ -312,10 +312,6 @@ func CanDeleteOpenSearch(ctx context.Context, teamSlug slug.Slug) error { return requireTeamAuthorization(ctx, teamSlug, "opensearches:delete") } -func CanReadPostgresAccess(ctx context.Context, teamSlug slug.Slug) error { - return requireStrictTeamAuthorization(ctx, teamSlug, "postgres:access:read") -} - func CanGrantPostgresAccess(ctx context.Context, teamSlug slug.Slug) error { return requireStrictTeamAuthorization(ctx, teamSlug, "postgres:access:grant") } diff --git a/internal/cmd/api/api.go b/internal/cmd/api/api.go index 2b5bec209..0735961f5 100644 --- a/internal/cmd/api/api.go +++ b/internal/cmd/api/api.go @@ -393,7 +393,7 @@ func run(ctx context.Context, cfg *Config, log logrus.FieldLogger) error { }) wg.Go(func() error { - if err := grpc.Run(ctx, cfg.GRPCListenAddress, pool, watchers.SqlDatabaseWatcher, watchers.ZalandoPostgresWatcher, log.WithField("subsystem", "grpc")); err != nil { + if err := grpc.Run(ctx, cfg.GRPCListenAddress, pool, watchers.SqlDatabaseWatcher, watchers.PostgresWatcher, log.WithField("subsystem", "grpc")); err != nil { log.WithError(err).Errorf("error in GRPC server") return err } diff --git a/internal/cmd/api/http.go b/internal/cmd/api/http.go index bb41fe3b9..8e9d396b2 100644 --- a/internal/cmd/api/http.go +++ b/internal/cmd/api/http.go @@ -232,7 +232,7 @@ func ConfigureGraph( kafkatopic.AddSearch(searcher, watchers.KafkaTopicWatcher) opensearch.AddSearch(searcher, watchers.OpenSearchWatcher) sqlinstance.AddSearchSQLInstance(searcher, watchers.SqlInstanceWatcher) - postgres.AddSearchZalandoPostgres(searcher, watchers.ZalandoPostgresWatcher) + postgres.AddSearchPostgres(searcher, watchers.PostgresWatcher) valkey.AddSearch(searcher, watchers.ValkeyWatcher) team.AddSearch(searcher, pool, notifier, log.WithField("subsystem", "team_search")) return nil @@ -355,7 +355,7 @@ func ConfigureGraph( ctx = alerts.NewLoaderContext(ctx, prometheusClient, log) ctx = metrics.NewLoaderContext(ctx, prometheusClient, log) ctx = sqlinstance.NewLoaderContext(ctx, sqlAdminService, watchers.SqlDatabaseWatcher, watchers.SqlInstanceWatcher, auditLogProjectID, auditLogLocation) - ctx = postgres.NewLoaderContext(ctx, watchers.ZalandoPostgresWatcher, auditLogProjectID, auditLogLocation) + ctx = postgres.NewLoaderContext(ctx, watchers.PostgresWatcher, auditLogProjectID, auditLogLocation) ctx = aivencredentials.NewClientContext(ctx, dynamicClients, log) ctx = database.NewLoaderContext(ctx, pool) ctx = issue.NewContext(ctx, pool) diff --git a/internal/database/migrations/0075_add_postgres_access_read_authorization.sql b/internal/database/migrations/0075_add_postgres_access_read_authorization.sql deleted file mode 100644 index 18a2aa221..000000000 --- a/internal/database/migrations/0075_add_postgres_access_read_authorization.sql +++ /dev/null @@ -1,29 +0,0 @@ --- +goose Up -INSERT INTO - authorizations (name, description) -VALUES - ( - 'postgres:access:read', - 'Permission to read personal Postgres access status and credentials' - ) -ON CONFLICT (name) DO NOTHING -; - -INSERT INTO - role_authorizations (role_name, authorization_name) -VALUES - ('Team member', 'postgres:access:read'), - ('Team owner', 'postgres:access:read') -ON CONFLICT (role_name, authorization_name) DO NOTHING -; - --- +goose Down -DELETE FROM role_authorizations -WHERE - authorization_name = 'postgres:access:read' -; - -DELETE FROM authorizations -WHERE - name = 'postgres:access:read' -; diff --git a/internal/graph/postgres.resolvers.go b/internal/graph/postgres.resolvers.go index 004235484..886a89351 100644 --- a/internal/graph/postgres.resolvers.go +++ b/internal/graph/postgres.resolvers.go @@ -63,7 +63,7 @@ func (r *mutationResolver) GrantPostgresAccess(ctx context.Context, input postgr return nil, err } - if err := postgres.GrantZalandoPostgresAccess(ctx, input); err != nil { + if err := postgres.GrantPostgresAccess(ctx, input); err != nil { return nil, err } @@ -88,7 +88,7 @@ func (r *postgresAccessResolver) TeamEnvironment(ctx context.Context, obj *postg } func (r *postgresAccessResolver) PostgresInstance(ctx context.Context, obj *postgres.PostgresAccess) (*postgres.PostgresInstance, error) { - return postgres.GetZalandoPostgres(ctx, obj.TeamSlug, obj.EnvironmentName, obj.PostgresInstanceName) + return postgres.GetPostgres(ctx, obj.TeamSlug, obj.EnvironmentName, obj.PostgresInstanceName) } func (r *postgresInstanceResolver) Team(ctx context.Context, obj *postgres.PostgresInstance) (*team.Team, error) { @@ -139,7 +139,7 @@ func (r *teamResolver) PostgresInstances(ctx context.Context, obj *team.Team, fi } func (r *teamEnvironmentResolver) PostgresInstance(ctx context.Context, obj *team.TeamEnvironment, name string) (*postgres.PostgresInstance, error) { - return postgres.GetZalandoPostgres(ctx, obj.TeamSlug, obj.EnvironmentName, name) + return postgres.GetPostgres(ctx, obj.TeamSlug, obj.EnvironmentName, name) } func (r *teamInventoryCountsResolver) PostgresInstances(ctx context.Context, obj *team.TeamInventoryCounts) (*postgres.TeamInventoryCountPostgresInstances, error) { diff --git a/internal/grpc/grpc.go b/internal/grpc/grpc.go index 132362244..566a61bf9 100644 --- a/internal/grpc/grpc.go +++ b/internal/grpc/grpc.go @@ -20,7 +20,7 @@ import ( "google.golang.org/grpc" ) -func Run(ctx context.Context, listenAddress string, pool *pgxpool.Pool, sqlDatabaseWatcher *watchers.SqlDatabaseWatcher, zalandoPostgresWatcher *watchers.ZalandoPostgresWatcher, log logrus.FieldLogger) error { +func Run(ctx context.Context, listenAddress string, pool *pgxpool.Pool, sqlDatabaseWatcher *watchers.SqlDatabaseWatcher, postgresWatcher *watchers.PostgresWatcher, log logrus.FieldLogger) error { log.Info("GRPC serving on ", listenAddress) lis, err := net.Listen("tcp", listenAddress) if err != nil { @@ -36,7 +36,7 @@ func Run(ctx context.Context, listenAddress string, pool *pgxpool.Pool, sqlDatab protoapi.RegisterUsersServer(s, grpcuser.NewServer(pool)) protoapi.RegisterReconcilersServer(s, grpcreconciler.NewServer(pool)) protoapi.RegisterDeploymentsServer(s, grpcdeployment.NewServer(pool)) - protoapi.RegisterDatabasesServer(s, grpcdatabase.NewServer(sqlDatabaseWatcher, zalandoPostgresWatcher)) + protoapi.RegisterDatabasesServer(s, grpcdatabase.NewServer(sqlDatabaseWatcher, postgresWatcher)) g, ctx := errgroup.WithContext(ctx) g.Go(func() error { return s.Serve(lis) }) diff --git a/internal/grpc/grpcdatabase/server.go b/internal/grpc/grpcdatabase/server.go index c70509d92..e7ac9de59 100644 --- a/internal/grpc/grpcdatabase/server.go +++ b/internal/grpc/grpcdatabase/server.go @@ -14,21 +14,21 @@ import ( ) type Server struct { - sqlDatabaseWatcher *watchers.SqlDatabaseWatcher - zalandoPostgresWatcher *watchers.ZalandoPostgresWatcher + sqlDatabaseWatcher *watchers.SqlDatabaseWatcher + postgresWatcher *watchers.PostgresWatcher protoapi.UnimplementedDatabasesServer } -func NewServer(sqlDatabaseWatcher *watchers.SqlDatabaseWatcher, zalandoPostgresWatcher *watchers.ZalandoPostgresWatcher) *Server { +func NewServer(sqlDatabaseWatcher *watchers.SqlDatabaseWatcher, postgresWatcher *watchers.PostgresWatcher) *Server { return &Server{ - sqlDatabaseWatcher: sqlDatabaseWatcher, - zalandoPostgresWatcher: zalandoPostgresWatcher, + sqlDatabaseWatcher: sqlDatabaseWatcher, + postgresWatcher: postgresWatcher, } } func (s *Server) List(_ context.Context, r *protoapi.ListDatabasesRequest) (*protoapi.ListDatabasesResponse, error) { sqlDatabases := watcher.Objects(s.sqlDatabaseWatcher.GetByNamespace(r.TeamSlug)) - postgresInstances := watcher.Objects(s.zalandoPostgresWatcher.GetByNamespace(r.TeamSlug)) + postgresInstances := watcher.Objects(s.postgresWatcher.GetByNamespace(r.TeamSlug)) all := make([]*protoapi.Database, 0, len(sqlDatabases)+len(postgresInstances)) for _, d := range sqlDatabases { diff --git a/internal/grpc/grpcdatabase/server_test.go b/internal/grpc/grpcdatabase/server_test.go index ffd895629..a1c6c2700 100644 --- a/internal/grpc/grpcdatabase/server_test.go +++ b/internal/grpc/grpcdatabase/server_test.go @@ -203,7 +203,7 @@ func newServer(t *testing.T, ctx context.Context) *grpcdatabase.Server { t.Cleanup(mgr.Stop) sqlDatabaseWatcher := sqlinstance.NewDatabaseWatcher(ctx, mgr) - zalandoPostgresWatcher := postgres.NewZalandoPostgresWatcher(ctx, mgr) + postgresWatcher := postgres.NewPostgresWatcher(ctx, mgr) ctxWait, cancel := context.WithTimeout(ctx, 5*time.Second) defer cancel() @@ -213,6 +213,6 @@ func newServer(t *testing.T, ctx context.Context) *grpcdatabase.Server { return grpcdatabase.NewServer( (*watchers.SqlDatabaseWatcher)(sqlDatabaseWatcher), - (*watchers.ZalandoPostgresWatcher)(zalandoPostgresWatcher), + (*watchers.PostgresWatcher)(postgresWatcher), ) } diff --git a/internal/kubernetes/watchers/watchers.go b/internal/kubernetes/watchers/watchers.go index e1655ee26..d93fcc555 100644 --- a/internal/kubernetes/watchers/watchers.go +++ b/internal/kubernetes/watchers/watchers.go @@ -29,51 +29,51 @@ import ( ) type ( - AppWatcher = watcher.Watcher[*nais_io_v1alpha1.Application] - JobWatcher = watcher.Watcher[*nais_io_v1.Naisjob] - RunWatcher = watcher.Watcher[*batchv1.Job] - BqWatcher = watcher.Watcher[*bigquery.BigQueryDataset] - ValkeyWatcher = watcher.Watcher[*valkey.Valkey] - OpenSearchWatcher = watcher.Watcher[*opensearch.OpenSearch] - NaisOpenSearchWatcher = watcher.Watcher[*opensearch.OpenSearch] - BucketWatcher = watcher.Watcher[*bucket.Bucket] - SqlDatabaseWatcher = watcher.Watcher[*sqlinstance.SQLDatabase] - SqlInstanceWatcher = watcher.Watcher[*sqlinstance.SQLInstance] - ZalandoPostgresWatcher = watcher.Watcher[*postgres.PostgresInstance] - KafkaTopicWatcher = watcher.Watcher[*kafkatopic.KafkaTopic] - PodWatcher = watcher.Watcher[*v1.Pod] - IngressWatcher = watcher.Watcher[*netv1.Ingress] - NamespaceWatcher = watcher.Watcher[*v1.Namespace] - UnleashWatcher = watcher.Watcher[*unleash.UnleashInstance] - SecretWatcher = watcher.Watcher[*secret.Secret] - ConfigWatcher = watcher.Watcher[*config.Config] - ReplicaSetWatcher = watcher.Watcher[*appsv1.ReplicaSet] - TunnelWatcher = watcher.Watcher[*tunnel.Tunnel] - NaisValkeyWatcher = watcher.Watcher[*valkey.Valkey] + AppWatcher = watcher.Watcher[*nais_io_v1alpha1.Application] + JobWatcher = watcher.Watcher[*nais_io_v1.Naisjob] + RunWatcher = watcher.Watcher[*batchv1.Job] + BqWatcher = watcher.Watcher[*bigquery.BigQueryDataset] + ValkeyWatcher = watcher.Watcher[*valkey.Valkey] + OpenSearchWatcher = watcher.Watcher[*opensearch.OpenSearch] + NaisOpenSearchWatcher = watcher.Watcher[*opensearch.OpenSearch] + BucketWatcher = watcher.Watcher[*bucket.Bucket] + SqlDatabaseWatcher = watcher.Watcher[*sqlinstance.SQLDatabase] + SqlInstanceWatcher = watcher.Watcher[*sqlinstance.SQLInstance] + PostgresWatcher = watcher.Watcher[*postgres.PostgresInstance] + KafkaTopicWatcher = watcher.Watcher[*kafkatopic.KafkaTopic] + PodWatcher = watcher.Watcher[*v1.Pod] + IngressWatcher = watcher.Watcher[*netv1.Ingress] + NamespaceWatcher = watcher.Watcher[*v1.Namespace] + UnleashWatcher = watcher.Watcher[*unleash.UnleashInstance] + SecretWatcher = watcher.Watcher[*secret.Secret] + ConfigWatcher = watcher.Watcher[*config.Config] + ReplicaSetWatcher = watcher.Watcher[*appsv1.ReplicaSet] + TunnelWatcher = watcher.Watcher[*tunnel.Tunnel] + NaisValkeyWatcher = watcher.Watcher[*valkey.Valkey] ) type Watchers struct { - AppWatcher *AppWatcher - JobWatcher *JobWatcher - RunWatcher *RunWatcher - BqWatcher *BqWatcher - ValkeyWatcher *ValkeyWatcher - OpenSearchWatcher *OpenSearchWatcher - NaisOpenSearchWatcher *NaisOpenSearchWatcher - BucketWatcher *BucketWatcher - SqlDatabaseWatcher *SqlDatabaseWatcher - SqlInstanceWatcher *SqlInstanceWatcher - ZalandoPostgresWatcher *ZalandoPostgresWatcher - KafkaTopicWatcher *KafkaTopicWatcher - PodWatcher *PodWatcher - IngressWatcher *IngressWatcher - NamespaceWatcher *NamespaceWatcher - UnleashWatcher *UnleashWatcher - SecretWatcher *SecretWatcher - ConfigWatcher *ConfigWatcher - ReplicaSetWatcher *ReplicaSetWatcher - TunnelWatcher *TunnelWatcher - NaisValkeyWatcher *NaisValkeyWatcher + AppWatcher *AppWatcher + JobWatcher *JobWatcher + RunWatcher *RunWatcher + BqWatcher *BqWatcher + ValkeyWatcher *ValkeyWatcher + OpenSearchWatcher *OpenSearchWatcher + NaisOpenSearchWatcher *NaisOpenSearchWatcher + BucketWatcher *BucketWatcher + SqlDatabaseWatcher *SqlDatabaseWatcher + SqlInstanceWatcher *SqlInstanceWatcher + PostgresWatcher *PostgresWatcher + KafkaTopicWatcher *KafkaTopicWatcher + PodWatcher *PodWatcher + IngressWatcher *IngressWatcher + NamespaceWatcher *NamespaceWatcher + UnleashWatcher *UnleashWatcher + SecretWatcher *SecretWatcher + ConfigWatcher *ConfigWatcher + ReplicaSetWatcher *ReplicaSetWatcher + TunnelWatcher *TunnelWatcher + NaisValkeyWatcher *NaisValkeyWatcher } func SetupWatchers( @@ -83,26 +83,26 @@ func SetupWatchers( unleashEnabled bool, ) *Watchers { ret := &Watchers{ - AppWatcher: application.NewWatcher(ctx, watcherMgr), - JobWatcher: job.NewWatcher(ctx, watcherMgr), - RunWatcher: job.NewRunWatcher(ctx, watcherMgr), - BqWatcher: bigquery.NewWatcher(ctx, watcherMgr), - ValkeyWatcher: valkey.NewWatcher(ctx, watcherMgr), - OpenSearchWatcher: opensearch.NewWatcher(ctx, watcherMgr), - NaisOpenSearchWatcher: opensearch.NewNaisOpenSearchWatcher(ctx, watcherMgr), - BucketWatcher: bucket.NewWatcher(ctx, watcherMgr), - SqlDatabaseWatcher: sqlinstance.NewDatabaseWatcher(ctx, watcherMgr), - SqlInstanceWatcher: sqlinstance.NewInstanceWatcher(ctx, watcherMgr), - ZalandoPostgresWatcher: postgres.NewZalandoPostgresWatcher(ctx, watcherMgr), - KafkaTopicWatcher: kafkatopic.NewWatcher(ctx, watcherMgr), - PodWatcher: workload.NewWatcher(ctx, watcherMgr), - IngressWatcher: application.NewIngressWatcher(ctx, watcherMgr), - NamespaceWatcher: team.NewNamespaceWatcher(ctx, watcherMgr), - SecretWatcher: secret.NewWatcher(ctx, watcherMgr), - ConfigWatcher: config.NewWatcher(ctx, watcherMgr), - ReplicaSetWatcher: instancegroup.NewWatcher(ctx, watcherMgr), - TunnelWatcher: tunnel.NewWatcher(ctx, watcherMgr), - NaisValkeyWatcher: valkey.NewNaisValkeyWatcher(ctx, watcherMgr), + AppWatcher: application.NewWatcher(ctx, watcherMgr), + JobWatcher: job.NewWatcher(ctx, watcherMgr), + RunWatcher: job.NewRunWatcher(ctx, watcherMgr), + BqWatcher: bigquery.NewWatcher(ctx, watcherMgr), + ValkeyWatcher: valkey.NewWatcher(ctx, watcherMgr), + OpenSearchWatcher: opensearch.NewWatcher(ctx, watcherMgr), + NaisOpenSearchWatcher: opensearch.NewNaisOpenSearchWatcher(ctx, watcherMgr), + BucketWatcher: bucket.NewWatcher(ctx, watcherMgr), + SqlDatabaseWatcher: sqlinstance.NewDatabaseWatcher(ctx, watcherMgr), + SqlInstanceWatcher: sqlinstance.NewInstanceWatcher(ctx, watcherMgr), + PostgresWatcher: postgres.NewPostgresWatcher(ctx, watcherMgr), + KafkaTopicWatcher: kafkatopic.NewWatcher(ctx, watcherMgr), + PodWatcher: workload.NewWatcher(ctx, watcherMgr), + IngressWatcher: application.NewIngressWatcher(ctx, watcherMgr), + NamespaceWatcher: team.NewNamespaceWatcher(ctx, watcherMgr), + SecretWatcher: secret.NewWatcher(ctx, watcherMgr), + ConfigWatcher: config.NewWatcher(ctx, watcherMgr), + ReplicaSetWatcher: instancegroup.NewWatcher(ctx, watcherMgr), + TunnelWatcher: tunnel.NewWatcher(ctx, watcherMgr), + NaisValkeyWatcher: valkey.NewNaisValkeyWatcher(ctx, watcherMgr), } if unleashEnabled { ret.UnleashWatcher = unleash.NewWatcher(ctx, mgmtWatcherMgr) diff --git a/internal/persistence/postgres/dataloader.go b/internal/persistence/postgres/dataloader.go index 0282dcb72..fa711dcfd 100644 --- a/internal/persistence/postgres/dataloader.go +++ b/internal/persistence/postgres/dataloader.go @@ -14,28 +14,28 @@ const loadersKey ctxKey = iota func NewLoaderContext( ctx context.Context, - zalandoPostgresWatcher *watcher.Watcher[*PostgresInstance], + postgresWatcher *watcher.Watcher[*PostgresInstance], auditLogProjectID string, auditLogLocation string, ) context.Context { - return context.WithValue(ctx, loadersKey, newLoaders(zalandoPostgresWatcher, auditLogProjectID, auditLogLocation)) + return context.WithValue(ctx, loadersKey, newLoaders(postgresWatcher, auditLogProjectID, auditLogLocation)) } type loaders struct { - zalandoPostgresWatcher *watcher.Watcher[*PostgresInstance] - auditLogProjectID string - auditLogLocation string + postgresWatcher *watcher.Watcher[*PostgresInstance] + auditLogProjectID string + auditLogLocation string } func newLoaders( - zalandoPostgresWatcher *watcher.Watcher[*PostgresInstance], + postgresWatcher *watcher.Watcher[*PostgresInstance], auditLogProjectID string, auditLogLocation string, ) *loaders { return &loaders{ - zalandoPostgresWatcher: zalandoPostgresWatcher, - auditLogProjectID: auditLogProjectID, - auditLogLocation: auditLogLocation, + postgresWatcher: postgresWatcher, + auditLogProjectID: auditLogProjectID, + auditLogLocation: auditLogLocation, } } @@ -45,7 +45,7 @@ func GetAuditLogConfig(ctx context.Context) (projectID, location string) { return loaders.auditLogProjectID, loaders.auditLogLocation } -func NewZalandoPostgresWatcher(ctx context.Context, mgr *watcher.Manager) *watcher.Watcher[*PostgresInstance] { +func NewPostgresWatcher(ctx context.Context, mgr *watcher.Manager) *watcher.Watcher[*PostgresInstance] { w := watcher.Watch(mgr, &PostgresInstance{}, watcher.WithConverter(func(o *unstructured.Unstructured, environmentName string) (obj any, ok bool) { ret, err := toPostgres(o, environmentName) if err != nil { diff --git a/internal/persistence/postgres/models.go b/internal/persistence/postgres/models.go index d5e8f2f46..814fe71bf 100644 --- a/internal/persistence/postgres/models.go +++ b/internal/persistence/postgres/models.go @@ -220,7 +220,7 @@ func (i *GrantPostgresAccessInput) ValidationErrors(ctx context.Context) *valida verr.Add("duration", "Duration \"%s\" is out-of-bounds. Must be less than 4 hours.", i.Duration) } - _, err = GetZalandoPostgres(ctx, i.TeamSlug, i.EnvironmentName, i.ClusterName) + _, err = GetPostgres(ctx, i.TeamSlug, i.EnvironmentName, i.ClusterName) if err != nil { if errors.Is(err, &watcher.ErrorNotFound{}) { verr.Add("clusterName", "Could not find postgres cluster named \"%s\"", i.ClusterName) @@ -281,7 +281,7 @@ func (i *CreatePostgresAccessInput) ValidationErrors(ctx context.Context) *valid return verr } - instance, err := GetZalandoPostgres(ctx, i.TeamSlug, i.EnvironmentName, i.PostgresInstance) + instance, err := GetPostgres(ctx, i.TeamSlug, i.EnvironmentName, i.PostgresInstance) if err != nil { if errors.Is(err, &watcher.ErrorNotFound{}) { verr.Add("postgresInstance", "Could not find postgres cluster named %q", i.PostgresInstance) diff --git a/internal/persistence/postgres/node.go b/internal/persistence/postgres/node.go index a22572ae5..9bf4b2df8 100644 --- a/internal/persistence/postgres/node.go +++ b/internal/persistence/postgres/node.go @@ -10,12 +10,12 @@ import ( type identType int const ( - identZalandoPostgres identType = iota + identPostgres identType = iota identPostgresAccess ) func init() { - ident.RegisterIdentType(identZalandoPostgres, "PP", GetZalandoPostgresByIdent) + ident.RegisterIdentType(identPostgres, "PP", GetPostgresByIdent) ident.RegisterIdentType(identPostgresAccess, "PA", GetPostgresAccessByIdent) } @@ -29,7 +29,7 @@ func parsePostgresInstanceIdent(id ident.Ident) (teamSlug slug.Slug, environment } func newIdent(teamSlug slug.Slug, environmentName, postgresInstanceName string) ident.Ident { - return ident.NewIdent(identZalandoPostgres, teamSlug.String(), environmentName, postgresInstanceName) + return ident.NewIdent(identPostgres, teamSlug.String(), environmentName, postgresInstanceName) } func parseAccessIdent(id ident.Ident) (teamSlug slug.Slug, environmentName, name string, err error) { diff --git a/internal/persistence/postgres/queries.go b/internal/persistence/postgres/queries.go index 961591c76..a54e7cd5f 100644 --- a/internal/persistence/postgres/queries.go +++ b/internal/persistence/postgres/queries.go @@ -39,7 +39,7 @@ func Delete(ctx context.Context, input DeletePostgresInput) (*DeletePostgresPayl return nil, err } - client, err := fromContext(ctx).zalandoPostgresWatcher.ImpersonatedClientWithNamespace(ctx, input.EnvironmentName, input.TeamSlug.String()) + client, err := fromContext(ctx).postgresWatcher.ImpersonatedClientWithNamespace(ctx, input.EnvironmentName, input.TeamSlug.String()) if err != nil { return nil, err } @@ -62,7 +62,7 @@ func Delete(ctx context.Context, input DeletePostgresInput) (*DeletePostgresPayl } } - if err := fromContext(ctx).zalandoPostgresWatcher.Delete(ctx, input.EnvironmentName, input.TeamSlug.String(), input.Name); err != nil { + if err := fromContext(ctx).postgresWatcher.Delete(ctx, input.EnvironmentName, input.TeamSlug.String(), input.Name); err != nil { return nil, err } @@ -85,7 +85,7 @@ func GetForWorkload(ctx context.Context, teamSlug slug.Slug, environmentName, cl return nil, nil } - return GetZalandoPostgres(ctx, teamSlug, environmentName, clusterName) + return GetPostgres(ctx, teamSlug, environmentName, clusterName) } func ListForTeam(ctx context.Context, teamSlug slug.Slug, page *pagination.Pagination, orderBy *PostgresInstanceOrder, filter *PostgresInstanceFilter) (*PostgresInstanceConnection, error) { @@ -102,21 +102,21 @@ func ListForTeam(ctx context.Context, teamSlug slug.Slug, page *pagination.Pagin } func ListAllForTeam(ctx context.Context, teamSlug slug.Slug, filter *PostgresInstanceFilter) []*PostgresInstance { - all := fromContext(ctx).zalandoPostgresWatcher.GetByNamespace(teamSlug.String()) + all := fromContext(ctx).postgresWatcher.GetByNamespace(teamSlug.String()) return watcher.Objects(all) } func CountForTeam(ctx context.Context, teamSlug slug.Slug) int { - return len(fromContext(ctx).zalandoPostgresWatcher.GetByNamespace(teamSlug.String())) + return len(fromContext(ctx).postgresWatcher.GetByNamespace(teamSlug.String())) } -func GetZalandoPostgresByIdent(ctx context.Context, id ident.Ident) (*PostgresInstance, error) { +func GetPostgresByIdent(ctx context.Context, id ident.Ident) (*PostgresInstance, error) { teamSlug, environmentName, clusterName, err := parsePostgresInstanceIdent(id) if err != nil { return nil, err } - return GetZalandoPostgres(ctx, teamSlug, environmentName, clusterName) + return GetPostgres(ctx, teamSlug, environmentName, clusterName) } func GetPostgresAccessByIdent(ctx context.Context, id ident.Ident) (*PostgresAccess, error) { @@ -136,7 +136,7 @@ const ( // GetPostgresAccess returns a personal PostgresAccess status. Connection // credentials are deliberately available only through GetPostgresAccessConnection. func GetPostgresAccess(ctx context.Context, name string, teamSlug slug.Slug, environmentName string) (*PostgresAccess, error) { - if err := authz.CanReadPostgresAccess(ctx, teamSlug); err != nil { + if err := authz.CanGrantPostgresAccess(ctx, teamSlug); err != nil { return nil, err } @@ -162,7 +162,7 @@ func GetPostgresAccessConnection(ctx context.Context, input PostgresAccessConnec if err := input.Validate(ctx); err != nil { return nil, err } - if err := authz.CanReadPostgresAccess(ctx, input.TeamSlug); err != nil { + if err := authz.CanGrantPostgresAccess(ctx, input.TeamSlug); err != nil { return nil, err } @@ -185,7 +185,7 @@ func GetPostgresAccessConnection(ctx context.Context, input PostgresAccessConnec return nil, err } - secretClient, err := fromContext(ctx).zalandoPostgresWatcher.SystemAuthenticatedClient(ctx, input.EnvironmentName, watcher.WithImpersonatedClientGVR(schema.GroupVersionResource{ + secretClient, err := fromContext(ctx).postgresWatcher.SystemAuthenticatedClient(ctx, input.EnvironmentName, watcher.WithImpersonatedClientGVR(schema.GroupVersionResource{ Version: "v1", Resource: "secrets", })) @@ -223,7 +223,7 @@ func GetPostgresAccessConnection(ctx context.Context, input PostgresAccessConnec } func getPostgresAccessResource(ctx context.Context, name string, teamSlug slug.Slug, environmentName string) (*unstructured.Unstructured, error) { - accessClient, err := fromContext(ctx).zalandoPostgresWatcher.SystemAuthenticatedClient(ctx, environmentName, watcher.WithImpersonatedClientGVR(schema.GroupVersionResource{ + accessClient, err := fromContext(ctx).postgresWatcher.SystemAuthenticatedClient(ctx, environmentName, watcher.WithImpersonatedClientGVR(schema.GroupVersionResource{ Group: postgresAccessGroup, Version: "v1", Resource: postgresAccessResource, @@ -397,8 +397,8 @@ func postgresAccessState(obj map[string]any, expiresAt time.Time) (PostgresAcces return PostgresAccessStatePending, "waiting for controller" } -func GetZalandoPostgres(ctx context.Context, teamSlug slug.Slug, environmentName string, clusterName string) (*PostgresInstance, error) { - return fromContext(ctx).zalandoPostgresWatcher.Get(environmentName, teamSlug.String(), clusterName) +func GetPostgres(ctx context.Context, teamSlug slug.Slug, environmentName string, clusterName string) (*PostgresInstance, error) { + return fromContext(ctx).postgresWatcher.Get(environmentName, teamSlug.String(), clusterName) } func GetAuditURL(ctx context.Context, audit *PostgresInstanceAudit) (*string, error) { @@ -443,7 +443,7 @@ func CreatePostgresAccess(ctx context.Context, input CreatePostgresAccessInput) Version: "v1", Resource: "postgresaccesses", } - client, err := fromContext(ctx).zalandoPostgresWatcher.SystemAuthenticatedClient(ctx, input.EnvironmentName, watcher.WithImpersonatedClientGVR(gvr)) + client, err := fromContext(ctx).postgresWatcher.SystemAuthenticatedClient(ctx, input.EnvironmentName, watcher.WithImpersonatedClientGVR(gvr)) if err != nil { return nil, err } @@ -493,7 +493,7 @@ func newPostgresAccessResource(input CreatePostgresAccessInput, username, name s return res } -func GrantZalandoPostgresAccess(ctx context.Context, input GrantPostgresAccessInput) error { +func GrantPostgresAccess(ctx context.Context, input GrantPostgresAccessInput) error { err := input.Validate(ctx) if err != nil { return err @@ -546,7 +546,7 @@ func createRoleBinding(ctx context.Context, input GrantPostgresAccessInput, name Version: "v1", Resource: "rolebindings", } - client, err := fromContext(ctx).zalandoPostgresWatcher.SystemAuthenticatedClient(ctx, input.EnvironmentName, watcher.WithImpersonatedClientGVR(gvr)) + client, err := fromContext(ctx).postgresWatcher.SystemAuthenticatedClient(ctx, input.EnvironmentName, watcher.WithImpersonatedClientGVR(gvr)) if err != nil { return err } @@ -584,7 +584,7 @@ func createRole(ctx context.Context, input GrantPostgresAccessInput, name string Resource: "roles", } - client, err := fromContext(ctx).zalandoPostgresWatcher.SystemAuthenticatedClient(ctx, input.EnvironmentName, watcher.WithImpersonatedClientGVR(gvr)) + client, err := fromContext(ctx).postgresWatcher.SystemAuthenticatedClient(ctx, input.EnvironmentName, watcher.WithImpersonatedClientGVR(gvr)) if err != nil { return err } diff --git a/internal/persistence/postgres/search.go b/internal/persistence/postgres/search.go index fe5128deb..14c2826d0 100644 --- a/internal/persistence/postgres/search.go +++ b/internal/persistence/postgres/search.go @@ -9,13 +9,13 @@ import ( "github.com/nais/api/internal/slug" ) -func AddSearchZalandoPostgres(client search.Client, watcher *watcher.Watcher[*PostgresInstance]) { +func AddSearchPostgres(client search.Client, watcher *watcher.Watcher[*PostgresInstance]) { createIdent := func(env string, obj *PostgresInstance) ident.Ident { return newIdent(slug.Slug(obj.GetNamespace()), env, obj.GetName()) } gbi := func(ctx context.Context, id ident.Ident) (search.SearchNode, error) { - return GetZalandoPostgresByIdent(ctx, id) + return GetPostgresByIdent(ctx, id) } client.AddClient("POSTGRES", search.NewK8sSearch("POSTGRES", watcher, gbi, createIdent)) From 9ddc6f0654dc9d48fb15cb88829c494edaaf4db4 Mon Sep 17 00:00:00 2001 From: Johnny Fredheim Horvi Date: Thu, 17 Sep 2026 15:48:56 +0200 Subject: [PATCH 04/19] fix review comments --- integration_tests/create_postgres_access.lua | 40 ++++++++++++++++ .../postgres_access_failed-access.yaml | 17 +++++++ internal/graph/gengql/root_.generated.go | 48 ++++++++++++++++++- internal/graph/schema/postgres.graphqls | 48 ++++++++++++++++++- internal/persistence/postgres/queries.go | 5 -- 5 files changed, 151 insertions(+), 7 deletions(-) create mode 100644 integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_failed-access.yaml diff --git a/integration_tests/create_postgres_access.lua b/integration_tests/create_postgres_access.lua index 0aa5d3c41..473011ca4 100644 --- a/integration_tests/create_postgres_access.lua +++ b/integration_tests/create_postgres_access.lua @@ -196,6 +196,46 @@ Test.gql("Personal postgres access is audited as a self-grant", function(t) } end) +Test.gql("PostgresAccess status is visible to authorized team members", function(t) + t.addHeader("x-user-email", otherMemberUser:email()) + for _, test in ipairs({ + { name = "ready-access", state = "READY", message = "Database role and tunnel are ready" }, + { name = "pending-access", state = "PENDING", message = Null }, + { name = "failed-access", state = "FAILED", message = Contains("not supported") }, + { name = "expired-access", state = "EXPIRED", message = "access has expired" }, + }) do + t.query(string.format( + [[query { postgresAccess(name: "%s", teamSlug: "someteamname", environmentName: "dev") { name state message } }]], + test.name)) + t.check { + data = { + postgresAccess = { + name = test.name, + state = test.state, + message = test.message, + }, + }, + } + end +end) + +Test.gql("PostgresAccess status rejects users outside the team", function(t) + t.addHeader("x-user-email", nonMemberUser:email()) + t.query [[ + query { postgresAccess(name: "ready-access", teamSlug: "someteamname", environmentName: "dev") { state } } + ]] + t.check { + errors = { + { + locations = NotNull(), + message = Contains('you need the "postgres:access:grant" authorization.'), + path = { "postgresAccess" }, + }, + }, + data = Null, + } +end) + Test.gql("PostgresAccess connection returns credentials only to its owner", function(t) t.addHeader("x-user-email", user:email()) t.query [[ diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_failed-access.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_failed-access.yaml new file mode 100644 index 000000000..144463575 --- /dev/null +++ b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_failed-access.yaml @@ -0,0 +1,17 @@ +apiVersion: nais.io/v1 +kind: PostgresAccess +metadata: + name: failed-access + namespace: someteamname +spec: + postgresInstance: foobar + username: user@usersen.com + accessLevel: readwritecreate + expiresAt: "2099-09-17T12:00:00Z" + clientWireGuardPublicKey: client-public-key +status: + conditions: + - type: Ready + status: "False" + reason: UnsupportedAccessLevel + message: "readwritecreate is not supported for this Postgres instance" diff --git a/internal/graph/gengql/root_.generated.go b/internal/graph/gengql/root_.generated.go index afe29cf6f..c8dcaaeff 100644 --- a/internal/graph/gengql/root_.generated.go +++ b/internal/graph/gengql/root_.generated.go @@ -26937,6 +26937,7 @@ type PostgresGrantAccessActivityLogEntryData { until: Time! } +"An audit-log entry for personal Postgres access created through the API broker." type PostgresPersonalAccessCreatedActivityLogEntry implements ActivityLogEntry & Node { "ID of the entry." id: ID! @@ -26958,20 +26959,33 @@ type PostgresPersonalAccessCreatedActivityLogEntry implements ActivityLogEntry & data: PostgresPersonalAccessCreatedActivityLogEntryData! } +"Personal-access-specific audit data." type PostgresPersonalAccessCreatedActivityLogEntryData { + "Identity that owns the new personal access." username: String! + "Server-controlled expiry of the access." expiresAt: Time! + "Caller-provided audit reason." reason: String! } +"An audit-log entry for retrieval of personal Postgres connection materials." type PostgresPersonalAccessConnectionActivityLogEntry implements ActivityLogEntry & Node { + "ID of the entry." id: ID! + "Identity that retrieved the connection materials." actor: String! + "Creation time of the entry." createdAt: Time! + "Message that summarizes the entry." message: String! + "Type of the affected resource." resourceType: ActivityLogEntryResourceType! + "Name of the affected PostgresAccess resource." resourceName: String! + "Team slug that the entry belongs to." teamSlug: Slug! + "Environment name that the entry belongs to." environmentName: String } @@ -27029,6 +27043,7 @@ extend type Mutation { deletePostgres(input: DeletePostgresInput!): DeletePostgresPayload! } +"Result of creating a personal Postgres access." type CreatePostgresAccessPayload { "Name of the newly created PostgresAccess resource." name: String! @@ -27036,19 +27051,29 @@ type CreatePostgresAccessPayload { expiresAt: Time! } +"Input for creating a time-limited personal Postgres access." input CreatePostgresAccessInput { + "Name of the available Postgres instance to access." postgresInstance: String! + "Team that owns the Postgres instance." teamSlug: Slug! + "Environment containing the Postgres instance." environmentName: String! + "Privileges requested for the personal database role." accessLevel: PostgresAccessLevel! + "WireGuard public key generated by the client for this access." clientWireGuardPublicKey: String! "Reason for personal database access. Must be at least 10 characters." reason: String! } +"Privilege level granted to a personal Postgres database role." enum PostgresAccessLevel { + "Read data without modifying it." READ + "Read and modify existing data." READWRITE + "Read, modify, and create database objects where supported." READWRITECREATE } @@ -27092,7 +27117,7 @@ extend type Query { "Get connection materials for a ready personal Postgres access owned by the caller." postgresAccessConnection(input: PostgresAccessConnectionInput!): PostgresAccessConnectionPayload! - "Get a personal PostgresAccess resource and its ready state." + "Get a personal PostgresAccess resource and its state. Available to authorized team members." postgresAccess( "Name of the PostgresAccess resource." name: String! @@ -27105,8 +27130,11 @@ extend type Query { ): PostgresAccess! } +"A time-limited personal access request for a Postgres instance." type PostgresAccess implements Node { + "Opaque ID for this PostgresAccess resource." id: ID! + "Name of the PostgresAccess resource." name: String! "Team that owns the access." team: Team! @@ -27126,13 +27154,19 @@ type PostgresAccess implements Node { tunnel: PostgresAccessTunnel } +"High-level reconciliation state of a personal Postgres access." enum PostgresAccessState { + "The controller has not finished provisioning the access." PENDING + "The access and its connection materials are ready." READY + "The controller cannot provision the requested access." FAILED + "The server-controlled expiry time has passed." EXPIRED } +"Tunnel details reported while provisioning a personal Postgres access." type PostgresAccessTunnel { "Name of the Tunnel resource owned by this access." name: String! @@ -27142,21 +27176,33 @@ type PostgresAccessTunnel { gatewayPublicKey: String } +"Input for retrieving connection materials for a ready personal access." input PostgresAccessConnectionInput { + "Name of the PostgresAccess resource." name: String! + "Team that owns the PostgresAccess resource." teamSlug: Slug! + "Environment containing the PostgresAccess resource." environmentName: String! } +"Sensitive connection materials for a ready personal Postgres access." type PostgresAccessConnectionPayload { + "Short-lived password for the caller's database role." password: String! + "CA certificate required to verify the PostgreSQL server certificate." caCertificate: String! + "PostgreSQL server name used for TLS verification." serverName: String! + "WireGuard tunnel endpoint and server public key." tunnel: PostgresAccessConnectionTunnel! } +"WireGuard connection parameters for a personal Postgres access." type PostgresAccessConnectionTunnel { + "Public UDP endpoint of the Tunnel forwarder." endpoint: String! + "WireGuard public key of the Tunnel gateway." gatewayPublicKey: String! } `, BuiltIn: false}, diff --git a/internal/graph/schema/postgres.graphqls b/internal/graph/schema/postgres.graphqls index 357727fa2..2d6b72b33 100644 --- a/internal/graph/schema/postgres.graphqls +++ b/internal/graph/schema/postgres.graphqls @@ -239,6 +239,7 @@ type PostgresGrantAccessActivityLogEntryData { until: Time! } +"An audit-log entry for personal Postgres access created through the API broker." type PostgresPersonalAccessCreatedActivityLogEntry implements ActivityLogEntry & Node { "ID of the entry." id: ID! @@ -260,20 +261,33 @@ type PostgresPersonalAccessCreatedActivityLogEntry implements ActivityLogEntry & data: PostgresPersonalAccessCreatedActivityLogEntryData! } +"Personal-access-specific audit data." type PostgresPersonalAccessCreatedActivityLogEntryData { + "Identity that owns the new personal access." username: String! + "Server-controlled expiry of the access." expiresAt: Time! + "Caller-provided audit reason." reason: String! } +"An audit-log entry for retrieval of personal Postgres connection materials." type PostgresPersonalAccessConnectionActivityLogEntry implements ActivityLogEntry & Node { + "ID of the entry." id: ID! + "Identity that retrieved the connection materials." actor: String! + "Creation time of the entry." createdAt: Time! + "Message that summarizes the entry." message: String! + "Type of the affected resource." resourceType: ActivityLogEntryResourceType! + "Name of the affected PostgresAccess resource." resourceName: String! + "Team slug that the entry belongs to." teamSlug: Slug! + "Environment name that the entry belongs to." environmentName: String } @@ -331,6 +345,7 @@ extend type Mutation { deletePostgres(input: DeletePostgresInput!): DeletePostgresPayload! } +"Result of creating a personal Postgres access." type CreatePostgresAccessPayload { "Name of the newly created PostgresAccess resource." name: String! @@ -338,19 +353,29 @@ type CreatePostgresAccessPayload { expiresAt: Time! } +"Input for creating a time-limited personal Postgres access." input CreatePostgresAccessInput { + "Name of the available Postgres instance to access." postgresInstance: String! + "Team that owns the Postgres instance." teamSlug: Slug! + "Environment containing the Postgres instance." environmentName: String! + "Privileges requested for the personal database role." accessLevel: PostgresAccessLevel! + "WireGuard public key generated by the client for this access." clientWireGuardPublicKey: String! "Reason for personal database access. Must be at least 10 characters." reason: String! } +"Privilege level granted to a personal Postgres database role." enum PostgresAccessLevel { + "Read data without modifying it." READ + "Read and modify existing data." READWRITE + "Read, modify, and create database objects where supported." READWRITECREATE } @@ -394,7 +419,7 @@ extend type Query { "Get connection materials for a ready personal Postgres access owned by the caller." postgresAccessConnection(input: PostgresAccessConnectionInput!): PostgresAccessConnectionPayload! - "Get a personal PostgresAccess resource and its ready state." + "Get a personal PostgresAccess resource and its state. Available to authorized team members." postgresAccess( "Name of the PostgresAccess resource." name: String! @@ -407,8 +432,11 @@ extend type Query { ): PostgresAccess! } +"A time-limited personal access request for a Postgres instance." type PostgresAccess implements Node { + "Opaque ID for this PostgresAccess resource." id: ID! + "Name of the PostgresAccess resource." name: String! "Team that owns the access." team: Team! @@ -428,13 +456,19 @@ type PostgresAccess implements Node { tunnel: PostgresAccessTunnel } +"High-level reconciliation state of a personal Postgres access." enum PostgresAccessState { + "The controller has not finished provisioning the access." PENDING + "The access and its connection materials are ready." READY + "The controller cannot provision the requested access." FAILED + "The server-controlled expiry time has passed." EXPIRED } +"Tunnel details reported while provisioning a personal Postgres access." type PostgresAccessTunnel { "Name of the Tunnel resource owned by this access." name: String! @@ -444,20 +478,32 @@ type PostgresAccessTunnel { gatewayPublicKey: String } +"Input for retrieving connection materials for a ready personal access." input PostgresAccessConnectionInput { + "Name of the PostgresAccess resource." name: String! + "Team that owns the PostgresAccess resource." teamSlug: Slug! + "Environment containing the PostgresAccess resource." environmentName: String! } +"Sensitive connection materials for a ready personal Postgres access." type PostgresAccessConnectionPayload { + "Short-lived password for the caller's database role." password: String! + "CA certificate required to verify the PostgreSQL server certificate." caCertificate: String! + "PostgreSQL server name used for TLS verification." serverName: String! + "WireGuard tunnel endpoint and server public key." tunnel: PostgresAccessConnectionTunnel! } +"WireGuard connection parameters for a personal Postgres access." type PostgresAccessConnectionTunnel { + "Public UDP endpoint of the Tunnel forwarder." endpoint: String! + "WireGuard public key of the Tunnel gateway." gatewayPublicKey: String! } diff --git a/internal/persistence/postgres/queries.go b/internal/persistence/postgres/queries.go index a54e7cd5f..690351f49 100644 --- a/internal/persistence/postgres/queries.go +++ b/internal/persistence/postgres/queries.go @@ -150,11 +150,6 @@ func GetPostgresAccess(ctx context.Context, name string, teamSlug slug.Slug, env return nil, err } - actor := authz.ActorFromContext(ctx) - if actor == nil || access.Username != actor.User.Identity() { - return nil, apierror.Errorf("PostgresAccess %q not found", name) - } - return access, nil } From 8da0ee7508d88ffaee1e71327c4f60d527543daf Mon Sep 17 00:00:00 2001 From: Johnny Fredheim Horvi Date: Fri, 18 Sep 2026 07:41:52 +0200 Subject: [PATCH 05/19] fix: specify usage on different pg access commands --- internal/graph/gengql/root_.generated.go | 10 ++++++++-- internal/graph/schema/postgres.graphqls | 10 ++++++++-- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/internal/graph/gengql/root_.generated.go b/internal/graph/gengql/root_.generated.go index c8dcaaeff..41c050acd 100644 --- a/internal/graph/gengql/root_.generated.go +++ b/internal/graph/gengql/root_.generated.go @@ -27035,9 +27035,15 @@ extend enum ActivityLogActivityType { } extend type Mutation { - "Create a time-limited personal Postgres access through the API broker." + """ + Create time-limited personal database access through the brokered PostgresAccess and WireGuard tunnel flow. + Use this for all new personal Postgres access. When the access is ready, retrieve its connection materials with postgresAccessConnection. + """ createPostgresAccess(input: CreatePostgresAccessInput!): CreatePostgresAccessPayload! - "Grant temporary access to a Postgres cluster." + """ + Grant legacy, time-limited Kubernetes RBAC access to CNPG pods for kubectl port-forward. + This does not create a PostgresAccess, WireGuard tunnel, or database credentials. Use createPostgresAccess for new personal access. + """ grantPostgresAccess(input: GrantPostgresAccessInput!): GrantPostgresAccessPayload! "Delete an existing Postgres instance." deletePostgres(input: DeletePostgresInput!): DeletePostgresPayload! diff --git a/internal/graph/schema/postgres.graphqls b/internal/graph/schema/postgres.graphqls index 2d6b72b33..419858ed0 100644 --- a/internal/graph/schema/postgres.graphqls +++ b/internal/graph/schema/postgres.graphqls @@ -337,9 +337,15 @@ extend enum ActivityLogActivityType { } extend type Mutation { - "Create a time-limited personal Postgres access through the API broker." + """ + Create time-limited personal database access through the brokered PostgresAccess and WireGuard tunnel flow. + Use this for all new personal Postgres access. When the access is ready, retrieve its connection materials with postgresAccessConnection. + """ createPostgresAccess(input: CreatePostgresAccessInput!): CreatePostgresAccessPayload! - "Grant temporary access to a Postgres cluster." + """ + Grant legacy, time-limited Kubernetes RBAC access to CNPG pods for kubectl port-forward. + This does not create a PostgresAccess, WireGuard tunnel, or database credentials. Use createPostgresAccess for new personal access. + """ grantPostgresAccess(input: GrantPostgresAccessInput!): GrantPostgresAccessPayload! "Delete an existing Postgres instance." deletePostgres(input: DeletePostgresInput!): DeletePostgresPayload! From 8d30c01b17100e506725d590cc01b36cfcd35dc4 Mon Sep 17 00:00:00 2001 From: Johnny Fredheim Horvi Date: Fri, 18 Sep 2026 09:35:46 +0200 Subject: [PATCH 06/19] fix stuff based on feedback --- integration_tests/create_postgres_access.lua | 1 + internal/graph/gengql/postgres.generated.go | 75 ++++++++++--------- internal/graph/gengql/root_.generated.go | 52 ++++++------- internal/graph/gengql/schema.generated.go | 8 +- internal/graph/postgres.resolvers.go | 2 +- internal/graph/schema/postgres.graphqls | 14 ++-- internal/persistence/postgres/models.go | 9 ++- internal/persistence/postgres/queries.go | 36 +++++++-- internal/persistence/postgres/queries_test.go | 34 +++++++++ 9 files changed, 154 insertions(+), 77 deletions(-) diff --git a/integration_tests/create_postgres_access.lua b/integration_tests/create_postgres_access.lua index 473011ca4..15cb4119f 100644 --- a/integration_tests/create_postgres_access.lua +++ b/integration_tests/create_postgres_access.lua @@ -138,6 +138,7 @@ Test.gql("Create personal postgres access", function(t) accessLevel: READWRITE clientWireGuardPublicKey: "client-public-key" reason: "Testing personal database access" + ttl: "2h" }) { name expiresAt diff --git a/internal/graph/gengql/postgres.generated.go b/internal/graph/gengql/postgres.generated.go index da3af728f..437760ad6 100644 --- a/internal/graph/gengql/postgres.generated.go +++ b/internal/graph/gengql/postgres.generated.go @@ -449,13 +449,13 @@ func (ec *executionContext) fieldContext_PostgresAccess_tunnel(_ context.Context return fc, nil } -func (ec *executionContext) _PostgresAccessConnectionPayload_password(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccessConnectionPayload) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresAccessConnection_password(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccessConnection) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresAccessConnectionPayload_password(ctx, field) + return ec.fieldContext_PostgresAccessConnection_password(ctx, field) }, func(ctx context.Context) (any, error) { return obj.Password, nil @@ -468,17 +468,17 @@ func (ec *executionContext) _PostgresAccessConnectionPayload_password(ctx contex true, ) } -func (ec *executionContext) fieldContext_PostgresAccessConnectionPayload_password(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresAccessConnectionPayload", field, false, false, errors.New("field of type String does not have child fields")) +func (ec *executionContext) fieldContext_PostgresAccessConnection_password(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresAccessConnection", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresAccessConnectionPayload_caCertificate(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccessConnectionPayload) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresAccessConnection_caCertificate(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccessConnection) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresAccessConnectionPayload_caCertificate(ctx, field) + return ec.fieldContext_PostgresAccessConnection_caCertificate(ctx, field) }, func(ctx context.Context) (any, error) { return obj.CACertificate, nil @@ -491,17 +491,17 @@ func (ec *executionContext) _PostgresAccessConnectionPayload_caCertificate(ctx c true, ) } -func (ec *executionContext) fieldContext_PostgresAccessConnectionPayload_caCertificate(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresAccessConnectionPayload", field, false, false, errors.New("field of type String does not have child fields")) +func (ec *executionContext) fieldContext_PostgresAccessConnection_caCertificate(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresAccessConnection", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresAccessConnectionPayload_serverName(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccessConnectionPayload) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresAccessConnection_serverName(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccessConnection) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresAccessConnectionPayload_serverName(ctx, field) + return ec.fieldContext_PostgresAccessConnection_serverName(ctx, field) }, func(ctx context.Context) (any, error) { return obj.ServerName, nil @@ -514,17 +514,17 @@ func (ec *executionContext) _PostgresAccessConnectionPayload_serverName(ctx cont true, ) } -func (ec *executionContext) fieldContext_PostgresAccessConnectionPayload_serverName(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresAccessConnectionPayload", field, false, false, errors.New("field of type String does not have child fields")) +func (ec *executionContext) fieldContext_PostgresAccessConnection_serverName(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresAccessConnection", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresAccessConnectionPayload_tunnel(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccessConnectionPayload) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresAccessConnection_tunnel(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccessConnection) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresAccessConnectionPayload_tunnel(ctx, field) + return ec.fieldContext_PostgresAccessConnection_tunnel(ctx, field) }, func(ctx context.Context) (any, error) { return obj.Tunnel, nil @@ -537,9 +537,9 @@ func (ec *executionContext) _PostgresAccessConnectionPayload_tunnel(ctx context. true, ) } -func (ec *executionContext) fieldContext_PostgresAccessConnectionPayload_tunnel(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_PostgresAccessConnection_tunnel(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "PostgresAccessConnectionPayload", + Object: "PostgresAccessConnection", Field: field, IsMethod: false, IsResolver: false, @@ -2542,7 +2542,7 @@ func (ec *executionContext) unmarshalInputCreatePostgresAccessInput(ctx context. asMap[k] = v } - fieldsInOrder := [...]string{"postgresInstance", "teamSlug", "environmentName", "accessLevel", "clientWireGuardPublicKey", "reason"} + fieldsInOrder := [...]string{"postgresInstance", "teamSlug", "environmentName", "accessLevel", "clientWireGuardPublicKey", "reason", "ttl"} for _, k := range fieldsInOrder { v, ok := asMap[k] if !ok { @@ -2591,6 +2591,13 @@ func (ec *executionContext) unmarshalInputCreatePostgresAccessInput(ctx context. return it, err } it.Reason = data + case "ttl": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("ttl")) + data, err := ec.unmarshalOString2string(ctx, v) + if err != nil { + return it, err + } + it.TTL = data } } return it, nil @@ -3139,34 +3146,34 @@ func (ec *executionContext) _PostgresAccess(ctx context.Context, sel ast.Selecti return out } -var postgresAccessConnectionPayloadImplementors = []string{"PostgresAccessConnectionPayload"} +var postgresAccessConnectionImplementors = []string{"PostgresAccessConnection"} -func (ec *executionContext) _PostgresAccessConnectionPayload(ctx context.Context, sel ast.SelectionSet, obj *postgres.PostgresAccessConnectionPayload) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, postgresAccessConnectionPayloadImplementors) +func (ec *executionContext) _PostgresAccessConnection(ctx context.Context, sel ast.SelectionSet, obj *postgres.PostgresAccessConnection) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, postgresAccessConnectionImplementors) out := graphql.NewFieldSet(fields) deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": - out.Values[i] = graphql.MarshalString("PostgresAccessConnectionPayload") + out.Values[i] = graphql.MarshalString("PostgresAccessConnection") case "password": - out.Values[i] = ec._PostgresAccessConnectionPayload_password(ctx, field, obj) + out.Values[i] = ec._PostgresAccessConnection_password(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } case "caCertificate": - out.Values[i] = ec._PostgresAccessConnectionPayload_caCertificate(ctx, field, obj) + out.Values[i] = ec._PostgresAccessConnection_caCertificate(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } case "serverName": - out.Values[i] = ec._PostgresAccessConnectionPayload_serverName(ctx, field, obj) + out.Values[i] = ec._PostgresAccessConnection_serverName(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } case "tunnel": - out.Values[i] = ec._PostgresAccessConnectionPayload_tunnel(ctx, field, obj) + out.Values[i] = ec._PostgresAccessConnection_tunnel(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } @@ -4516,23 +4523,23 @@ func (ec *executionContext) marshalNPostgresAccess2ᚖgithubᚗcomᚋnaisᚋapi return ec._PostgresAccess(ctx, sel, v) } -func (ec *executionContext) unmarshalNPostgresAccessConnectionInput2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccessConnectionInput(ctx context.Context, v any) (postgres.PostgresAccessConnectionInput, error) { - res, err := ec.unmarshalInputPostgresAccessConnectionInput(ctx, v) - return res, graphql.ErrorOnPath(ctx, err) -} - -func (ec *executionContext) marshalNPostgresAccessConnectionPayload2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccessConnectionPayload(ctx context.Context, sel ast.SelectionSet, v postgres.PostgresAccessConnectionPayload) graphql.Marshaler { - return ec._PostgresAccessConnectionPayload(ctx, sel, &v) +func (ec *executionContext) marshalNPostgresAccessConnection2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccessConnection(ctx context.Context, sel ast.SelectionSet, v postgres.PostgresAccessConnection) graphql.Marshaler { + return ec._PostgresAccessConnection(ctx, sel, &v) } -func (ec *executionContext) marshalNPostgresAccessConnectionPayload2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccessConnectionPayload(ctx context.Context, sel ast.SelectionSet, v *postgres.PostgresAccessConnectionPayload) graphql.Marshaler { +func (ec *executionContext) marshalNPostgresAccessConnection2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccessConnection(ctx context.Context, sel ast.SelectionSet, v *postgres.PostgresAccessConnection) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { graphql.AddErrorf(ctx, "the requested element is null which the schema does not allow") } return graphql.Null } - return ec._PostgresAccessConnectionPayload(ctx, sel, v) + return ec._PostgresAccessConnection(ctx, sel, v) +} + +func (ec *executionContext) unmarshalNPostgresAccessConnectionInput2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccessConnectionInput(ctx context.Context, v any) (postgres.PostgresAccessConnectionInput, error) { + res, err := ec.unmarshalInputPostgresAccessConnectionInput(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) } func (ec *executionContext) marshalNPostgresAccessConnectionTunnel2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccessConnectionTunnel(ctx context.Context, sel ast.SelectionSet, v postgres.PostgresAccessConnectionTunnel) graphql.Marshaler { diff --git a/internal/graph/gengql/root_.generated.go b/internal/graph/gengql/root_.generated.go index 41c050acd..32ada8427 100644 --- a/internal/graph/gengql/root_.generated.go +++ b/internal/graph/gengql/root_.generated.go @@ -1872,7 +1872,7 @@ type ComplexityRoot struct { Tunnel func(childComplexity int) int } - PostgresAccessConnectionPayload struct { + PostgresAccessConnection struct { CACertificate func(childComplexity int) int Password func(childComplexity int) int ServerName func(childComplexity int) int @@ -11400,33 +11400,33 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.PostgresAccess.Tunnel(childComplexity), true - case "PostgresAccessConnectionPayload.caCertificate": - if e.ComplexityRoot.PostgresAccessConnectionPayload.CACertificate == nil { + case "PostgresAccessConnection.caCertificate": + if e.ComplexityRoot.PostgresAccessConnection.CACertificate == nil { break } - return e.ComplexityRoot.PostgresAccessConnectionPayload.CACertificate(childComplexity), true + return e.ComplexityRoot.PostgresAccessConnection.CACertificate(childComplexity), true - case "PostgresAccessConnectionPayload.password": - if e.ComplexityRoot.PostgresAccessConnectionPayload.Password == nil { + case "PostgresAccessConnection.password": + if e.ComplexityRoot.PostgresAccessConnection.Password == nil { break } - return e.ComplexityRoot.PostgresAccessConnectionPayload.Password(childComplexity), true + return e.ComplexityRoot.PostgresAccessConnection.Password(childComplexity), true - case "PostgresAccessConnectionPayload.serverName": - if e.ComplexityRoot.PostgresAccessConnectionPayload.ServerName == nil { + case "PostgresAccessConnection.serverName": + if e.ComplexityRoot.PostgresAccessConnection.ServerName == nil { break } - return e.ComplexityRoot.PostgresAccessConnectionPayload.ServerName(childComplexity), true + return e.ComplexityRoot.PostgresAccessConnection.ServerName(childComplexity), true - case "PostgresAccessConnectionPayload.tunnel": - if e.ComplexityRoot.PostgresAccessConnectionPayload.Tunnel == nil { + case "PostgresAccessConnection.tunnel": + if e.ComplexityRoot.PostgresAccessConnection.Tunnel == nil { break } - return e.ComplexityRoot.PostgresAccessConnectionPayload.Tunnel(childComplexity), true + return e.ComplexityRoot.PostgresAccessConnection.Tunnel(childComplexity), true case "PostgresAccessConnectionTunnel.endpoint": if e.ComplexityRoot.PostgresAccessConnectionTunnel.Endpoint == nil { @@ -27036,13 +27036,13 @@ extend enum ActivityLogActivityType { extend type Mutation { """ - Create time-limited personal database access through the brokered PostgresAccess and WireGuard tunnel flow. - Use this for all new personal Postgres access. When the access is ready, retrieve its connection materials with postgresAccessConnection. + Create time-limited personal access to a NAIS Postgres instance through the brokered PostgresAccess and WireGuard tunnel flow. + Use this for new NAIS Postgres personal access. When the access is ready, retrieve its connection materials with postgresAccessConnection. """ createPostgresAccess(input: CreatePostgresAccessInput!): CreatePostgresAccessPayload! """ - Grant legacy, time-limited Kubernetes RBAC access to CNPG pods for kubectl port-forward. - This does not create a PostgresAccess, WireGuard tunnel, or database credentials. Use createPostgresAccess for new personal access. + Grant time-limited Kubernetes RBAC access to database pods for kubectl port-forward. + Use this existing flow for Cloud SQL access; it does not create a PostgresAccess, WireGuard tunnel, or database credentials. """ grantPostgresAccess(input: GrantPostgresAccessInput!): GrantPostgresAccessPayload! "Delete an existing Postgres instance." @@ -27071,6 +27071,8 @@ input CreatePostgresAccessInput { clientWireGuardPublicKey: String! "Reason for personal database access. Must be at least 10 characters." reason: String! + "Requested access lifetime (for example '1h' or '4h'). Defaults to '1h' and cannot exceed '8h'." + ttl: String } "Privilege level granted to a personal Postgres database role." @@ -27121,7 +27123,7 @@ type TeamInventoryCountPostgresInstances { extend type Query { "Get connection materials for a ready personal Postgres access owned by the caller." - postgresAccessConnection(input: PostgresAccessConnectionInput!): PostgresAccessConnectionPayload! + postgresAccessConnection(input: PostgresAccessConnectionInput!): PostgresAccessConnection! "Get a personal PostgresAccess resource and its state. Available to authorized team members." postgresAccess( @@ -27193,7 +27195,7 @@ input PostgresAccessConnectionInput { } "Sensitive connection materials for a ready personal Postgres access." -type PostgresAccessConnectionPayload { +type PostgresAccessConnection { "Short-lived password for the caller's database role." password: String! "CA certificate required to verify the PostgreSQL server certificate." @@ -36904,18 +36906,18 @@ func (ec *executionContext) childFields_PostgresAccess(ctx context.Context, fiel return nil, fmt.Errorf("no field named %q was found under type PostgresAccess", field.Name) } -func (ec *executionContext) childFields_PostgresAccessConnectionPayload(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { +func (ec *executionContext) childFields_PostgresAccessConnection(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { switch field.Name { case "password": - return ec.fieldContext_PostgresAccessConnectionPayload_password(ctx, field) + return ec.fieldContext_PostgresAccessConnection_password(ctx, field) case "caCertificate": - return ec.fieldContext_PostgresAccessConnectionPayload_caCertificate(ctx, field) + return ec.fieldContext_PostgresAccessConnection_caCertificate(ctx, field) case "serverName": - return ec.fieldContext_PostgresAccessConnectionPayload_serverName(ctx, field) + return ec.fieldContext_PostgresAccessConnection_serverName(ctx, field) case "tunnel": - return ec.fieldContext_PostgresAccessConnectionPayload_tunnel(ctx, field) + return ec.fieldContext_PostgresAccessConnection_tunnel(ctx, field) } - return nil, fmt.Errorf("no field named %q was found under type PostgresAccessConnectionPayload", field.Name) + return nil, fmt.Errorf("no field named %q was found under type PostgresAccessConnection", field.Name) } func (ec *executionContext) childFields_PostgresAccessConnectionTunnel(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { diff --git a/internal/graph/gengql/schema.generated.go b/internal/graph/gengql/schema.generated.go index 0c8dd0c0f..761ed9f9d 100644 --- a/internal/graph/gengql/schema.generated.go +++ b/internal/graph/gengql/schema.generated.go @@ -141,7 +141,7 @@ type QueryResolver interface { Environments(ctx context.Context, orderBy *environment.EnvironmentOrder) (*pagination.Connection[*environment.Environment], error) Environment(ctx context.Context, name string) (*environment.Environment, error) Features(ctx context.Context) (*feature.Features, error) - PostgresAccessConnection(ctx context.Context, input postgres.PostgresAccessConnectionInput) (*postgres.PostgresAccessConnectionPayload, error) + PostgresAccessConnection(ctx context.Context, input postgres.PostgresAccessConnectionInput) (*postgres.PostgresAccessConnection, error) PostgresAccess(ctx context.Context, name string, teamSlug slug.Slug, environmentName string) (*postgres.PostgresAccess, error) CurrentUnitPrices(ctx context.Context) (*price.CurrentUnitPrices, error) Reconcilers(ctx context.Context, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor) (*pagination.Connection[*reconciler.Reconciler], error) @@ -5279,8 +5279,8 @@ func (ec *executionContext) _Query_postgresAccessConnection(ctx context.Context, return ec.Resolvers.Query().PostgresAccessConnection(ctx, fc.Args["input"].(postgres.PostgresAccessConnectionInput)) }, nil, - func(ctx context.Context, selections ast.SelectionSet, v *postgres.PostgresAccessConnectionPayload) graphql.Marshaler { - return ec.marshalNPostgresAccessConnectionPayload2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccessConnectionPayload(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *postgres.PostgresAccessConnection) graphql.Marshaler { + return ec.marshalNPostgresAccessConnection2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccessConnection(ctx, selections, v) }, true, true, @@ -5293,7 +5293,7 @@ func (ec *executionContext) fieldContext_Query_postgresAccessConnection(ctx cont IsMethod: true, IsResolver: true, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_PostgresAccessConnectionPayload(ctx, field) + return ec.childFields_PostgresAccessConnection(ctx, field) }, } defer func() { diff --git a/internal/graph/postgres.resolvers.go b/internal/graph/postgres.resolvers.go index 886a89351..fd932fa53 100644 --- a/internal/graph/postgres.resolvers.go +++ b/internal/graph/postgres.resolvers.go @@ -121,7 +121,7 @@ func (r *postgresInstanceConnectionResolver) Facets(ctx context.Context, obj *pa }, nil } -func (r *queryResolver) PostgresAccessConnection(ctx context.Context, input postgres.PostgresAccessConnectionInput) (*postgres.PostgresAccessConnectionPayload, error) { +func (r *queryResolver) PostgresAccessConnection(ctx context.Context, input postgres.PostgresAccessConnectionInput) (*postgres.PostgresAccessConnection, error) { return postgres.GetPostgresAccessConnection(ctx, input) } diff --git a/internal/graph/schema/postgres.graphqls b/internal/graph/schema/postgres.graphqls index 419858ed0..2efef5694 100644 --- a/internal/graph/schema/postgres.graphqls +++ b/internal/graph/schema/postgres.graphqls @@ -338,13 +338,13 @@ extend enum ActivityLogActivityType { extend type Mutation { """ - Create time-limited personal database access through the brokered PostgresAccess and WireGuard tunnel flow. - Use this for all new personal Postgres access. When the access is ready, retrieve its connection materials with postgresAccessConnection. + Create time-limited personal access to a NAIS Postgres instance through the brokered PostgresAccess and WireGuard tunnel flow. + Use this for new NAIS Postgres personal access. When the access is ready, retrieve its connection materials with postgresAccessConnection. """ createPostgresAccess(input: CreatePostgresAccessInput!): CreatePostgresAccessPayload! """ - Grant legacy, time-limited Kubernetes RBAC access to CNPG pods for kubectl port-forward. - This does not create a PostgresAccess, WireGuard tunnel, or database credentials. Use createPostgresAccess for new personal access. + Grant time-limited Kubernetes RBAC access to database pods for kubectl port-forward. + Use this existing flow for Cloud SQL access; it does not create a PostgresAccess, WireGuard tunnel, or database credentials. """ grantPostgresAccess(input: GrantPostgresAccessInput!): GrantPostgresAccessPayload! "Delete an existing Postgres instance." @@ -373,6 +373,8 @@ input CreatePostgresAccessInput { clientWireGuardPublicKey: String! "Reason for personal database access. Must be at least 10 characters." reason: String! + "Requested access lifetime (for example '1h' or '4h'). Defaults to '1h' and cannot exceed '8h'." + ttl: String } "Privilege level granted to a personal Postgres database role." @@ -423,7 +425,7 @@ type TeamInventoryCountPostgresInstances { extend type Query { "Get connection materials for a ready personal Postgres access owned by the caller." - postgresAccessConnection(input: PostgresAccessConnectionInput!): PostgresAccessConnectionPayload! + postgresAccessConnection(input: PostgresAccessConnectionInput!): PostgresAccessConnection! "Get a personal PostgresAccess resource and its state. Available to authorized team members." postgresAccess( @@ -495,7 +497,7 @@ input PostgresAccessConnectionInput { } "Sensitive connection materials for a ready personal Postgres access." -type PostgresAccessConnectionPayload { +type PostgresAccessConnection { "Short-lived password for the caller's database role." password: String! "CA certificate required to verify the PostgreSQL server certificate." diff --git a/internal/persistence/postgres/models.go b/internal/persistence/postgres/models.go index 814fe71bf..0870fd8b5 100644 --- a/internal/persistence/postgres/models.go +++ b/internal/persistence/postgres/models.go @@ -237,7 +237,7 @@ type GrantPostgresAccessPayload struct { } // CreatePostgresAccessInput requests a new, time-limited personal database access. -// The authenticated actor and access lifetime are deliberately not caller-controlled. +// The authenticated actor and final expiry are server-controlled. type CreatePostgresAccessInput struct { PostgresInstance string `json:"postgresInstance"` TeamSlug slug.Slug `json:"teamSlug"` @@ -245,6 +245,7 @@ type CreatePostgresAccessInput struct { AccessLevel PostgresAccessLevel `json:"accessLevel"` ClientWireGuardPublicKey string `json:"clientWireGuardPublicKey"` Reason string `json:"reason"` + TTL string `json:"ttl"` } func (i *CreatePostgresAccessInput) Validate(ctx context.Context) error { @@ -257,6 +258,7 @@ func (i *CreatePostgresAccessInput) ValidationErrors(ctx context.Context) *valid i.EnvironmentName = strings.TrimSpace(i.EnvironmentName) i.ClientWireGuardPublicKey = strings.TrimSpace(i.ClientWireGuardPublicKey) i.Reason = strings.TrimSpace(i.Reason) + i.TTL = strings.TrimSpace(i.TTL) if i.PostgresInstance == "" { verr.Add("postgresInstance", "Postgres instance must not be empty.") @@ -276,6 +278,9 @@ func (i *CreatePostgresAccessInput) ValidationErrors(ctx context.Context) *valid if len(i.Reason) < 10 { verr.Add("reason", "Reason must be at least 10 characters.") } + if _, err := i.accessTTL(); err != nil { + verr.Add("ttl", "%s", err) + } if i.PostgresInstance == "" || i.EnvironmentName == "" || i.TeamSlug == "" { return verr @@ -610,7 +615,7 @@ func (i *PostgresAccessConnectionInput) ValidationErrors(_ context.Context) *val return verr } -type PostgresAccessConnectionPayload struct { +type PostgresAccessConnection struct { Password string `json:"password"` CACertificate string `json:"caCertificate"` ServerName string `json:"serverName"` diff --git a/internal/persistence/postgres/queries.go b/internal/persistence/postgres/queries.go index 690351f49..287e9c6a2 100644 --- a/internal/persistence/postgres/queries.go +++ b/internal/persistence/postgres/queries.go @@ -153,7 +153,7 @@ func GetPostgresAccess(ctx context.Context, name string, teamSlug slug.Slug, env return access, nil } -func GetPostgresAccessConnection(ctx context.Context, input PostgresAccessConnectionInput) (*PostgresAccessConnectionPayload, error) { +func GetPostgresAccessConnection(ctx context.Context, input PostgresAccessConnectionInput) (*PostgresAccessConnection, error) { if err := input.Validate(ctx); err != nil { return nil, err } @@ -236,7 +236,7 @@ func getPostgresAccessResource(ctx context.Context, name string, teamSlug slug.S return u, nil } -func postgresAccessConnectionDetails(access *unstructured.Unstructured, now time.Time) (*PostgresAccessConnectionPayload, string, error) { +func postgresAccessConnectionDetails(access *unstructured.Unstructured, now time.Time) (*PostgresAccessConnection, string, error) { expiresAt, _, err := unstructured.NestedString(access.Object, "spec", "expiresAt") if err != nil { return nil, "", fmt.Errorf("reading PostgresAccess %q expiry: %w", access.GetName(), err) @@ -269,7 +269,7 @@ func postgresAccessConnectionDetails(access *unstructured.Unstructured, now time return nil, "", apierror.Errorf("PostgresAccess %q is not ready", access.GetName()) } - return &PostgresAccessConnectionPayload{ + return &PostgresAccessConnection{ ServerName: serverName, Tunnel: PostgresAccessConnectionTunnel{ Endpoint: endpoint, GatewayPublicKey: gatewayPublicKey, @@ -426,12 +426,20 @@ func GetAuditURL(ctx context.Context, audit *PostgresInstanceAudit) (*string, er return &logURL, nil } -const postgresAccessAPIVersion = "nais.io/v1" +const ( + postgresAccessAPIVersion = "nais.io/v1" + defaultPostgresAccessTTL = time.Hour + maxPostgresAccessTTL = 8 * time.Hour +) func CreatePostgresAccess(ctx context.Context, input CreatePostgresAccessInput) (*CreatePostgresAccessPayload, error) { if err := input.Validate(ctx); err != nil { return nil, err } + accessTTL, err := input.accessTTL() + if err != nil { + return nil, err + } gvr := schema.GroupVersionResource{ Group: "nais.io", @@ -443,7 +451,7 @@ func CreatePostgresAccess(ctx context.Context, input CreatePostgresAccessInput) return nil, err } - expiresAt := time.Now().Add(time.Hour) + expiresAt := time.Now().Add(accessTTL) name := fmt.Sprintf("postgres-access-%s", uuid.NewString()[:8]) res := newPostgresAccessResource(input, authz.ActorFromContext(ctx).User.Identity(), name, expiresAt) @@ -470,6 +478,24 @@ func CreatePostgresAccess(ctx context.Context, input CreatePostgresAccessInput) return &CreatePostgresAccessPayload{Name: name, ExpiresAt: expiresAt}, nil } +func (i CreatePostgresAccessInput) accessTTL() (time.Duration, error) { + if i.TTL == "" { + return defaultPostgresAccessTTL, nil + } + + ttl, err := time.ParseDuration(i.TTL) + if err != nil { + return 0, fmt.Errorf("TTL must be a Go duration, for example %q", "4h") + } + if ttl <= 0 { + return 0, fmt.Errorf("TTL must be positive") + } + if ttl > maxPostgresAccessTTL { + return 0, fmt.Errorf("TTL cannot exceed %s", maxPostgresAccessTTL) + } + return ttl, nil +} + func newPostgresAccessResource(input CreatePostgresAccessInput, username, name string, expiresAt time.Time) *unstructured.Unstructured { res := &unstructured.Unstructured{} res.SetAPIVersion(postgresAccessAPIVersion) diff --git a/internal/persistence/postgres/queries_test.go b/internal/persistence/postgres/queries_test.go index c7cfbb43a..524332b92 100644 --- a/internal/persistence/postgres/queries_test.go +++ b/internal/persistence/postgres/queries_test.go @@ -51,6 +51,40 @@ func TestNewPostgresAccessResource(t *testing.T) { } } +func TestCreatePostgresAccessTTL(t *testing.T) { + tests := []struct { + name string + ttl string + want time.Duration + wantErr string + }{ + {name: "default", want: time.Hour}, + {name: "requested", ttl: "4h", want: 4 * time.Hour}, + {name: "maximum", ttl: "8h", want: 8 * time.Hour}, + {name: "invalid", ttl: "tomorrow", wantErr: "TTL must be a Go duration"}, + {name: "zero", ttl: "0s", wantErr: "TTL must be positive"}, + {name: "too long", ttl: "8h1m", wantErr: "TTL cannot exceed 8h0m0s"}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := (CreatePostgresAccessInput{TTL: tt.ttl}).accessTTL() + if tt.wantErr != "" { + if err == nil || !strings.Contains(err.Error(), tt.wantErr) { + t.Errorf("accessTTL() error = %v, want containing %q", err, tt.wantErr) + } + return + } + if err != nil { + t.Fatalf("accessTTL() error = %v", err) + } + if got != tt.want { + t.Errorf("accessTTL() = %s, want %s", got, tt.want) + } + }) + } +} + func TestPostgresAccessState(t *testing.T) { future := time.Now().Add(time.Hour) past := time.Now().Add(-time.Hour) From bb6bcbed85563599d4264c83e71ccb94333aca59 Mon Sep 17 00:00:00 2001 From: Johnny Fredheim Horvi Date: Tue, 29 Sep 2026 06:52:46 +0200 Subject: [PATCH 07/19] Align Postgres API with Postgres and PostgresInstance CRDs --- .../console-backend-rbac/templates/rbac.yaml | 45 +- data/k8s/dev/devteam/postgres.yaml | 29 +- go.mod | 55 +- go.sum | 121 +- integration_tests/create_postgres_access.lua | 76 +- integration_tests/grant_postgres_access.lua | 343 +--- .../cnpg_cluster_foobar-recovered.yaml | 15 + .../dev/someteamname/cnpg_cluster_foobar.yaml | 15 + .../postgres_access_expired-access.yaml | 6 - .../postgres_access_failed-access.yaml | 1 - ...postgres_access_missing-secret-access.yaml | 10 +- .../postgres_access_pending-access.yaml | 6 - .../someteamname/postgres_access_ready.yaml | 13 +- .../postgres_access_recovered-access.yaml | 14 + .../dev/someteamname/postgres_foobar.yaml | 13 +- .../postgres_instance_foobar.yaml | 15 + .../postgres_instance_progressing.yaml | 15 + .../postgres_instance_recovered.yaml | 15 + .../someteamname/postgres_legacy-only.yaml | 8 + .../someteamname/postgres_progressing.yaml | 18 +- .../relay_access_missing_secret.yaml | 17 + .../dev/someteamname/relay_access_ready.yaml | 17 + .../dev/someteamname/secret_pg_foobar_ca.yaml | 8 + .../secret_ready_access_credentials.yaml | 9 +- .../secret_ready_access_relay_token.yaml | 14 + .../dev/someteamname/postgres_foobar.yaml | 15 - .../dev/labelteam/postgres.yaml | 87 +- .../postgres_with_audit.yaml | 31 +- .../dev/pg-delete-team/postgres.yaml | 25 + .../dev/someteamname/applications.yaml | 15 +- .../dev/someteamname/postgres_another_db.yaml | 29 +- .../dev/someteamname/postgres_foobar.yaml | 33 +- .../dev/someteamname/postgres_with_audit.yaml | 31 +- .../someteamname/postgres_without_audit.yaml | 31 +- .../dev/postgres-workload-team/resources.yaml | 62 + integration_tests/postgres_audit_log.lua | 78 +- integration_tests/postgres_delete.lua | 20 + integration_tests/postgres_instances.lua | 695 +------- integration_tests/postgres_workloads.lua | 36 + internal/apply/whitelist.go | 4 +- internal/cmd/api/http.go | 2 +- internal/graph/gengql/postgres.generated.go | 1476 ++++++----------- internal/graph/gengql/root_.generated.go | 628 +++---- internal/graph/gengql/schema.generated.go | 73 +- internal/graph/gengql/teams.generated.go | 95 ++ internal/graph/postgres.resolvers.go | 57 +- internal/graph/schema/postgres.graphqls | 150 +- internal/grpc/grpcdatabase/server.go | 2 +- internal/grpc/grpcdatabase/server_test.go | 8 +- .../testdata/dev-gcp/myteam/postgres.yaml | 57 +- internal/kubernetes/fake/fake.go | 4 +- .../kubernetes/fake/postgres_fixtures_test.go | 39 + internal/kubernetes/scheme.go | 16 +- internal/persistence/bigquery/models.go | 2 - internal/persistence/postgres/connection.go | 160 ++ .../persistence/postgres/connection_test.go | 66 + internal/persistence/postgres/dataloader.go | 12 +- internal/persistence/postgres/delete_test.go | 176 ++ internal/persistence/postgres/facets.go | 48 - internal/persistence/postgres/facets_test.go | 234 +-- internal/persistence/postgres/models.go | 317 ++-- internal/persistence/postgres/models_test.go | 263 +-- internal/persistence/postgres/node.go | 12 +- internal/persistence/postgres/queries.go | 426 ++--- internal/persistence/postgres/queries_test.go | 84 +- internal/persistence/postgres/search.go | 2 +- internal/persistence/postgres/sortfilter.go | 12 - internal/workload/secret/queries.go | 26 +- internal/workload/secret/queries_test.go | 27 + pkg/apiclient/protoapi/databases.pb.go | 29 +- .../protoapi/databases_protoopaque.pb.go | 29 +- pkg/apiclient/protoapi/schema/databases.proto | 2 +- 72 files changed, 2602 insertions(+), 4022 deletions(-) create mode 100644 integration_tests/k8s_resources/create_postgres_access/dev/someteamname/cnpg_cluster_foobar-recovered.yaml create mode 100644 integration_tests/k8s_resources/create_postgres_access/dev/someteamname/cnpg_cluster_foobar.yaml create mode 100644 integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_recovered-access.yaml create mode 100644 integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_instance_foobar.yaml create mode 100644 integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_instance_progressing.yaml create mode 100644 integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_instance_recovered.yaml create mode 100644 integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_legacy-only.yaml create mode 100644 integration_tests/k8s_resources/create_postgres_access/dev/someteamname/relay_access_missing_secret.yaml create mode 100644 integration_tests/k8s_resources/create_postgres_access/dev/someteamname/relay_access_ready.yaml create mode 100644 integration_tests/k8s_resources/create_postgres_access/dev/someteamname/secret_pg_foobar_ca.yaml create mode 100644 integration_tests/k8s_resources/create_postgres_access/dev/someteamname/secret_ready_access_relay_token.yaml delete mode 100644 integration_tests/k8s_resources/grant_zalando_postgres_access/dev/someteamname/postgres_foobar.yaml create mode 100644 integration_tests/k8s_resources/postgres_delete/dev/pg-delete-team/postgres.yaml create mode 100644 integration_tests/k8s_resources/postgres_workloads/dev/postgres-workload-team/resources.yaml create mode 100644 integration_tests/postgres_delete.lua create mode 100644 integration_tests/postgres_workloads.lua create mode 100644 internal/kubernetes/fake/postgres_fixtures_test.go create mode 100644 internal/persistence/postgres/connection.go create mode 100644 internal/persistence/postgres/connection_test.go create mode 100644 internal/persistence/postgres/delete_test.go create mode 100644 internal/workload/secret/queries_test.go diff --git a/charts/console-backend-rbac/templates/rbac.yaml b/charts/console-backend-rbac/templates/rbac.yaml index 79d7840d3..11e6d206d 100644 --- a/charts/console-backend-rbac/templates/rbac.yaml +++ b/charts/console-backend-rbac/templates/rbac.yaml @@ -126,6 +126,28 @@ rules: verbs: - get - create + - apiGroups: + - "nais.io" + resources: + - postgresinstances + verbs: + - get + - list + - watch + - delete + # Owner-only connection retrieval reads the mapping, not the relay's proof hash via status. + - apiGroups: + - "nais.io" + resources: + - relayaccesses + verbs: + - get + - apiGroups: + - postgresql.cnpg.io + resources: + - clusters + verbs: + - get - apiGroups: - "aiven.nais.io" resources: @@ -273,7 +295,7 @@ rules: - list - watch - apiGroups: - - "data.nais.io" + - "nais.io" resources: - postgres verbs: @@ -287,6 +309,27 @@ rules: verbs: - get - create + - apiGroups: + - "nais.io" + resources: + - postgresinstances + verbs: + - get + - list + - watch + - delete + - apiGroups: + - "nais.io" + resources: + - relayaccesses + verbs: + - get + - apiGroups: + - postgresql.cnpg.io + resources: + - clusters + verbs: + - get - apiGroups: - "" resources: diff --git a/data/k8s/dev/devteam/postgres.yaml b/data/k8s/dev/devteam/postgres.yaml index 20069a296..8930a6aed 100644 --- a/data/k8s/dev/devteam/postgres.yaml +++ b/data/k8s/dev/devteam/postgres.yaml @@ -1,5 +1,16 @@ -apiVersion: data.nais.io/v1 +--- +apiVersion: nais.io/v1 kind: Postgres +metadata: + name: postgres-1 + namespace: devteam +spec: + majorVersion: "18" +status: + activeInstance: postgres-1 +--- +apiVersion: nais.io/v1 +kind: PostgresInstance metadata: name: postgres-1 namespace: devteam @@ -7,10 +18,12 @@ metadata: key: value team: devteam spec: - cluster: - allowDeletion: false - majorVersion: "18" - resources: - diskSize: "2Gi" - cpu: "100m" - memory: "1Gi" + postgres: postgres-1 +status: + reconcilePhase: Completed + conditions: + - type: cluster.postgresql.cnpg.io/ObservedState + status: "True" + reason: Reconciled + message: "Cluster is in phase: Cluster in healthy state" + lastTransitionTime: "2026-09-17T00:00:00Z" diff --git a/go.mod b/go.mod index a64d648b3..e08a92fae 100644 --- a/go.mod +++ b/go.mod @@ -40,7 +40,7 @@ require ( github.com/lestrrat-go/jwx/v3 v3.0.1 github.com/nais/api/pkg/apiclient v0.0.0-20250219111538-2b76a0fd6ed9 github.com/nais/bifrost v0.0.0-20260106105449-911627ac2c61 - github.com/nais/liberator v0.0.0-20260216142648-ee49a9372bc4 + github.com/nais/liberator v0.0.0-20260903194126-706ea87ddf9a github.com/nais/pgrator/pkg/api v0.0.0-20260915202302-d699a2823ec5 github.com/nais/tester v0.2.0 github.com/nais/unleasherator v0.0.0-20251216221129-efebc54203fe @@ -48,15 +48,15 @@ require ( github.com/patrickmn/go-cache v2.1.0+incompatible github.com/pressly/goose/v3 v3.27.0 github.com/prometheus/client_golang v1.23.2 - github.com/prometheus/common v0.67.5 + github.com/prometheus/common v0.69.0 github.com/prometheus/prometheus v0.312.0 github.com/ravilushqa/otelgqlgen v0.19.0 github.com/robfig/cron/v3 v3.0.1 github.com/rs/cors v1.11.1 github.com/sethvargo/go-envconfig v1.3.0 - github.com/sirupsen/logrus v1.9.4 + github.com/sirupsen/logrus v1.10.2 github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 - github.com/stretchr/testify v1.11.1 + github.com/stretchr/testify v1.12.1 github.com/testcontainers/testcontainers-go v0.35.0 github.com/testcontainers/testcontainers-go/modules/postgres v0.35.0 github.com/vektah/gqlparser/v2 v2.5.33 @@ -83,9 +83,9 @@ require ( google.golang.org/genproto/googleapis/api v0.0.0-20260630182238-925bb5da69e7 google.golang.org/grpc v1.83.1 google.golang.org/protobuf v1.36.12 - k8s.io/api v0.36.0 + k8s.io/api v0.36.2 k8s.io/apimachinery v0.36.4 - k8s.io/client-go v0.36.0 + k8s.io/client-go v0.36.2 k8s.io/klog/v2 v2.140.0 k8s.io/utils v0.0.0-20260707023825-cf1189d6abe3 sigs.k8s.io/yaml v1.6.0 @@ -189,37 +189,37 @@ require ( github.com/envoyproxy/protoc-gen-validate v1.3.3 // indirect github.com/evanphx/json-patch v5.9.0+incompatible // indirect github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb // indirect - github.com/fatih/color v1.18.0 // indirect + github.com/fatih/color v1.19.0 // indirect github.com/fatih/structs v1.1.0 // indirect github.com/fatih/structtag v1.2.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.10.1 // indirect - github.com/fxamacker/cbor/v2 v2.9.0 // indirect + github.com/fxamacker/cbor/v2 v2.9.2 // indirect github.com/go-jose/go-jose/v4 v4.1.4 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.6.1 // indirect - github.com/go-logr/logr v1.4.3 // indirect + github.com/go-logr/logr v1.4.4 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.3.0 // indirect github.com/go-openapi/analysis v0.25.0 // indirect github.com/go-openapi/errors v0.22.7 // indirect - github.com/go-openapi/jsonpointer v0.23.1 // indirect - github.com/go-openapi/jsonreference v0.21.5 // indirect + github.com/go-openapi/jsonpointer v0.24.0 // indirect + github.com/go-openapi/jsonreference v0.21.6 // indirect github.com/go-openapi/loads v0.23.3 // indirect github.com/go-openapi/spec v0.22.4 // indirect github.com/go-openapi/strfmt v0.26.2 // indirect - github.com/go-openapi/swag v0.25.5 // indirect - github.com/go-openapi/swag/cmdutils v0.25.5 // indirect - github.com/go-openapi/swag/conv v0.25.5 // indirect - github.com/go-openapi/swag/fileutils v0.25.5 // indirect + github.com/go-openapi/swag v0.27.0 // indirect + github.com/go-openapi/swag/cmdutils v0.27.0 // indirect + github.com/go-openapi/swag/conv v0.27.0 // indirect + github.com/go-openapi/swag/fileutils v0.27.0 // indirect github.com/go-openapi/swag/jsonname v0.26.0 // indirect - github.com/go-openapi/swag/jsonutils v0.25.5 // indirect - github.com/go-openapi/swag/loading v0.25.5 // indirect - github.com/go-openapi/swag/mangling v0.25.5 // indirect - github.com/go-openapi/swag/netutils v0.25.5 // indirect - github.com/go-openapi/swag/stringutils v0.25.5 // indirect - github.com/go-openapi/swag/typeutils v0.25.5 // indirect - github.com/go-openapi/swag/yamlutils v0.25.5 // indirect + github.com/go-openapi/swag/jsonutils v0.27.0 // indirect + github.com/go-openapi/swag/loading v0.27.0 // indirect + github.com/go-openapi/swag/mangling v0.27.0 // indirect + github.com/go-openapi/swag/netutils v0.27.0 // indirect + github.com/go-openapi/swag/stringutils v0.27.0 // indirect + github.com/go-openapi/swag/typeutils v0.27.0 // indirect + github.com/go-openapi/swag/yamlutils v0.27.0 // indirect github.com/go-openapi/validate v0.25.2 // indirect github.com/go-sql-driver/mysql v1.9.3 // indirect github.com/go-viper/mapstructure/v2 v2.5.0 // indirect @@ -270,7 +270,6 @@ require ( github.com/hashicorp/memberlist v0.5.4 // indirect github.com/hashicorp/serf v0.10.2 // indirect github.com/huandu/xstrings v1.5.0 // indirect - github.com/imdario/mergo v0.3.16 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/influxdata/tdigest v0.0.2-0.20210216194612-fc98d27c9e8b // indirect github.com/invopop/jsonschema v0.13.0 // indirect @@ -359,7 +358,7 @@ require ( github.com/prometheus/client_model v0.6.2 // indirect github.com/prometheus/exporter-toolkit v0.16.0 // indirect github.com/prometheus/otlptranslator v1.0.0 // indirect - github.com/prometheus/procfs v0.19.2 // indirect + github.com/prometheus/procfs v0.21.1 // indirect github.com/prometheus/sigv4 v0.4.1 // indirect github.com/puzpuzpuz/xsync/v4 v4.5.0 // indirect github.com/redis/go-redis/v9 v9.18.0 // indirect @@ -444,7 +443,7 @@ require ( go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.28.0 // indirect go.yaml.in/yaml/v2 v2.4.4 // indirect - go.yaml.in/yaml/v3 v3.0.4 // indirect + go.yaml.in/yaml/v3 v3.0.5 // indirect go.yaml.in/yaml/v4 v4.0.0-rc.4 // indirect go4.org/netipx v0.0.0-20230125063823-8449b0a6169f // indirect golang.org/x/crypto v0.54.0 // indirect @@ -467,13 +466,13 @@ require ( gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect honnef.co/go/tools v0.7.0 // indirect - k8s.io/apiextensions-apiserver v0.36.0 // indirect - k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a // indirect + k8s.io/apiextensions-apiserver v0.36.2 // indirect + k8s.io/kube-openapi v0.0.0-20260624041617-8f3fa4921821 // indirect mvdan.cc/gofumpt v0.9.2 // indirect sigs.k8s.io/controller-runtime v0.24.1 // indirect sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/randfill v1.0.0 // indirect - sigs.k8s.io/structured-merge-diff/v6 v6.3.3 // indirect + sigs.k8s.io/structured-merge-diff/v6 v6.4.0 // indirect ) replace github.com/GoogleCloudPlatform/k8s-config-connector/mockgcp => ./mockgcp diff --git a/go.sum b/go.sum index b280fb940..7016f6add 100644 --- a/go.sum +++ b/go.sum @@ -341,8 +341,8 @@ github.com/exaring/otelpgx v0.9.0/go.mod h1:ANkRZDfgfmN6yJS1xKMkshbnsHO8at5sYwtV github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb h1:IT4JYU7k4ikYg1SCxNI1/Tieq/NFvh6dzLdgi7eu0tM= github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb/go.mod h1:bH6Xx7IW64qjjJq8M2u4dxNaBiDfKK+z/3eGDpXEQhc= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM= -github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU= +github.com/fatih/color v1.19.0 h1:Zp3PiM21/9Ld6FzSKyL5c/BULoe/ONr9KlbYVOfG8+w= +github.com/fatih/color v1.19.0/go.mod h1:zNk67I0ZUT1bEGsSGyCZYZNrHuTkJJB+r6Q9VuMi0LE= github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4= @@ -354,8 +354,8 @@ github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7z github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.10.1 h1:b0/UzAf9yR5rhf3RPm9gf3ehBPpf0oZKIjtpKrx59Ho= github.com/fsnotify/fsnotify v1.10.1/go.mod h1:TLheqan6HD6GBK6PrDWyDPBaEV8LspOxvPSjC+bVfgo= -github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM= -github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= +github.com/fxamacker/cbor/v2 v2.9.2 h1:X4Ksno9+x3cz0TZv69ec1hxP/+tymuR8PXQJyDwfh78= +github.com/fxamacker/cbor/v2 v2.9.2/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= github.com/go-chi/chi/v5 v5.2.4 h1:WtFKPHwlywe8Srng8j2BhOD9312j9cGUxG1SP4V2cR4= github.com/go-chi/chi/v5 v5.2.4/go.mod h1:X7Gx4mteadT3eDOMTsXzmI4/rwUpOwBHLpAfupzFJP0= github.com/go-jose/go-jose/v4 v4.1.4 h1:moDMcTHmvE6Groj34emNPLs/qtYXRVcd6S7NHbHz3kA= @@ -372,8 +372,8 @@ github.com/go-logfmt/logfmt v0.6.1 h1:4hvbpePJKnIzH1B+8OR/JPbTx37NktoI9LE2QZBBkv github.com/go-logfmt/logfmt v0.6.1/go.mod h1:EV2pOAQoZaT1ZXZbqDl5hrymndi4SY9ED9/z6CO0XAk= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.3.0/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= -github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= -github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.4 h1:tG4xh9yMsRCAiodLVTxyrkzSZ9+o0L1Kg/+cPVcbP/8= +github.com/go-logr/logr v1.4.4/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-logr/zapr v1.3.0 h1:XGdV8XW8zdwFiwOA2Dryh1gj2KRQyOOoNmBy4EplIcQ= @@ -385,46 +385,46 @@ github.com/go-openapi/analysis v0.25.0 h1:EnjAq1yO8wEO9HbPmY8vLPEIkdZuuFhCAKBPvC github.com/go-openapi/analysis v0.25.0/go.mod h1:5WFTRE43WLkPG9r9OtlMfqkkvUTYLVVCIxLlEpyF8kE= github.com/go-openapi/errors v0.22.7 h1:JLFBGC0Apwdzw3484MmBqspjPbwa2SHvpDm0u5aGhUA= github.com/go-openapi/errors v0.22.7/go.mod h1://QW6SD9OsWtH6gHllUCddOXDL0tk0ZGNYHwsw4sW3w= -github.com/go-openapi/jsonpointer v0.23.1 h1:1HBACs7XIwR2RcmItfdSFlALhGbe6S92p0ry4d1GWg4= -github.com/go-openapi/jsonpointer v0.23.1/go.mod h1:iWRmZTrGn7XwYhtPt/fvdSFj1OfNBngqRT2UG3BxSqY= -github.com/go-openapi/jsonreference v0.21.5 h1:6uCGVXU/aNF13AQNggxfysJ+5ZcU4nEAe+pJyVWRdiE= -github.com/go-openapi/jsonreference v0.21.5/go.mod h1:u25Bw85sX4E2jzFodh1FOKMTZLcfifd1Q+iKKOUxExw= +github.com/go-openapi/jsonpointer v0.24.0 h1:AA6mCjHYHmZ+1RU2Js089EaOK/iwXXNwQsTgnsTha2M= +github.com/go-openapi/jsonpointer v0.24.0/go.mod h1:Z3rw7dWu1p9IgitXCFamSlA5lmDiklEB6vkaxcNZW5Y= +github.com/go-openapi/jsonreference v0.21.6 h1:NZ5nGfnaM1n4I43Xjm1e5/M2GjOwQwndQz22uhxwD+Y= +github.com/go-openapi/jsonreference v0.21.6/go.mod h1:xzbgtQ3ZbWxvET3AxdzCJlJt6vkovbf+IfSPJjD0tUY= github.com/go-openapi/loads v0.23.3 h1:g5Xap1JfwKkUnZdn+S0L3SzBDpcTIYzZ5Qaag0YDkKQ= github.com/go-openapi/loads v0.23.3/go.mod h1:NOH07zLajXo8y55hom0omlHWDVVvCwBM/S+csCK8LqA= github.com/go-openapi/spec v0.22.4 h1:4pxGjipMKu0FzFiu/DPwN3CTBRlVM2yLf/YTWorYfDQ= github.com/go-openapi/spec v0.22.4/go.mod h1:WQ6Ai0VPWMZgMT4XySjlRIE6GP1bGQOtEThn3gcWLtQ= github.com/go-openapi/strfmt v0.26.2 h1:ysjheCh4i1rmFEo2LanhELDNucNzfWTZhUDKgWWPaFM= github.com/go-openapi/strfmt v0.26.2/go.mod h1:fXh1e449cyUn2NYuz+wb3wARBUdMl7qPEZwX00nqivY= -github.com/go-openapi/swag v0.25.5 h1:pNkwbUEeGwMtcgxDr+2GBPAk4kT+kJ+AaB+TMKAg+TU= -github.com/go-openapi/swag v0.25.5/go.mod h1:B3RT6l8q7X803JRxa2e59tHOiZlX1t8viplOcs9CwTA= -github.com/go-openapi/swag/cmdutils v0.25.5 h1:yh5hHrpgsw4NwM9KAEtaDTXILYzdXh/I8Whhx9hKj7c= -github.com/go-openapi/swag/cmdutils v0.25.5/go.mod h1:pdae/AFo6WxLl5L0rq87eRzVPm/XRHM3MoYgRMvG4A0= -github.com/go-openapi/swag/conv v0.25.5 h1:wAXBYEXJjoKwE5+vc9YHhpQOFj2JYBMF2DUi+tGu97g= -github.com/go-openapi/swag/conv v0.25.5/go.mod h1:CuJ1eWvh1c4ORKx7unQnFGyvBbNlRKbnRyAvDvzWA4k= -github.com/go-openapi/swag/fileutils v0.25.5 h1:B6JTdOcs2c0dBIs9HnkyTW+5gC+8NIhVBUwERkFhMWk= -github.com/go-openapi/swag/fileutils v0.25.5/go.mod h1:V3cT9UdMQIaH4WiTrUc9EPtVA4txS0TOmRURmhGF4kc= +github.com/go-openapi/swag v0.27.0 h1:8ecSuZlh4NXc3GsmAOqECIYqDTApCWaMe3gO4gjJNEE= +github.com/go-openapi/swag v0.27.0/go.mod h1:Kkgz9Ht0+ul9/aVdFmc9xSyPzUwf/aFF5KiFPBXfSY0= +github.com/go-openapi/swag/cmdutils v0.27.0 h1:aIKiqhB29AaP+7xm8/CPg3uOpeHx2SUp6TvMpu/a31Y= +github.com/go-openapi/swag/cmdutils v0.27.0/go.mod h1:Sm1MVFMkF6guJJ+pQqHnQA3N0j9qALV3NxzDSv6bETM= +github.com/go-openapi/swag/conv v0.27.0 h1:EKOH4feXrvdo8DbSsXSAqRT8fz1epEnS5O2IfXUOzE8= +github.com/go-openapi/swag/conv v0.27.0/go.mod h1:pfiv0uKQTbaGApk8Zs/lZV3uSjmSpa2FO1y183YngN8= +github.com/go-openapi/swag/fileutils v0.27.0 h1:ib5jMUqGq5tY1EyO4inlrabsaeDAleFU+XD1FXQcgp8= +github.com/go-openapi/swag/fileutils v0.27.0/go.mod h1:VvJFZLTZS0AI854gEQz5tk7dBESdLjiNUMSZ/th2ry8= github.com/go-openapi/swag/jsonname v0.26.0 h1:gV1NFX9M8avo0YSpmWogqfQISigCmpaiNci8cGECU5w= github.com/go-openapi/swag/jsonname v0.26.0/go.mod h1:urBBR8bZNoDYGr653ynhIx+gTeIz0ARZxHkAPktJK2M= -github.com/go-openapi/swag/jsonutils v0.25.5 h1:XUZF8awQr75MXeC+/iaw5usY/iM7nXPDwdG3Jbl9vYo= -github.com/go-openapi/swag/jsonutils v0.25.5/go.mod h1:48FXUaz8YsDAA9s5AnaUvAmry1UcLcNVWUjY42XkrN4= -github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.5 h1:SX6sE4FrGb4sEnnxbFL/25yZBb5Hcg1inLeErd86Y1U= -github.com/go-openapi/swag/jsonutils/fixtures_test v0.25.5/go.mod h1:/2KvOTrKWjVA5Xli3DZWdMCZDzz3uV/T7bXwrKWPquo= -github.com/go-openapi/swag/loading v0.25.5 h1:odQ/umlIZ1ZVRteI6ckSrvP6e2w9UTF5qgNdemJHjuU= -github.com/go-openapi/swag/loading v0.25.5/go.mod h1:I8A8RaaQ4DApxhPSWLNYWh9NvmX2YKMoB9nwvv6oW6g= -github.com/go-openapi/swag/mangling v0.25.5 h1:hyrnvbQRS7vKePQPHHDso+k6CGn5ZBs5232UqWZmJZw= -github.com/go-openapi/swag/mangling v0.25.5/go.mod h1:6hadXM/o312N/h98RwByLg088U61TPGiltQn71Iw0NY= -github.com/go-openapi/swag/netutils v0.25.5 h1:LZq2Xc2QI8+7838elRAaPCeqJnHODfSyOa7ZGfxDKlU= -github.com/go-openapi/swag/netutils v0.25.5/go.mod h1:lHbtmj4m57APG/8H7ZcMMSWzNqIQcu0RFiXrPUara14= -github.com/go-openapi/swag/stringutils v0.25.5 h1:NVkoDOA8YBgtAR/zvCx5rhJKtZF3IzXcDdwOsYzrB6M= -github.com/go-openapi/swag/stringutils v0.25.5/go.mod h1:PKK8EZdu4QJq8iezt17HM8RXnLAzY7gW0O1KKarrZII= -github.com/go-openapi/swag/typeutils v0.25.5 h1:EFJ+PCga2HfHGdo8s8VJXEVbeXRCYwzzr9u4rJk7L7E= -github.com/go-openapi/swag/typeutils v0.25.5/go.mod h1:itmFmScAYE1bSD8C4rS0W+0InZUBrB2xSPbWt6DLGuc= -github.com/go-openapi/swag/yamlutils v0.25.5 h1:kASCIS+oIeoc55j28T4o8KwlV2S4ZLPT6G0iq2SSbVQ= -github.com/go-openapi/swag/yamlutils v0.25.5/go.mod h1:Gek1/SjjfbYvM+Iq4QGwa/2lEXde9n2j4a3wI3pNuOQ= -github.com/go-openapi/testify/enable/yaml/v2 v2.4.1 h1:NZOrZmIb6PTv5LTFxr5/mKV/FjbUzGE7E6gLz7vFoOQ= -github.com/go-openapi/testify/enable/yaml/v2 v2.4.1/go.mod h1:r7dwsujEHawapMsxA69i+XMGZrQ5tRauhLAjV/sxg3Q= -github.com/go-openapi/testify/v2 v2.4.2 h1:tiByHpvE9uHrrKjOszax7ZvKB7QOgizBWGBLuq0ePx4= -github.com/go-openapi/testify/v2 v2.4.2/go.mod h1:SgsVHtfooshd0tublTtJ50FPKhujf47YRqauXXOUxfw= +github.com/go-openapi/swag/jsonutils v0.27.0 h1:VYtd9jEQYeU4j8q5vdn5KWotF4vKywhGdMBrALtAsfE= +github.com/go-openapi/swag/jsonutils v0.27.0/go.mod h1:U7pb8AGuwhok3RDicHeHwSG4L3PXSq6PAL98Aon632g= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.27.0 h1:+d7C7Ur/SsGg/UZ9G0JEovnfRqtMNZCJQGKc2h/ojoE= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.27.0/go.mod h1:mofwUWx70wvskwESqRJ//k/9kURmCgyJl5m5Ppoh5kY= +github.com/go-openapi/swag/loading v0.27.0 h1:s8DA9aPEdFH6OluHUYUn3DnIuoTdyWs9RwffXBUfyeI= +github.com/go-openapi/swag/loading v0.27.0/go.mod h1:VOz+Jg6UGGywcmRvYsI4fvtp+bd7NfioseGEPleYdA4= +github.com/go-openapi/swag/mangling v0.27.0 h1:rpPJuqQHa6z2pDiP3iIpXOyNXlSs9cQCxnJSAxzdfOc= +github.com/go-openapi/swag/mangling v0.27.0/go.mod h1:jtBE2+V+3pILxOR7Vgce+Cwp6A2PgZbvVqfNntbVs0w= +github.com/go-openapi/swag/netutils v0.27.0 h1:lEUG+hHvPvLggB3A8snFk0IRKNf9uC0YKc+7WYqvAF8= +github.com/go-openapi/swag/netutils v0.27.0/go.mod h1:J+WYyFMLtvtCGqa6jLv+YNUmIKI3ZRQRrvfNDMoQoEQ= +github.com/go-openapi/swag/stringutils v0.27.0 h1:Of7w/HljWsNZvuxsUAnw3n+hCOyI6HLJOxW2kQRAxio= +github.com/go-openapi/swag/stringutils v0.27.0/go.mod h1:lzRN95CxXmA03XcDWHLOb6nOMcxCqR5rGY0lOgsfRoM= +github.com/go-openapi/swag/typeutils v0.27.0 h1:aCf4MSGo8NLwZP8Q6t32DWLJSvl/WwNqgmEG+xJ6v2o= +github.com/go-openapi/swag/typeutils v0.27.0/go.mod h1:Srm0xFNRZ1Y+vCxJclo5qzx8aj+1pAKda/YfFPrG0dQ= +github.com/go-openapi/swag/yamlutils v0.27.0 h1:bQ6eAMil5X9tdcf7dMn4t15alzG6jddnrKPuKa/zxKM= +github.com/go-openapi/swag/yamlutils v0.27.0/go.mod h1:yRfIo7qqVkmJRQjX8exjA3AfcI8rH1KDNPsTparoCv4= +github.com/go-openapi/testify/enable/yaml/v2 v2.6.0 h1:gGHwAJ0R/5jU8BEGDbfRNR3hL68dAVi84WuOApp29B0= +github.com/go-openapi/testify/enable/yaml/v2 v2.6.0/go.mod h1:tY+St1SGq4NFl0QIqdTY4aEdbChAHxhyB77XQi9iJCo= +github.com/go-openapi/testify/v2 v2.6.0 h1:5PKH2HE7YJ/LuRPQGvSxBRlFXNQhSetBLlGAgUEu3ug= +github.com/go-openapi/testify/v2 v2.6.0/go.mod h1:SgsVHtfooshd0tublTtJ50FPKhujf47YRqauXXOUxfw= github.com/go-openapi/validate v0.25.2 h1:12NsfLAwGegqbGWr2CnvT65X/Q2USJipmJ9b7xDJZz0= github.com/go-openapi/validate v0.25.2/go.mod h1:Pgl1LpPPGFnZ+ys4/hTlDiRYQdI1ocKypgE+8Q8BLfY= github.com/go-quicktest/qt v1.101.0 h1:O1K29Txy5P2OK0dGo59b7b0LR6wKfIhttaAhHUyn7eI= @@ -607,8 +607,6 @@ github.com/hetznercloud/hcloud-go/v2 v2.41.2/go.mod h1:9OGvC//jbHE4sv2Oyo0bQ2vEW github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI= github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= -github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4= -github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY= github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/influxdata/tdigest v0.0.2-0.20210216194612-fc98d27c9e8b h1:i44CesU68ZBRvtCjBi3QSosCIKrjmMbYlQMFAwVLds4= @@ -805,8 +803,8 @@ github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+ github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nais/bifrost v0.0.0-20260106105449-911627ac2c61 h1:DMIjq7U47OJ8GlgOR3Z6kMzIWm7f+r8jzYbyE1oYCrg= github.com/nais/bifrost v0.0.0-20260106105449-911627ac2c61/go.mod h1:sAeomjrnGAI9VAErCaOHbTehVkf6hhKoJpHL8uzOqGg= -github.com/nais/liberator v0.0.0-20260216142648-ee49a9372bc4 h1:i7jBukqLtNpQIBhy/YBA8XjLRVdI8B7WxC9nhQyxlWE= -github.com/nais/liberator v0.0.0-20260216142648-ee49a9372bc4/go.mod h1:jmMoQtUMhvv7j1C2gz89Gxc4hxc73GXtTR3mEXn7cvU= +github.com/nais/liberator v0.0.0-20260903194126-706ea87ddf9a h1:GAIHGbZVhT5Yzx/NrYWdLxlsn+IaqXetGm4zsnJW5hU= +github.com/nais/liberator v0.0.0-20260903194126-706ea87ddf9a/go.mod h1:11Mi+k5w8IcdmgNwk6gORoBhHR9Ua4I9UtI8uljg4kc= github.com/nais/pgrator/pkg/api v0.0.0-20260915202302-d699a2823ec5 h1:7VBS6QIP1BTG3i9OLW1J1ekbd+yh6XIGfmAlM8BSQFU= github.com/nais/pgrator/pkg/api v0.0.0-20260915202302-d699a2823ec5/go.mod h1:kjcHI6Uh4++6CEsQf8JeGKE37XrY+ffhoaQv3jn0qAc= github.com/nais/tester v0.2.0 h1:lcTkDP52ddw9l5s3KC4snUP+GlUpZMUtJ3XR2vF4G0w= @@ -921,8 +919,8 @@ github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.67.5 h1:pIgK94WWlQt1WLwAC5j2ynLaBRDiinoAb86HZHTUGI4= -github.com/prometheus/common v0.67.5/go.mod h1:SjE/0MzDEEAyrdr5Gqc6G+sXI67maCxzaT3A2+HqjUw= +github.com/prometheus/common v0.69.0 h1:OA85nJQS/T/MaYh/Q2CcgDKSGWqNIgrBDvDH85CuiNk= +github.com/prometheus/common v0.69.0/go.mod h1:ZzL3f6u94qUxh9p+tJTrF+FvBS1XXbbRAZCQkytAL0Y= github.com/prometheus/common/sigv4 v0.1.0 h1:qoVebwtwwEhS85Czm2dSROY5fTo2PAPEVdDeppTwGX4= github.com/prometheus/common/sigv4 v0.1.0/go.mod h1:2Jkxxk9yYvCkE5G1sQT7GuEXm57JrvHu9k5YwTjsNtI= github.com/prometheus/exporter-toolkit v0.16.0 h1:xT/j7L2XKF+VJd6B4fpUw6xWabHrSmsUf6mYmFqyu0s= @@ -934,8 +932,8 @@ github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsT github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.19.2 h1:zUMhqEW66Ex7OXIiDkll3tl9a1ZdilUOd/F6ZXw4Vws= -github.com/prometheus/procfs v0.19.2/go.mod h1:M0aotyiemPhBCM0z5w87kL22CxfcH05ZpYlu+b4J7mw= +github.com/prometheus/procfs v0.21.1 h1:GljZCt+zSTS+NZq88cyQ1LjZ+RCHp3uVuabBWA5+OJI= +github.com/prometheus/procfs v0.21.1/go.mod h1:aB55Cww9pdSJVHk0hUf0inxWyyjPogFIjmHKYgMKmtY= github.com/prometheus/prometheus v0.312.0 h1:f9jdv2fQhQ1fks9a9YwlGZrKr4hih0rRP/rh0mu3Q18= github.com/prometheus/prometheus v0.312.0/go.mod h1:8oAYd2XPgHXLP4fFKam594R/ZLlPicrrBkVdaWt74Sw= github.com/prometheus/sigv4 v0.4.1 h1:EIc3j+8NBea9u1iV6O5ZAN8uvPq2xOIUPcqCTivHuXs= @@ -993,8 +991,8 @@ github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+D github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= -github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w= -github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g= +github.com/sirupsen/logrus v1.10.2 h1:G2SED73/qrAu6YwbdxOD6peLkCBI3z7L+ykJFTXJBBo= +github.com/sirupsen/logrus v1.10.2/go.mod h1:SLEg8TqYulVKKfIGHldVp2K2aYz2DKSVBq4g/H5bR7Q= github.com/sony/gobreaker/v2 v2.4.0 h1:g2KJRW1Ubty3+ZOcSEUN7K+REQJdN6yo6XvaML+jptg= github.com/sony/gobreaker/v2 v2.4.0/go.mod h1:pTyFJgcZ3h2tdQVLZZruK2C0eoFL1fb/G83wK1ZQl+s= github.com/sosodev/duration v1.4.0 h1:35ed0KiVFriGHHzZZJaZLgmTEEICIyt8Sx0RQfj9IjE= @@ -1035,8 +1033,8 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= -github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/stretchr/testify v1.12.1 h1:EuwCh5fleGS7H32xRwO3wRGT7DxrDhLAT6FF8MpWDWE= +github.com/stretchr/testify v1.12.1/go.mod h1:MDEgiDPPsNp5cuIrHPPCyornHKgEVbtFUmoNlxoYthg= github.com/testcontainers/testcontainers-go v0.35.0 h1:uADsZpTKFAtp8SLK+hMwSaa+X+JiERHtd4sQAFmXeMo= github.com/testcontainers/testcontainers-go v0.35.0/go.mod h1:oEVBj5zrfJTrgjwONs1SsRbnBtH9OKl+IGl3UMcr2B4= github.com/testcontainers/testcontainers-go/modules/postgres v0.35.0 h1:eEGx9kYzZb2cNhRbBrNOCL/YPOM7+RMJiy3bB+ie0/I= @@ -1256,8 +1254,9 @@ go.uber.org/zap v1.28.0 h1:IZzaP1Fv73/T/pBMLk4VutPl36uNC+OSUh3JLG3FIjo= go.uber.org/zap v1.28.0/go.mod h1:rDLpOi171uODNm/mxFcuYWxDsqWSAVkFdX4XojSKg/Q= go.yaml.in/yaml/v2 v2.4.4 h1:tuyd0P+2Ont/d6e2rl3be67goVK4R6deVxCUX5vyPaQ= go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ= -go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +go.yaml.in/yaml/v3 v3.0.5 h1:N6y/pJk8buWs9NY5ERU2HSMfm+IuD/OtfdAnq6kESPw= +go.yaml.in/yaml/v3 v3.0.5/go.mod h1:HVTZu1O7/Vkt2N+BFy8Zza+lnLsABggaTM2ZpNIGuKg= go.yaml.in/yaml/v4 v4.0.0-rc.4 h1:UP4+v6fFrBIb1l934bDl//mmnoIZEDK0idg1+AIvX5U= go.yaml.in/yaml/v4 v4.0.0-rc.4/go.mod h1:aZqd9kCMsGL7AuUv/m/PvWLdg5sjJsZ4oHDEnfPPfY0= go4.org/netipx v0.0.0-20230125063823-8449b0a6169f h1:ketMxHg+vWm3yccyYiq+uK8D3fRmna2Fcj+awpQp84s= @@ -1460,18 +1459,18 @@ honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.7.0 h1:w6WUp1VbkqPEgLz4rkBzH/CSU6HkoqNLp6GstyTx3lU= honnef.co/go/tools v0.7.0/go.mod h1:pm29oPxeP3P82ISxZDgIYeOaf9ta6Pi0EWvCFoLG2vc= -k8s.io/api v0.36.0 h1:SgqDhZzHdOtMk40xVSvCXkP9ME0H05hPM3p9AB1kL80= -k8s.io/api v0.36.0/go.mod h1:m1LVrGPNYax5NBHdO+QuAedXyuzTt4RryI/qnmNvs34= -k8s.io/apiextensions-apiserver v0.36.0 h1:Wt7E8J+VBCbj4FjiBfDTK/neXDDjyJVJc7xfuOHImZ0= -k8s.io/apiextensions-apiserver v0.36.0/go.mod h1:kGDjH0msuiIB3tgsYRV0kS9GqpMYMUsQ3GHv7TApyug= +k8s.io/api v0.36.2 h1:TF6YDLIzKfccK7cq9YpTcGX8TJmEkHVRv78DM51fRYY= +k8s.io/api v0.36.2/go.mod h1:F4LbMO4brjZYh7yFkXWhynSvtB7YauxV4c+HHkNRGNg= +k8s.io/apiextensions-apiserver v0.36.2 h1:3O5gqOj/dt2XWWbpMe+TXWpE9yU6pjM/tXxtHHJT/K4= +k8s.io/apiextensions-apiserver v0.36.2/go.mod h1:cL1tBWe8XSaP1H30iWKGo7hf6iAUUUJPEU70dskmAnA= k8s.io/apimachinery v0.36.4 h1:PT2UzkupGuAx/+xT5XjiMJ1WGpY3fn9/hdAvjweRet4= k8s.io/apimachinery v0.36.4/go.mod h1:p2I2dipt7JHG+quVwQ1d02d28O4GdDi77RByQ13MTpk= -k8s.io/client-go v0.36.0 h1:pOYi7C4RHChYjMiHpZSpSbIM6ZxVbRXBy7CuiIwqA3c= -k8s.io/client-go v0.36.0/go.mod h1:ZKKcpwF0aLYfkHFCjillCKaTK/yBkEDHTDXCFY6AS9Y= +k8s.io/client-go v0.36.2 h1:bfgxmFKc9CgqsgX4xKLAAdmTQlWee7Ob/HlDOrJ5TBI= +k8s.io/client-go v0.36.2/go.mod h1:1vgO4OAlfPnoLcb+Rze2GF5rAr14w8qjrYMoyXJzQj0= k8s.io/klog/v2 v2.140.0 h1:Tf+J3AH7xnUzZyVVXhTgGhEKnFqye14aadWv7bzXdzc= k8s.io/klog/v2 v2.140.0/go.mod h1:o+/RWfJ6PwpnFn7OyAG3QnO47BFsymfEfrz6XyYSSp0= -k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a h1:xCeOEAOoGYl2jnJoHkC3hkbPJgdATINPMAxaynU2Ovg= -k8s.io/kube-openapi v0.0.0-20260317180543-43fb72c5454a/go.mod h1:uGBT7iTA6c6MvqUvSXIaYZo9ukscABYi2btjhvgKGZ0= +k8s.io/kube-openapi v0.0.0-20260624041617-8f3fa4921821 h1:m2wZhD5+vJZyCVkTvUHIfaiXc/mdt3Pxyx3vUnGsKzU= +k8s.io/kube-openapi v0.0.0-20260624041617-8f3fa4921821/go.mod h1:V/QaCUYDa+0QpcHhVVc5l99Uz56wEMEXBSj9oCDkNDY= k8s.io/utils v0.0.0-20260707023825-cf1189d6abe3 h1:jVkFFVfXdXP74B/zbO3hM3hpSFD0xvhQ5U686DPurkE= k8s.io/utils v0.0.0-20260707023825-cf1189d6abe3/go.mod h1:M2s5JB1lIYP3jzZdorPLHXIPJzt9vv2muW5a6L9DtNM= modernc.org/libc v1.68.0 h1:PJ5ikFOV5pwpW+VqCK1hKJuEWsonkIJhhIXyuF/91pQ= @@ -1490,7 +1489,7 @@ sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5E sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= -sigs.k8s.io/structured-merge-diff/v6 v6.3.3 h1:u08YRbVUi59ri4YD6cg0UqNM4Dimn0sIl+wldcx5PYw= -sigs.k8s.io/structured-merge-diff/v6 v6.3.3/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= +sigs.k8s.io/structured-merge-diff/v6 v6.4.0 h1:qmp2e3ZfFi1/jJbDGpD4mt3wyp6PE1NfKHCYLqgNQJo= +sigs.k8s.io/structured-merge-diff/v6 v6.4.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= diff --git a/integration_tests/create_postgres_access.lua b/integration_tests/create_postgres_access.lua index 15cb4119f..54b3667a8 100644 --- a/integration_tests/create_postgres_access.lua +++ b/integration_tests/create_postgres_access.lua @@ -17,7 +17,6 @@ Test.gql("Create personal postgres access without authorization", function(t) environmentName: "dev" teamSlug: "someteamname" accessLevel: READ - clientWireGuardPublicKey: "client-public-key" reason: "Testing personal database access" }) { name @@ -47,7 +46,6 @@ Test.gql("Create personal postgres access requires an audit reason", function(t) environmentName: "dev" teamSlug: "someteamname" accessLevel: READ - clientWireGuardPublicKey: "client-public-key" reason: "short" }) { name @@ -76,7 +74,6 @@ Test.gql("Create personal postgres access rejects an unknown instance", function environmentName: "dev" teamSlug: "someteamname" accessLevel: READ - clientWireGuardPublicKey: "client-public-key" reason: "Testing personal database access" }) { name @@ -89,7 +86,7 @@ Test.gql("Create personal postgres access rejects an unknown instance", function errors = { { extensions = { field = "postgresInstance" }, - message = Contains("Could not find postgres cluster"), + message = Contains("Could not find PostgresInstance"), path = { "createPostgresAccess" }, }, }, @@ -97,6 +94,21 @@ Test.gql("Create personal postgres access rejects an unknown instance", function } end) +Test.gql("Create personal postgres access rejects a logical Postgres without a physical instance", function(t) + t.addHeader("x-user-email", user:email()) + t.query [[ + mutation { createPostgresAccess(input: { + postgresInstance: "legacy-only", environmentName: "dev", + teamSlug: "someteamname", accessLevel: READ, + reason: "Testing missing physical database instance" + }) { name } } + ]] + t.check { + errors = { { extensions = { field = "postgresInstance" }, message = Contains("Could not find PostgresInstance"), path = { "createPostgresAccess" } } }, + data = Null, + } +end) + Test.gql("Create personal postgres access rejects an unavailable instance", function(t) t.addHeader("x-user-email", user:email()) t.query [[ @@ -106,7 +118,6 @@ Test.gql("Create personal postgres access rejects an unavailable instance", func environmentName: "dev" teamSlug: "someteamname" accessLevel: READ - clientWireGuardPublicKey: "client-public-key" reason: "Testing personal database access" }) { name @@ -136,9 +147,8 @@ Test.gql("Create personal postgres access", function(t) environmentName: "dev" teamSlug: "someteamname" accessLevel: READWRITE - clientWireGuardPublicKey: "client-public-key" reason: "Testing personal database access" - ttl: "2h" + ttl: "30m" }) { name expiresAt @@ -197,10 +207,29 @@ Test.gql("Personal postgres access is audited as a self-grant", function(t) } end) +Test.gql("Personal access targets a physical instance, even when its name differs from logical Postgres", function(t) + t.addHeader("x-user-email", user:email()) + t.query [[ + mutation { createPostgresAccess(input: { + postgresInstance: "foobar-recovered", environmentName: "dev", + teamSlug: "someteamname", accessLevel: READ, + reason: "Testing access to a recovered instance" + }) { name } } + ]] + t.check { data = { createPostgresAccess = { name = NotNull() } } } + + t.query [[ + query { postgresAccess(name: "recovered-access", teamSlug: "someteamname", environmentName: "dev") { + postgresInstance { name } + } } + ]] + t.check { data = { postgresAccess = { postgresInstance = { name = "foobar-recovered" } } } } +end) + Test.gql("PostgresAccess status is visible to authorized team members", function(t) t.addHeader("x-user-email", otherMemberUser:email()) for _, test in ipairs({ - { name = "ready-access", state = "READY", message = "Database role and tunnel are ready" }, + { name = "ready-access", state = "READY", message = "database role and relay mapping are ready" }, { name = "pending-access", state = "PENDING", message = Null }, { name = "failed-access", state = "FAILED", message = Contains("not supported") }, { name = "expired-access", state = "EXPIRED", message = "access has expired" }, @@ -245,10 +274,10 @@ Test.gql("PostgresAccess connection returns credentials only to its owner", func password caCertificate serverName - tunnel { - endpoint - gatewayPublicKey - } + username + relayEndpoint + relayAccess + relayToken } } ]] @@ -259,7 +288,10 @@ Test.gql("PostgresAccess connection returns credentials only to its owner", func password = "supersecret", caCertificate = "test-ca-certificate", serverName = "pg-foobar-rw.someteamname.svc.cluster.local", - tunnel = { endpoint = "1.2.3.4:12345", gatewayPublicKey = "gw-public-key" }, + username = "user-foobar-role", + relayEndpoint = Contains("https://relay.external.dev."), + relayAccess = "someteamname/ready-access", + relayToken = "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8", }, }, } @@ -276,12 +308,28 @@ Test.gql("PostgresAccess connection rejects a different team member", function(t } end) +Test.gql("PostgresAccess credentials cannot be read through generic Secret elevation", function(t) + t.addHeader("x-user-email", otherMemberUser:email()) + for _, name in ipairs({ "ready-access-relay-token", "ready-access-credentials" }) do + t.query(string.format([[ + mutation { viewSecretValues(input: { + name: "%s", team: "someteamname", environment: "dev", + reason: "Trying to read personal access credentials" + }) { values { name value } } } + ]], name)) + t.check { + errors = { { path = { "viewSecretValues" }, message = Contains("only available through postgresAccessConnection") } }, + data = Null, + } + end +end) + Test.gql("PostgresAccess connection rejects expired, unready, and missing-secret access", function(t) t.addHeader("x-user-email", user:email()) for _, test in ipairs({ { name = "expired-access", message = "has expired" }, { name = "pending-access", message = "is not ready" }, - { name = "missing-secret-access", message = "credentials" }, + { name = "missing-secret-access", message = "secrets for PostgresAccess is not available" }, }) do t.query(string.format( [[query { postgresAccessConnection(input: {name: "%s", teamSlug: "someteamname", environmentName: "dev"}) { password } }]], diff --git a/integration_tests/grant_postgres_access.lua b/integration_tests/grant_postgres_access.lua index adaf55453..eb7a7ee16 100644 --- a/integration_tests/grant_postgres_access.lua +++ b/integration_tests/grant_postgres_access.lua @@ -1,337 +1,8 @@ -local user = User.new("user", "user@usersen.com") -local nonMemberUser = User.new("nonmember", "other@user.com") - -local mainTeam = Team.new("someteamname", "purpose", "#slack_channel") -mainTeam:addMember(user) - -Helper.readK8sResources("k8s_resources/grant_zalando_postgres_access") - -Test.gql("Grant postgres access without authorization in non-existent team", function(t) - t.addHeader("x-user-email", user:email()) - t.query([[ - mutation GrantPostgresAccess { - grantPostgresAccess( - input: { - clusterName: "foobar" - environmentName: "dev" - teamSlug: "non-existing-team" - grantee: "some@email.com" - duration: "30m" - } - ) { - error - } - } - ]]) - - t.check({ - errors = { - { - locations = NotNull(), - message = Contains('you need the "postgres:access:grant" authorization.'), - path = { - "grantPostgresAccess", - }, - }, - }, - data = Null, - }) -end) - -Test.gql("Grant postgres access without authorization in existing team", function(t) - t.addHeader("x-user-email", nonMemberUser:email()) - t.query([[ - mutation GrantPostgresAccess { - grantPostgresAccess( - input: { - clusterName: "foobar" - environmentName: "dev" - teamSlug: "someteamname" - grantee: "some@email.com" - duration: "30m" - } - ) { - error - } - } - ]]) - - t.check({ - errors = { - { - locations = NotNull(), - message = Contains('you need the "postgres:access:grant" authorization.'), - path = { - "grantPostgresAccess", - }, - }, - }, - data = Null, - }) -end) - -Test.gql("Grant postgres access with invalid duration", function(t) - t.addHeader("x-user-email", user:email()) - t.query([[ - mutation GrantPostgresAccess { - grantPostgresAccess( - input: { - clusterName: "foobar" - environmentName: "dev" - teamSlug: "someteamname" - grantee: "some@email.com" - duration: "halfhour" - } - ) { - error - } - } - ]]) - - t.check({ - errors = { - { - extensions = { - field = "duration", - }, - message = Contains('invalid duration "halfhour"'), - path = { - "grantPostgresAccess", - }, - }, - }, - data = Null, - }) -end) - -Test.gql("Grant postgres access with out-of-bounds duration", function(t) - t.addHeader("x-user-email", user:email()) - t.query([[ - mutation GrantPostgresAccess { - grantPostgresAccess( - input: { - clusterName: "foobar" - environmentName: "dev" - teamSlug: "someteamname" - grantee: "some@email.com" - duration: "24h" - } - ) { - error - } - } - ]]) - - t.check({ - errors = { - { - extensions = { - field = "duration", - }, - message = Contains('Duration "24h" is out-of-bounds'), - path = { - "grantPostgresAccess", - }, - }, - }, - data = Null, - }) -end) - -Test.gql("Grant postgres access to non-existing cluster", function(t) - t.addHeader("x-user-email", user:email()) - t.query([[ - mutation GrantPostgresAccess { - grantPostgresAccess( - input: { - clusterName: "baz" - environmentName: "dev" - teamSlug: "someteamname" - grantee: "some@email.com" - duration: "4h" - } - ) { - error - } - } - ]]) - - t.check({ - errors = { - { - extensions = { - field = "clusterName", - }, - message = Contains("Could not find postgres cluster"), - path = { - "grantPostgresAccess", - }, - }, - }, - data = Null, - }) -end) - -Test.gql("Grant postgres access with authorization", function(t) - t.addHeader("x-user-email", user:email()) - t.query([[ - mutation GrantPostgresAccess { - grantPostgresAccess( - input: { - clusterName: "foobar" - environmentName: "dev" - teamSlug: "someteamname" - grantee: "some@email.com" - duration: "30m" - } - ) { - error - } - } - ]]) - - t.check({ - data = { - grantPostgresAccess = { - error = "", - }, - }, - }) -end) - -Test.k8s("Validate Role resource", function(t) - local resourceName = "pg-grant-93a898ea" - local pgNamespace = string.format("pg-%s", mainTeam:slug()) - - t.check("rbac.authorization.k8s.io/v1", "roles", "dev", pgNamespace, resourceName, { - apiVersion = "rbac.authorization.k8s.io/v1", - kind = "Role", - metadata = { - name = resourceName, - namespace = pgNamespace, - annotations = { - ["console.nais.io/last-modified-at"] = NotNull(), - ["console.nais.io/last-modified-by"] = user:email(), - }, - labels = { - ["app.kubernetes.io/managed-by"] = "console", - ["euthanaisa.nais.io/kill-after"] = NotNull(), - ["nais.io/managed-by"] = "console", - ["postgres.data.nais.io/name"] = "foobar", - }, - }, - rules = { - { - apiGroups = { - "", - }, - resourceNames = { - "foobar-0", - "foobar-1", - "foobar-2", - }, - resources = { - "pods", - }, - verbs = { - "get", - "list", - "watch", - }, - }, - { - apiGroups = { - "", - }, - resourceNames = { - "foobar-0", - "foobar-1", - "foobar-2", - }, - resources = { - "pods/portforward", - }, - verbs = { - "get", - "list", - "watch", - "create", - }, - }, - }, - }) -end) - -Test.k8s("Validate RoleBinding resource", function(t) - local resourceName = "pg-grant-93a898ea" - local pgNamespace = string.format("pg-%s", mainTeam:slug()) - - t.check("rbac.authorization.k8s.io/v1", "rolebindings", "dev", pgNamespace, resourceName, { - apiVersion = "rbac.authorization.k8s.io/v1", - kind = "RoleBinding", - metadata = { - name = resourceName, - namespace = pgNamespace, - annotations = { - ["console.nais.io/last-modified-at"] = NotNull(), - ["console.nais.io/last-modified-by"] = user:email(), - }, - labels = { - ["app.kubernetes.io/managed-by"] = "console", - ["euthanaisa.nais.io/kill-after"] = NotNull(), - ["nais.io/managed-by"] = "console", - ["postgres.data.nais.io/name"] = "foobar", - }, - }, - roleRef = { - apiGroup = "rbac.authorization.k8s.io", - kind = "Role", - name = resourceName, - }, - subjects = { - { - kind = "User", - name = "some@email.com", - }, - }, - }) -end) - -Test.gql("Check acitivity log entry", function(t) - t.addHeader("x-user-email", user:email()) - t.query([[ - { - team(slug:"someteamname") { - activityLog { - nodes { - message - ... on PostgresGrantAccessActivityLogEntry { - data { - grantee - until - } - } - } - } - } - } - ]]) - - t.check({ - data = { - team = { - activityLog = { - nodes = { - { - message = Contains("Granted access to some@email.com"), - data = { - grantee = "some@email.com", - ["until"] = NotNull(), - }, - }, - }, - }, - }, - }, - }) +-- Port-forward RBAC grants were removed with the legacy Postgres CRD. +Test.gql("Legacy Postgres grant mutation is no longer available", function(t) + t.query [[mutation { grantPostgresAccess(input: { + clusterName: "legacy", teamSlug: "someteamname", environmentName: "dev", + grantee: "someone@example.com", duration: "1h" + }) { error } }]] + t.check { errors = { { message = Contains("grantPostgresAccess") } }, data = Null } end) diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/cnpg_cluster_foobar-recovered.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/cnpg_cluster_foobar-recovered.yaml new file mode 100644 index 000000000..240b9a489 --- /dev/null +++ b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/cnpg_cluster_foobar-recovered.yaml @@ -0,0 +1,15 @@ +apiVersion: postgresql.cnpg.io/v1 +kind: Cluster +metadata: + name: pg-foobar-recovered + namespace: someteamname +spec: + certificates: + serverCASecret: pg-foobar-ca +status: + phase: Cluster in healthy state + conditions: + - type: Ready + status: "True" + reason: ClusterReady + lastTransitionTime: "2026-09-17T00:00:00Z" diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/cnpg_cluster_foobar.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/cnpg_cluster_foobar.yaml new file mode 100644 index 000000000..7b8a21ba8 --- /dev/null +++ b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/cnpg_cluster_foobar.yaml @@ -0,0 +1,15 @@ +apiVersion: postgresql.cnpg.io/v1 +kind: Cluster +metadata: + name: pg-foobar + namespace: someteamname +spec: + certificates: + serverCASecret: pg-foobar-ca +status: + phase: Cluster in healthy state + conditions: + - type: Ready + status: "True" + reason: ClusterReady + lastTransitionTime: "2026-09-17T00:00:00Z" diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_expired-access.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_expired-access.yaml index 0e3b15701..aab36f8c9 100644 --- a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_expired-access.yaml +++ b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_expired-access.yaml @@ -8,13 +8,7 @@ spec: username: user@usersen.com accessLevel: read expiresAt: "2000-01-01T00:00:00Z" - clientWireGuardPublicKey: client-public-key status: - credentialSecretName: expired-access-credentials - serverName: pg-foobar-rw.someteamname.svc.cluster.local conditions: - type: Ready status: "True" - tunnel: - endpoint: "1.2.3.4:12345" - gatewayPublicKey: gw-public-key diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_failed-access.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_failed-access.yaml index 144463575..1a13c599a 100644 --- a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_failed-access.yaml +++ b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_failed-access.yaml @@ -8,7 +8,6 @@ spec: username: user@usersen.com accessLevel: readwritecreate expiresAt: "2099-09-17T12:00:00Z" - clientWireGuardPublicKey: client-public-key status: conditions: - type: Ready diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_missing-secret-access.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_missing-secret-access.yaml index b8beb8444..91c78eebe 100644 --- a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_missing-secret-access.yaml +++ b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_missing-secret-access.yaml @@ -3,18 +3,16 @@ kind: PostgresAccess metadata: name: missing-secret-access namespace: someteamname + uid: 22222222-2222-4222-8222-222222222222 spec: postgresInstance: foobar username: user@usersen.com accessLevel: read expiresAt: "2099-09-17T12:00:00Z" - clientWireGuardPublicKey: client-public-key status: - credentialSecretName: missing-secret-access-credentials - serverName: pg-foobar-rw.someteamname.svc.cluster.local + databaseRole: user-foobar-role + relayAccess: missing-secret-access + tokenSecret: missing-secret-access-relay-token conditions: - type: Ready status: "True" - tunnel: - endpoint: "1.2.3.4:12345" - gatewayPublicKey: gw-public-key diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_pending-access.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_pending-access.yaml index 67410521c..85448e023 100644 --- a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_pending-access.yaml +++ b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_pending-access.yaml @@ -8,13 +8,7 @@ spec: username: user@usersen.com accessLevel: read expiresAt: "2099-09-17T12:00:00Z" - clientWireGuardPublicKey: client-public-key status: - credentialSecretName: pending-access-credentials - serverName: pg-foobar-rw.someteamname.svc.cluster.local conditions: - type: Ready status: "False" - tunnel: - endpoint: "1.2.3.4:12345" - gatewayPublicKey: gw-public-key diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_ready.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_ready.yaml index 0a611ad72..e6d9f6cf6 100644 --- a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_ready.yaml +++ b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_ready.yaml @@ -3,21 +3,18 @@ kind: PostgresAccess metadata: name: ready-access namespace: someteamname + uid: 11111111-1111-4111-8111-111111111111 spec: postgresInstance: foobar username: user@usersen.com accessLevel: readwrite expiresAt: "2099-09-17T12:00:00Z" - clientWireGuardPublicKey: client-public-key status: - credentialSecretName: ready-access-credentials - serverName: pg-foobar-rw.someteamname.svc.cluster.local + databaseRole: user-foobar-role + relayAccess: ready-access + tokenSecret: ready-access-relay-token conditions: - type: Ready status: "True" reason: Ready - message: "Database role and tunnel are ready" - tunnel: - name: ready-access - endpoint: "1.2.3.4:12345" - gatewayPublicKey: "gw-public-key" + message: "database role and relay mapping are ready" diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_recovered-access.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_recovered-access.yaml new file mode 100644 index 000000000..2abfe46e9 --- /dev/null +++ b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_recovered-access.yaml @@ -0,0 +1,14 @@ +apiVersion: nais.io/v1 +kind: PostgresAccess +metadata: + name: recovered-access + namespace: someteamname +spec: + postgresInstance: foobar-recovered + username: user@usersen.com + accessLevel: read + expiresAt: "2099-09-17T12:00:00Z" +status: + conditions: + - type: Ready + status: "False" diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_foobar.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_foobar.yaml index 6796d66e0..086fe4610 100644 --- a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_foobar.yaml +++ b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_foobar.yaml @@ -1,15 +1,10 @@ --- -apiVersion: data.nais.io/v1 +apiVersion: nais.io/v1 kind: Postgres metadata: name: foobar namespace: someteamname spec: - cluster: - majorVersion: "17" - resources: - cpu: 100m - diskSize: 2Gi - memory: 2G - database: - collation: nb_NO + majorVersion: "17" +status: + activeInstance: foobar diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_instance_foobar.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_instance_foobar.yaml new file mode 100644 index 000000000..88ea525d5 --- /dev/null +++ b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_instance_foobar.yaml @@ -0,0 +1,15 @@ +apiVersion: nais.io/v1 +kind: PostgresInstance +metadata: + name: foobar + namespace: someteamname +spec: + postgres: foobar +status: + reconcilePhase: Completed + conditions: + - type: cluster.postgresql.cnpg.io/ObservedState + status: "True" + reason: Reconciled + message: "Cluster is in phase: Cluster in healthy state" + lastTransitionTime: "2026-09-17T00:00:00Z" diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_instance_progressing.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_instance_progressing.yaml new file mode 100644 index 000000000..988638ad5 --- /dev/null +++ b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_instance_progressing.yaml @@ -0,0 +1,15 @@ +apiVersion: nais.io/v1 +kind: PostgresInstance +metadata: + name: progressing + namespace: someteamname +spec: + postgres: progressing +status: + reconcilePhase: Preparing + conditions: + - type: cluster.postgresql.cnpg.io/ObservedState + status: "False" + reason: Reconciling + message: "Cluster is in phase: " + lastTransitionTime: "2026-09-17T00:00:00Z" diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_instance_recovered.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_instance_recovered.yaml new file mode 100644 index 000000000..f24d799ac --- /dev/null +++ b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_instance_recovered.yaml @@ -0,0 +1,15 @@ +apiVersion: nais.io/v1 +kind: PostgresInstance +metadata: + name: foobar-recovered + namespace: someteamname +spec: + postgres: foobar +status: + reconcilePhase: Completed + conditions: + - type: cluster.postgresql.cnpg.io/ObservedState + status: "True" + reason: Reconciled + message: "Cluster is in phase: Cluster in healthy state" + lastTransitionTime: "2026-09-17T00:00:00Z" diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_legacy-only.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_legacy-only.yaml new file mode 100644 index 000000000..9f78de4bf --- /dev/null +++ b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_legacy-only.yaml @@ -0,0 +1,8 @@ +--- +apiVersion: nais.io/v1 +kind: Postgres +metadata: + name: legacy-only + namespace: someteamname +spec: + majorVersion: "17" diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_progressing.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_progressing.yaml index 8a926e827..b274f7d3b 100644 --- a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_progressing.yaml +++ b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_progressing.yaml @@ -1,22 +1,10 @@ --- -apiVersion: data.nais.io/v1 +apiVersion: nais.io/v1 kind: Postgres metadata: name: progressing namespace: someteamname spec: - cluster: - majorVersion: "17" - resources: - cpu: 100m - diskSize: 2Gi - memory: 2G - database: - collation: nb_NO + majorVersion: "17" status: - conditions: - - type: Progressing - status: "True" - reason: Reconciling - message: Creating Postgres cluster - lastTransitionTime: "2026-09-17T00:00:00Z" + activeInstance: progressing diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/relay_access_missing_secret.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/relay_access_missing_secret.yaml new file mode 100644 index 000000000..012d84507 --- /dev/null +++ b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/relay_access_missing_secret.yaml @@ -0,0 +1,17 @@ +apiVersion: nais.io/v1alpha1 +kind: RelayAccess +metadata: + name: missing-secret-access + namespace: someteamname + ownerReferences: + - apiVersion: nais.io/v1 + kind: PostgresAccess + name: missing-secret-access + uid: 22222222-2222-4222-8222-222222222222 + controller: true +spec: + target: + serviceName: pg-foobar-rw + port: 5432 + expiresAt: "2099-09-17T12:00:00Z" + tokenSHA256: 630dcd2966c4336691125448bbb25b4ff412a49c732db2c8abc1b8581bd710dd diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/relay_access_ready.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/relay_access_ready.yaml new file mode 100644 index 000000000..c95c5fdd9 --- /dev/null +++ b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/relay_access_ready.yaml @@ -0,0 +1,17 @@ +apiVersion: nais.io/v1alpha1 +kind: RelayAccess +metadata: + name: ready-access + namespace: someteamname + ownerReferences: + - apiVersion: nais.io/v1 + kind: PostgresAccess + name: ready-access + uid: 11111111-1111-4111-8111-111111111111 + controller: true +spec: + target: + serviceName: pg-foobar-rw + port: 5432 + expiresAt: "2099-09-17T12:00:00Z" + tokenSHA256: 630dcd2966c4336691125448bbb25b4ff412a49c732db2c8abc1b8581bd710dd diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/secret_pg_foobar_ca.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/secret_pg_foobar_ca.yaml new file mode 100644 index 000000000..6c7b171d1 --- /dev/null +++ b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/secret_pg_foobar_ca.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: Secret +metadata: + name: pg-foobar-ca + namespace: someteamname +type: Opaque +data: + ca.crt: dGVzdC1jYS1jZXJ0aWZpY2F0ZQ== diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/secret_ready_access_credentials.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/secret_ready_access_credentials.yaml index 4a845780e..34631543a 100644 --- a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/secret_ready_access_credentials.yaml +++ b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/secret_ready_access_credentials.yaml @@ -3,8 +3,13 @@ kind: Secret metadata: name: ready-access-credentials namespace: someteamname + ownerReferences: + - apiVersion: nais.io/v1 + kind: PostgresAccess + name: ready-access + uid: 11111111-1111-4111-8111-111111111111 + controller: true type: kubernetes.io/basic-auth data: - username: YXBwLWZvb2Jhci1hYmMxMjM= + username: dXNlci1mb29iYXItcm9sZQ== password: c3VwZXJzZWNyZXQ= - ca.crt: dGVzdC1jYS1jZXJ0aWZpY2F0ZQ== diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/secret_ready_access_relay_token.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/secret_ready_access_relay_token.yaml new file mode 100644 index 000000000..0d8d2d958 --- /dev/null +++ b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/secret_ready_access_relay_token.yaml @@ -0,0 +1,14 @@ +apiVersion: v1 +kind: Secret +metadata: + name: ready-access-relay-token + namespace: someteamname + ownerReferences: + - apiVersion: nais.io/v1 + kind: PostgresAccess + name: ready-access + uid: 11111111-1111-4111-8111-111111111111 + controller: true +type: Opaque +data: + token: QUFFQ0F3UUZCZ2NJQ1FvTERBME9EeEFSRWhNVUZSWVhHQmthR3h3ZEhoOA== diff --git a/integration_tests/k8s_resources/grant_zalando_postgres_access/dev/someteamname/postgres_foobar.yaml b/integration_tests/k8s_resources/grant_zalando_postgres_access/dev/someteamname/postgres_foobar.yaml deleted file mode 100644 index 6796d66e0..000000000 --- a/integration_tests/k8s_resources/grant_zalando_postgres_access/dev/someteamname/postgres_foobar.yaml +++ /dev/null @@ -1,15 +0,0 @@ ---- -apiVersion: data.nais.io/v1 -kind: Postgres -metadata: - name: foobar - namespace: someteamname -spec: - cluster: - majorVersion: "17" - resources: - cpu: 100m - diskSize: 2Gi - memory: 2G - database: - collation: nb_NO diff --git a/integration_tests/k8s_resources/label_selectors/dev/labelteam/postgres.yaml b/integration_tests/k8s_resources/label_selectors/dev/labelteam/postgres.yaml index 7b92807cd..d79b3f7a8 100644 --- a/integration_tests/k8s_resources/label_selectors/dev/labelteam/postgres.yaml +++ b/integration_tests/k8s_resources/label_selectors/dev/labelteam/postgres.yaml @@ -1,6 +1,16 @@ --- -apiVersion: data.nais.io/v1 +apiVersion: nais.io/v1 kind: Postgres +metadata: + name: postgres-one + namespace: labelteam +spec: + majorVersion: "17" +status: + activeInstance: postgres-one +--- +apiVersion: nais.io/v1 +kind: PostgresInstance metadata: name: postgres-one namespace: labelteam @@ -8,45 +18,68 @@ metadata: tag: target priority: high spec: - cluster: - majorVersion: "17" - resources: - cpu: 100m - diskSize: 2Gi - memory: 2G - database: - collation: nb_NO + postgres: postgres-one +status: + reconcilePhase: Completed + conditions: + - type: cluster.postgresql.cnpg.io/ObservedState + status: "True" + reason: Reconciled + message: "Cluster is in phase: Cluster in healthy state" + lastTransitionTime: "2026-09-17T00:00:00Z" --- -apiVersion: data.nais.io/v1 +apiVersion: nais.io/v1 kind: Postgres +metadata: + name: postgres-two + namespace: labelteam +spec: + majorVersion: "17" +status: + activeInstance: postgres-two +--- +apiVersion: nais.io/v1 +kind: PostgresInstance metadata: name: postgres-two namespace: labelteam labels: tag: target spec: - cluster: - majorVersion: "17" - resources: - cpu: 100m - diskSize: 2Gi - memory: 2G - database: - collation: nb_NO + postgres: postgres-two +status: + reconcilePhase: Completed + conditions: + - type: cluster.postgresql.cnpg.io/ObservedState + status: "True" + reason: Reconciled + message: "Cluster is in phase: Cluster in healthy state" + lastTransitionTime: "2026-09-17T00:00:00Z" --- -apiVersion: data.nais.io/v1 +apiVersion: nais.io/v1 kind: Postgres +metadata: + name: postgres-three + namespace: labelteam +spec: + majorVersion: "17" +status: + activeInstance: postgres-three +--- +apiVersion: nais.io/v1 +kind: PostgresInstance metadata: name: postgres-three namespace: labelteam labels: tag: other spec: - cluster: - majorVersion: "17" - resources: - cpu: 100m - diskSize: 2Gi - memory: 2G - database: - collation: nb_NO + postgres: postgres-three +status: + reconcilePhase: Completed + conditions: + - type: cluster.postgresql.cnpg.io/ObservedState + status: "True" + reason: Reconciled + message: "Cluster is in phase: Cluster in healthy state" + lastTransitionTime: "2026-09-17T00:00:00Z" diff --git a/integration_tests/k8s_resources/postgres_audit_log/dev-gcp/audit-postgres-team/postgres_with_audit.yaml b/integration_tests/k8s_resources/postgres_audit_log/dev-gcp/audit-postgres-team/postgres_with_audit.yaml index bdfbcd8f2..9b5eb3747 100644 --- a/integration_tests/k8s_resources/postgres_audit_log/dev-gcp/audit-postgres-team/postgres_with_audit.yaml +++ b/integration_tests/k8s_resources/postgres_audit_log/dev-gcp/audit-postgres-team/postgres_with_audit.yaml @@ -1,17 +1,26 @@ --- -apiVersion: data.nais.io/v1 +apiVersion: nais.io/v1 kind: Postgres metadata: name: audit-enabled namespace: audit-postgres-team spec: - cluster: - majorVersion: "16" - resources: - cpu: 100m - diskSize: 5Gi - memory: 2G - audit: - enabled: true - database: - collation: en_US + majorVersion: "16" +status: + activeInstance: audit-enabled +--- +apiVersion: nais.io/v1 +kind: PostgresInstance +metadata: + name: audit-enabled + namespace: audit-postgres-team +spec: + postgres: audit-enabled +status: + reconcilePhase: Completed + conditions: + - type: cluster.postgresql.cnpg.io/ObservedState + status: "True" + reason: Reconciled + message: "Cluster is in phase: Cluster in healthy state" + lastTransitionTime: "2026-09-17T00:00:00Z" diff --git a/integration_tests/k8s_resources/postgres_delete/dev/pg-delete-team/postgres.yaml b/integration_tests/k8s_resources/postgres_delete/dev/pg-delete-team/postgres.yaml new file mode 100644 index 000000000..2f42bcc21 --- /dev/null +++ b/integration_tests/k8s_resources/postgres_delete/dev/pg-delete-team/postgres.yaml @@ -0,0 +1,25 @@ +apiVersion: nais.io/v1 +kind: Postgres +metadata: + name: orders + namespace: pg-delete-team +spec: + majorVersion: "17" +status: + activeInstance: orders-new +--- +apiVersion: nais.io/v1 +kind: PostgresInstance +metadata: + name: orders-new + namespace: pg-delete-team +spec: + postgres: orders +--- +apiVersion: nais.io/v1 +kind: PostgresInstance +metadata: + name: orders-old + namespace: pg-delete-team +spec: + postgres: orders diff --git a/integration_tests/k8s_resources/postgres_instances/dev/someteamname/applications.yaml b/integration_tests/k8s_resources/postgres_instances/dev/someteamname/applications.yaml index 5a57282e5..304150ad5 100644 --- a/integration_tests/k8s_resources/postgres_instances/dev/someteamname/applications.yaml +++ b/integration_tests/k8s_resources/postgres_instances/dev/someteamname/applications.yaml @@ -6,8 +6,9 @@ metadata: namespace: someteamname spec: image: ghcr.io/nais/testapp:latest - postgres: - clusterName: foobar + uses: + postgres: + - name: foobar --- apiVersion: nais.io/v1alpha1 kind: Application @@ -16,8 +17,9 @@ metadata: namespace: someteamname spec: image: ghcr.io/nais/testapp:latest - postgres: - clusterName: foobar + uses: + postgres: + - name: foobar --- apiVersion: nais.io/v1 kind: Naisjob @@ -27,8 +29,9 @@ metadata: spec: image: ghcr.io/nais/testapp:latest schedule: "0 0 * * *" - postgres: - clusterName: foobar + uses: + postgres: + - name: foobar --- apiVersion: nais.io/v1alpha1 kind: Application diff --git a/integration_tests/k8s_resources/postgres_instances/dev/someteamname/postgres_another_db.yaml b/integration_tests/k8s_resources/postgres_instances/dev/someteamname/postgres_another_db.yaml index 3c35bfab3..0886470fb 100644 --- a/integration_tests/k8s_resources/postgres_instances/dev/someteamname/postgres_another_db.yaml +++ b/integration_tests/k8s_resources/postgres_instances/dev/someteamname/postgres_another_db.yaml @@ -1,15 +1,26 @@ --- -apiVersion: data.nais.io/v1 +apiVersion: nais.io/v1 kind: Postgres metadata: name: another-db namespace: someteamname spec: - cluster: - majorVersion: "16" - resources: - cpu: 200m - diskSize: 10Gi - memory: 4G - database: - collation: en_US + majorVersion: "16" +status: + activeInstance: another-db +--- +apiVersion: nais.io/v1 +kind: PostgresInstance +metadata: + name: another-db + namespace: someteamname +spec: + postgres: another-db +status: + reconcilePhase: Completed + conditions: + - type: cluster.postgresql.cnpg.io/ObservedState + status: "True" + reason: Reconciled + message: "Cluster is in phase: Cluster in healthy state" + lastTransitionTime: "2026-09-17T00:00:00Z" diff --git a/integration_tests/k8s_resources/postgres_instances/dev/someteamname/postgres_foobar.yaml b/integration_tests/k8s_resources/postgres_instances/dev/someteamname/postgres_foobar.yaml index 6796d66e0..38b534fae 100644 --- a/integration_tests/k8s_resources/postgres_instances/dev/someteamname/postgres_foobar.yaml +++ b/integration_tests/k8s_resources/postgres_instances/dev/someteamname/postgres_foobar.yaml @@ -1,15 +1,30 @@ --- -apiVersion: data.nais.io/v1 +apiVersion: nais.io/v1 kind: Postgres metadata: name: foobar namespace: someteamname spec: - cluster: - majorVersion: "17" - resources: - cpu: 100m - diskSize: 2Gi - memory: 2G - database: - collation: nb_NO + majorVersion: "17" + resources: + cpu: 100m + memory: 2Gi + diskSize: 2Gi +status: + activeInstance: foobar +--- +apiVersion: nais.io/v1 +kind: PostgresInstance +metadata: + name: foobar + namespace: someteamname +spec: + postgres: foobar +status: + reconcilePhase: Completed + conditions: + - type: cluster.postgresql.cnpg.io/ObservedState + status: "True" + reason: Reconciled + message: "Cluster is in phase: Cluster in healthy state" + lastTransitionTime: "2026-09-17T00:00:00Z" diff --git a/integration_tests/k8s_resources/postgres_instances/dev/someteamname/postgres_with_audit.yaml b/integration_tests/k8s_resources/postgres_instances/dev/someteamname/postgres_with_audit.yaml index 6123e143d..f926335ea 100644 --- a/integration_tests/k8s_resources/postgres_instances/dev/someteamname/postgres_with_audit.yaml +++ b/integration_tests/k8s_resources/postgres_instances/dev/someteamname/postgres_with_audit.yaml @@ -1,17 +1,26 @@ --- -apiVersion: data.nais.io/v1 +apiVersion: nais.io/v1 kind: Postgres metadata: name: with-audit namespace: someteamname spec: - cluster: - majorVersion: "16" - resources: - cpu: 100m - diskSize: 5Gi - memory: 2G - audit: - enabled: true - database: - collation: en_US + majorVersion: "16" +status: + activeInstance: with-audit +--- +apiVersion: nais.io/v1 +kind: PostgresInstance +metadata: + name: with-audit + namespace: someteamname +spec: + postgres: with-audit +status: + reconcilePhase: Completed + conditions: + - type: cluster.postgresql.cnpg.io/ObservedState + status: "True" + reason: Reconciled + message: "Cluster is in phase: Cluster in healthy state" + lastTransitionTime: "2026-09-17T00:00:00Z" diff --git a/integration_tests/k8s_resources/postgres_instances/dev/someteamname/postgres_without_audit.yaml b/integration_tests/k8s_resources/postgres_instances/dev/someteamname/postgres_without_audit.yaml index cdb00f766..0be70c9d0 100644 --- a/integration_tests/k8s_resources/postgres_instances/dev/someteamname/postgres_without_audit.yaml +++ b/integration_tests/k8s_resources/postgres_instances/dev/someteamname/postgres_without_audit.yaml @@ -1,17 +1,26 @@ --- -apiVersion: data.nais.io/v1 +apiVersion: nais.io/v1 kind: Postgres metadata: name: without-audit namespace: someteamname spec: - cluster: - majorVersion: "15" - resources: - cpu: 100m - diskSize: 3Gi - memory: 1G - audit: - enabled: false - database: - collation: en_US + majorVersion: "15" +status: + activeInstance: without-audit +--- +apiVersion: nais.io/v1 +kind: PostgresInstance +metadata: + name: without-audit + namespace: someteamname +spec: + postgres: without-audit +status: + reconcilePhase: Completed + conditions: + - type: cluster.postgresql.cnpg.io/ObservedState + status: "True" + reason: Reconciled + message: "Cluster is in phase: Cluster in healthy state" + lastTransitionTime: "2026-09-17T00:00:00Z" diff --git a/integration_tests/k8s_resources/postgres_workloads/dev/postgres-workload-team/resources.yaml b/integration_tests/k8s_resources/postgres_workloads/dev/postgres-workload-team/resources.yaml new file mode 100644 index 000000000..e17382fde --- /dev/null +++ b/integration_tests/k8s_resources/postgres_workloads/dev/postgres-workload-team/resources.yaml @@ -0,0 +1,62 @@ +apiVersion: nais.io/v1 +kind: Postgres +metadata: + name: orders + namespace: postgres-workload-team +spec: + majorVersion: "17" +status: + activeInstance: orders-green +--- +apiVersion: nais.io/v1 +kind: Postgres +metadata: + name: reports + namespace: postgres-workload-team +spec: + majorVersion: "17" +status: + activeInstance: reports-recovered +--- +apiVersion: nais.io/v1 +kind: PostgresInstance +metadata: + name: orders-green + namespace: postgres-workload-team +spec: + postgres: orders +--- +apiVersion: nais.io/v1 +kind: PostgresInstance +metadata: + name: reports-recovered + namespace: postgres-workload-team +spec: + postgres: reports +--- +apiVersion: nais.io/v1alpha1 +kind: Application +metadata: + name: consumer + namespace: postgres-workload-team +spec: + image: ghcr.io/nais/testapp:latest + uses: + postgres: + - name: orders + - name: reports + envPrefix: REPORTS_ +--- +apiVersion: nais.io/v1 +kind: Naisjob +metadata: + name: scheduled-reader + namespace: postgres-workload-team +spec: + image: ghcr.io/nais/testapp:latest + schedule: "0 0 * * *" + uses: + postgres: + - name: orders + - name: reports + envPrefix: REPORTS_ diff --git a/integration_tests/postgres_audit_log.lua b/integration_tests/postgres_audit_log.lua index 5266e2cfe..a59785d13 100644 --- a/integration_tests/postgres_audit_log.lua +++ b/integration_tests/postgres_audit_log.lua @@ -1,74 +1,16 @@ +-- The old per-instance audit flag and Cloud SQL Logs URL are not part of +-- nais.io/v1 PostgresInstance. Verify logical configuration instead. Helper.readK8sResources("k8s_resources/postgres_audit_log") - local user = User.new("authenticated", "postgres-audit-user@example.com", "postgres-audit-user-id") -local team = Team.new("audit-postgres-team", "Testing Postgres audit logging", "#audit-postgres") +local team = Team.new("audit-postgres-team", "Testing logical Postgres", "#audit-postgres") team:addMember(user) -team:setEnvironmentGCPProjectID("dev-gcp", "nais-audit-project") - -Test.gql("Postgres instance with audit logging enabled has audit URL", function(t) - t.addHeader("x-user-email", user:email()) - - t.query [[ - query { - team(slug: "audit-postgres-team") { - environment(name: "dev-gcp") { - postgresInstance(name: "audit-enabled") { - name - audit { - enabled - url - } - } - } - } - } - ]] - t.check { - data = { - team = { - environment = { - postgresInstance = { - name = "audit-enabled", - audit = { - enabled = true, - url = Contains("console.cloud.google.com/logs"), - }, - }, - }, - }, - }, - } -end) - -Test.gql("Postgres audit URL contains expected components", function(t) +Test.gql("Logical Postgres settings are not fabricated on physical instances", function(t) t.addHeader("x-user-email", user:email()) - - t.query [[ - query { - team(slug: "audit-postgres-team") { - environment(name: "dev-gcp") { - postgresInstance(name: "audit-enabled") { - audit { - url - } - } - } - } - } - ]] - - t.check { - data = { - team = { - environment = { - postgresInstance = { - audit = { - url = Contains("nais-audit-project%3Aaudit-enabled"), - }, - }, - }, - }, - }, - } + t.query [[{ team(slug:"audit-postgres-team") { environment(name:"dev-gcp") { + postgresInstance(name:"audit-enabled") { name state postgres { name majorVersion } } + } } }]] + t.check { data = { team = { environment = { postgresInstance = { + name = "audit-enabled", state = "AVAILABLE", postgres = { name = "audit-enabled", majorVersion = "17" }, + } } } } } end) diff --git a/integration_tests/postgres_delete.lua b/integration_tests/postgres_delete.lua new file mode 100644 index 000000000..190b79bcc --- /dev/null +++ b/integration_tests/postgres_delete.lua @@ -0,0 +1,20 @@ +local user = User.new("postgres-delete-user", "postgres-delete-user@usersen.com") +local team = Team.new("pg-delete-team", "Testing PostgresInstance deletion", "#postgres-delete") +team:addMember(user) +Helper.readK8sResources("k8s_resources/postgres_delete") + +Test.gql("Active PostgresInstance cannot be marked for deletion", function(t) + t.addHeader("x-user-email", user:email()) + t.query [[mutation { deletePostgres(input: { + name: "orders-new", environmentName: "dev", teamSlug: "pg-delete-team" + }) { postgresDeleted } }]] + t.check { errors = { { path = { "deletePostgres" }, message = Contains("is active and cannot be deleted") } }, data = Null } +end) + +Test.gql("Inactive PostgresInstance can be deleted", function(t) + t.addHeader("x-user-email", user:email()) + t.query [[mutation { deletePostgres(input: { + name: "orders-old", environmentName: "dev", teamSlug: "pg-delete-team" + }) { postgresDeleted } }]] + t.check { data = { deletePostgres = { postgresDeleted = true } } } +end) diff --git a/integration_tests/postgres_instances.lua b/integration_tests/postgres_instances.lua index 122e58c54..0de06fcb4 100644 --- a/integration_tests/postgres_instances.lua +++ b/integration_tests/postgres_instances.lua @@ -1,640 +1,63 @@ local user = User.new("user", "user@usersen.com") -local nonMemberUser = User.new("nonmember", "other@user.com") - -local mainTeam = Team.new("someteamname", "purpose", "#slack_channel") -mainTeam:addMember(user) - +local nonMember = User.new("nonmember", "not@usersen.com") +local team = Team.new("someteamname", "purpose", "#slack_channel") +team:addMember(user) Helper.readK8sResources("k8s_resources/postgres_instances") -Test.gql("List postgres instances for team", function(t) - t.addHeader("x-user-email", user:email()) - - t.query [[ - { - team(slug: "someteamname") { - postgresInstances(orderBy: {field: NAME, direction: ASC}) { - nodes { - name - majorVersion - resources { - cpu - memory - diskSize - } - audit { - enabled - } - } - } - } - } - ]] - - t.check { - data = { - team = { - postgresInstances = { - nodes = { - { - name = "another-db", - majorVersion = "16", - resources = { - cpu = "200m", - memory = "4G", - diskSize = "10Gi", - }, - audit = { - enabled = false, - }, - }, - { - name = "foobar", - majorVersion = "17", - resources = { - cpu = "100m", - memory = "2G", - diskSize = "2Gi", - }, - audit = { - enabled = false, - }, - }, - { - name = "with-audit", - majorVersion = "16", - resources = { - cpu = "100m", - memory = "2G", - diskSize = "5Gi", - }, - audit = { - enabled = true, - }, - }, - { - name = "without-audit", - majorVersion = "15", - resources = { - cpu = "100m", - memory = "1G", - diskSize = "3Gi", - }, - audit = { - enabled = false, - }, - }, - }, - }, - }, - }, - } -end) - -Test.gql("Get specific postgres instance from team environment", function(t) - t.addHeader("x-user-email", user:email()) - - t.query [[ - { - team(slug: "someteamname") { - environment(name: "dev") { - postgresInstance(name: "foobar") { - name - majorVersion - teamEnvironment { - name - } - } - } - } - } - ]] - - t.check { - data = { - team = { - environment = { - postgresInstance = { - name = "foobar", - majorVersion = "17", - teamEnvironment = { - name = "dev", - }, - }, - }, - }, - }, - } -end) - -Test.gql("List postgres instances with ordering by name", function(t) - t.addHeader("x-user-email", user:email()) - - t.query [[ - { - team(slug: "someteamname") { - postgresInstances(orderBy: {field: NAME, direction: ASC}) { - nodes { - name - } - } - } - } - ]] - - t.check { - data = { - team = { - postgresInstances = { - nodes = { - { - name = "another-db", - }, - { - name = "foobar", - }, - { - name = "with-audit", - }, - { - name = "without-audit", - }, - }, - }, - }, - }, - } -end) - -Test.gql("List postgres instances with ordering by environment", function(t) - t.addHeader("x-user-email", user:email()) - - t.query [[ - { - team(slug: "someteamname") { - postgresInstances(orderBy: {field: ENVIRONMENT, direction: DESC}, first: 10) { - nodes { - name - teamEnvironment { - name - } - } - } - } - } - ]] - - t.check { - data = { - team = { - postgresInstances = { - nodes = { - { - name = "another-db", - teamEnvironment = { - name = "dev", - }, - }, - { - name = "foobar", - teamEnvironment = { - name = "dev", - }, - }, - { - name = "with-audit", - teamEnvironment = { - name = "dev", - }, - }, - { - name = "without-audit", - teamEnvironment = { - name = "dev", - }, - }, - }, - }, - }, - }, - } -end) - -Test.gql("Get postgres instance from application", function(t) - t.addHeader("x-user-email", user:email()) - - t.query [[ - { - team(slug: "someteamname") { - environment(name: "dev") { - application(name: "app-with-postgres") { - name - postgresInstances { - nodes { - name - majorVersion - } - } - } - } - } - } - ]] - - t.check { - data = { - team = { - environment = { - application = { - name = "app-with-postgres", - postgresInstances = { - nodes = { - { - name = "foobar", - majorVersion = "17", - }, - }, - }, - }, - }, - }, - }, - } -end) - -Test.gql("Get workloads referencing postgres instance", function(t) - t.addHeader("x-user-email", user:email()) - - t.query [[ - { - team(slug: "someteamname") { - environment(name: "dev") { - postgresInstance(name: "foobar") { - name - workloads { - nodes { - __typename - name - } - } - } - } - } - } - ]] - - t.check { - data = { - team = { - environment = { - postgresInstance = { - name = "foobar", - workloads = { - nodes = { - { - __typename = "Application", - name = "app-with-postgres", - }, - { - __typename = "Application", - name = "app-with-postgres-2", - }, - { - __typename = "Job", - name = "job-with-postgres", - }, - }, - }, - }, - }, - }, - }, - } -end) - -Test.gql("Get empty postgres instances from application without postgres", function(t) - t.addHeader("x-user-email", user:email()) - - t.query [[ - { - team(slug: "someteamname") { - environment(name: "dev") { - application(name: "app-without-postgres") { - name - postgresInstances { - nodes { - name - } - } - } - } - } - } - ]] - - t.check { - data = { - team = { - environment = { - application = { - name = "app-without-postgres", - postgresInstances = { - nodes = {}, - }, - }, - }, - }, - }, - } -end) - -Test.gql("Access postgres instance fields", function(t) - t.addHeader("x-user-email", user:email()) - - t.query [[ - { - team(slug: "someteamname") { - postgresInstances(first: 1) { - nodes { - id - name - majorVersion - team { - slug - } - teamEnvironment { - name - } - resources { - cpu - memory - diskSize - } - } - } - } - } - ]] - - t.check { - data = { - team = { - postgresInstances = { - nodes = { - { - id = NotNull(), - name = NotNull(), - majorVersion = NotNull(), - team = { - slug = "someteamname", - }, - teamEnvironment = { - name = NotNull(), - }, - resources = { - cpu = NotNull(), - memory = NotNull(), - diskSize = NotNull(), - }, - }, - }, - }, - }, - }, - } -end) - -Test.gql("Postgres instance with audit logging enabled", function(t) - t.addHeader("x-user-email", user:email()) - - t.query [[ - { - team(slug: "someteamname") { - environment(name: "dev") { - postgresInstance(name: "with-audit") { - name - audit { - enabled - url - } - } - } - } - } - ]] - - t.check { - data = { - team = { - environment = { - postgresInstance = { - name = "with-audit", - audit = { - enabled = true, - url = Null, - }, - }, - }, - }, - }, - } -end) - -Test.gql("Postgres instance without audit logging", function(t) - t.addHeader("x-user-email", user:email()) - - t.query [[ - { - team(slug: "someteamname") { - environment(name: "dev") { - postgresInstance(name: "foobar") { - name - audit { - enabled - url - } - } - } - } - } - ]] - - t.check { - data = { - team = { - environment = { - postgresInstance = { - name = "foobar", - audit = { - enabled = false, - url = Null, - }, - }, - }, - }, - }, - } -end) - -Test.gql("Postgres instance with explicit audit disabled", function(t) - t.addHeader("x-user-email", user:email()) - - t.query [[ - { - team(slug: "someteamname") { - environment(name: "dev") { - postgresInstance(name: "without-audit") { - name - audit { - enabled - url - } - } - } - } - } - ]] - - t.check { - data = { - team = { - environment = { - postgresInstance = { - name = "without-audit", - audit = { - enabled = false, - url = Null, - }, - }, - }, - }, - }, - } -end) - -Test.gql("Delete Postgres in non-existing team", function(t) - t.addHeader("x-user-email", user:email()) - t.query [[ - mutation DeletePostgres { - deletePostgres( - input: { - name: "foobar" - environmentName: "dev" - teamSlug: "devteam" - } - ) { - postgresDeleted - } - } - ]] - - t.check { - errors = { - { - locations = NotNull(), - message = Contains("you need the \"postgres:delete\" authorization."), - path = { - "deletePostgres", - }, - }, - }, - data = Null, - } -end) - -Test.gql("Delete Postgres as non-team-member", function(t) - t.addHeader("x-user-email", nonMemberUser:email()) - t.query [[ - mutation DeletePostgres { - deletePostgres( - input: { - name: "foobar" - environmentName: "dev" - teamSlug: "someteamname" - } - ) { - postgresDeleted - } - } - ]] - - t.check { - errors = { - { - locations = NotNull(), - message = Contains("You are authenticated"), - path = { - "deletePostgres", - }, - }, - }, - data = Null, - } -end) - -Test.gql("Delete Postgres as team-member", function(t) - t.addHeader("x-user-email", user:email()) - t.query [[ - mutation DeletePostgres { - deletePostgres( - input: { - name: "foobar" - environmentName: "dev" - teamSlug: "someteamname" - } - ) { - postgresDeleted - } - } - ]] - - t.check { - data = { - deletePostgres = { - postgresDeleted = true, - }, - }, - } -end) - -Test.gql("Verify activity log for postgres delete", function(t) - t.addHeader("x-user-email", user:email()) - t.query(string.format([[ - { - team(slug: "%s") { - activityLog(first: 50, filter: { activityTypes: [POSTGRES_DELETED] }) { - nodes { - __typename - message - actor - createdAt - resourceType - resourceName - environmentName - teamSlug - } - } - } - } - ]], mainTeam:slug())) - - t.check { - data = { - team = { - activityLog = { - nodes = { - { - __typename = "PostgresDeletedActivityLogEntry", - message = "Deleted Postgres", - actor = user:email(), - createdAt = NotNull(), - resourceType = "POSTGRES", - resourceName = "foobar", - environmentName = "dev", - teamSlug = mainTeam:slug(), - }, - }, - }, - }, - }, - } +Test.gql("List concrete PostgresInstances with their logical owners", function(t) + t.addHeader("x-user-email", user:email()) + t.query [[{ team(slug: "someteamname") { postgresInstances(orderBy: {field: NAME, direction: ASC}) { + nodes { name state postgres { name majorVersion activeInstance } } + } } }]] + t.check { data = { team = { postgresInstances = { nodes = { + { name = "another-db", state = "AVAILABLE", postgres = { name = "another-db", majorVersion = "16", activeInstance = "another-db" } }, + { name = "foobar", state = "AVAILABLE", postgres = { name = "foobar", majorVersion = "17", activeInstance = "foobar" } }, + { name = "with-audit", state = "AVAILABLE", postgres = { name = "with-audit", majorVersion = "16", activeInstance = "with-audit" } }, + { name = "without-audit", state = "AVAILABLE", postgres = { name = "without-audit", majorVersion = "15", activeInstance = "without-audit" } }, + } } } } } +end) + +Test.gql("Retrieve logical Postgres and selected physical instance separately", function(t) + t.addHeader("x-user-email", user:email()) + t.query [[{ team(slug:"someteamname") { environment(name:"dev") { + postgres(name:"foobar") { name activeInstance majorVersion highAvailability resources { cpu memory diskSize } } + postgresInstance(name:"foobar") { name postgres { name } teamEnvironment { name } } + } } }]] + t.check { data = { team = { environment = { + postgres = { name = "foobar", activeInstance = "foobar", majorVersion = "17", highAvailability = false, resources = { cpu = "100m", memory = "2Gi", diskSize = "2Gi" } }, + postgresInstance = { name = "foobar", postgres = { name = "foobar" }, teamEnvironment = { name = "dev" } }, + } } } } +end) + +Test.gql("Physical instances may be filtered by observed state", function(t) + t.addHeader("x-user-email", user:email()) + t.query [[{ team(slug:"someteamname") { postgresInstances(filter: {states:[AVAILABLE]}) { + nodes { name } facets { states { state count } } + } } }]] + t.check { data = { team = { postgresInstances = { + nodes = { { name = "another-db" }, { name = "foobar" }, { name = "with-audit" }, { name = "without-audit" } }, + facets = { states = { { state = "AVAILABLE", count = 4 } } }, + } } } } +end) + +Test.gql("A workload follows the active physical instance", function(t) + t.addHeader("x-user-email", user:email()) + t.query [[{ team(slug:"someteamname") { environment(name:"dev") { + application(name:"app-with-postgres") { postgresInstances { nodes { name postgres { name } } } } + postgresInstance(name:"foobar") { workloads { nodes { __typename name } } } + } } }]] + t.check { data = { team = { environment = { + application = { postgresInstances = { nodes = { { name = "foobar", postgres = { name = "foobar" } } } } }, + postgresInstance = { workloads = { nodes = { + { __typename = "Application", name = "app-with-postgres" }, + { __typename = "Application", name = "app-with-postgres-2" }, + { __typename = "Job", name = "job-with-postgres" }, + } } }, + } } } } +end) + +Test.gql("Delete a concrete PostgresInstance requires authorization", function(t) + t.addHeader("x-user-email", nonMember:email()) + t.query [[mutation { deletePostgres(input:{name:"foobar",environmentName:"dev",teamSlug:"someteamname"}) { postgresDeleted } }]] + t.check { errors = { { message = Contains('postgres:delete'), path = { "deletePostgres" } } }, data = Null } end) diff --git a/integration_tests/postgres_workloads.lua b/integration_tests/postgres_workloads.lua new file mode 100644 index 000000000..3286ce062 --- /dev/null +++ b/integration_tests/postgres_workloads.lua @@ -0,0 +1,36 @@ +local user = User.new("pg-workload-user", "pg-workload-user@usersen.com") +local team = Team.new("postgres-workload-team", "Testing workload Postgres uses", "#postgres-workloads") +team:addMember(user) +Helper.readK8sResources("k8s_resources/postgres_workloads") + +Test.gql("Application and job resolve every uses.postgres entry to its selected instance", function(t) + t.addHeader("x-user-email", user:email()) + t.query [[{ team(slug: "postgres-workload-team") { environment(name: "dev") { + application(name: "consumer") { postgresInstances { nodes { name postgres { name } } } } + job(name: "scheduled-reader") { postgresInstances { nodes { name postgres { name } } } } + } } }]] + local instances = { + { name = "orders-green", postgres = { name = "orders" } }, + { name = "reports-recovered", postgres = { name = "reports" } }, + } + t.check { data = { team = { environment = { + application = { postgresInstances = { nodes = instances } }, + job = { postgresInstances = { nodes = instances } }, + } } } } +end) + +Test.gql("PostgresInstance workloads reference its Postgres through uses.postgres", function(t) + t.addHeader("x-user-email", user:email()) + t.query [[{ team(slug: "postgres-workload-team") { environment(name: "dev") { + postgresInstance(name: "orders-green") { workloads { nodes { __typename name } } } + other: postgresInstance(name: "reports-recovered") { workloads { nodes { __typename name } } } + } } }]] + local workloads = { + { __typename = "Application", name = "consumer" }, + { __typename = "Job", name = "scheduled-reader" }, + } + t.check { data = { team = { environment = { + postgresInstance = { workloads = { nodes = workloads } }, + other = { workloads = { nodes = workloads } }, + } } } } +end) diff --git a/internal/apply/whitelist.go b/internal/apply/whitelist.go index de1e59af0..23acf25e7 100644 --- a/internal/apply/whitelist.go +++ b/internal/apply/whitelist.go @@ -63,8 +63,8 @@ var allowedResources = map[AllowedResource]schema.GroupVersionResource{ }, // Postgres (NAIS) - {APIVersion: "data.nais.io/v1", Kind: "Postgres"}: { - Group: "data.nais.io", Version: "v1", Resource: "postgres", + {APIVersion: "nais.io/v1", Kind: "Postgres"}: { + Group: "nais.io", Version: "v1", Resource: "postgres", }, // IAM (Config Connector) diff --git a/internal/cmd/api/http.go b/internal/cmd/api/http.go index 8e9d396b2..34a454ccd 100644 --- a/internal/cmd/api/http.go +++ b/internal/cmd/api/http.go @@ -355,7 +355,7 @@ func ConfigureGraph( ctx = alerts.NewLoaderContext(ctx, prometheusClient, log) ctx = metrics.NewLoaderContext(ctx, prometheusClient, log) ctx = sqlinstance.NewLoaderContext(ctx, sqlAdminService, watchers.SqlDatabaseWatcher, watchers.SqlInstanceWatcher, auditLogProjectID, auditLogLocation) - ctx = postgres.NewLoaderContext(ctx, watchers.PostgresWatcher, auditLogProjectID, auditLogLocation) + ctx = postgres.NewLoaderContext(ctx, watchers.PostgresWatcher, auditLogProjectID, auditLogLocation, tenantName) ctx = aivencredentials.NewClientContext(ctx, dynamicClients, log) ctx = database.NewLoaderContext(ctx, pool) ctx = issue.NewContext(ctx, pool) diff --git a/internal/graph/gengql/postgres.generated.go b/internal/graph/gengql/postgres.generated.go index 437760ad6..6f55b49b1 100644 --- a/internal/graph/gengql/postgres.generated.go +++ b/internal/graph/gengql/postgres.generated.go @@ -32,11 +32,9 @@ type PostgresAccessResolver interface { type PostgresInstanceResolver interface { Team(ctx context.Context, obj *postgres.PostgresInstance) (*team.Team, error) TeamEnvironment(ctx context.Context, obj *postgres.PostgresInstance) (*team.TeamEnvironment, error) + Postgres(ctx context.Context, obj *postgres.PostgresInstance) (*postgres.Postgres, error) Workloads(ctx context.Context, obj *postgres.PostgresInstance, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor) (*pagination.Connection[workload.Workload], error) } -type PostgresInstanceAuditResolver interface { - URL(ctx context.Context, obj *postgres.PostgresInstanceAudit) (*string, error) -} type PostgresInstanceConnectionResolver interface { Facets(ctx context.Context, obj *pagination.FacetableConnection[*postgres.PostgresInstance, *postgres.PostgresInstanceFilter]) (*postgres.PostgresInstanceFacets, error) } @@ -160,16 +158,140 @@ func (ec *executionContext) fieldContext_DeletePostgresPayload_postgresDeleted(_ return graphql.NewScalarFieldContext("DeletePostgresPayload", field, false, false, errors.New("field of type Boolean does not have child fields")) } -func (ec *executionContext) _GrantPostgresAccessPayload_error(ctx context.Context, field graphql.CollectedField, obj *postgres.GrantPostgresAccessPayload) (ret graphql.Marshaler) { +func (ec *executionContext) _Postgres_id(ctx context.Context, field graphql.CollectedField, obj *postgres.Postgres) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_Postgres_id(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.ID(), nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v ident.Ident) graphql.Marshaler { + return ec.marshalNID2githubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋidentᚐIdent(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_Postgres_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("Postgres", field, true, false, errors.New("field of type ID does not have child fields")) +} + +func (ec *executionContext) _Postgres_name(ctx context.Context, field graphql.CollectedField, obj *postgres.Postgres) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_Postgres_name(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Name, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { + return ec.marshalNString2string(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_Postgres_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("Postgres", field, false, false, errors.New("field of type String does not have child fields")) +} + +func (ec *executionContext) _Postgres_majorVersion(ctx context.Context, field graphql.CollectedField, obj *postgres.Postgres) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_Postgres_majorVersion(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.MajorVersion, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { + return ec.marshalNString2string(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_Postgres_majorVersion(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("Postgres", field, false, false, errors.New("field of type String does not have child fields")) +} + +func (ec *executionContext) _Postgres_highAvailability(ctx context.Context, field graphql.CollectedField, obj *postgres.Postgres) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_Postgres_highAvailability(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.HighAvailability, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v bool) graphql.Marshaler { + return ec.marshalNBoolean2bool(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_Postgres_highAvailability(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("Postgres", field, false, false, errors.New("field of type Boolean does not have child fields")) +} + +func (ec *executionContext) _Postgres_resources(ctx context.Context, field graphql.CollectedField, obj *postgres.Postgres) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_Postgres_resources(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Resources, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v postgres.PostgresResources) graphql.Marshaler { + return ec.marshalNPostgresResources2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresResources(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_Postgres_resources(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Postgres", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_PostgresResources(ctx, field) + }, + } + return fc, nil +} + +func (ec *executionContext) _Postgres_activeInstance(ctx context.Context, field graphql.CollectedField, obj *postgres.Postgres) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_GrantPostgresAccessPayload_error(ctx, field) + return ec.fieldContext_Postgres_activeInstance(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Error, nil + return obj.ActiveInstance, nil }, nil, func(ctx context.Context, selections ast.SelectionSet, v *string) graphql.Marshaler { @@ -179,8 +301,40 @@ func (ec *executionContext) _GrantPostgresAccessPayload_error(ctx context.Contex false, ) } -func (ec *executionContext) fieldContext_GrantPostgresAccessPayload_error(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("GrantPostgresAccessPayload", field, false, false, errors.New("field of type String does not have child fields")) +func (ec *executionContext) fieldContext_Postgres_activeInstance(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("Postgres", field, false, false, errors.New("field of type String does not have child fields")) +} + +func (ec *executionContext) _Postgres_labels(ctx context.Context, field graphql.CollectedField, obj *postgres.Postgres) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_Postgres_labels(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Labels, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v []*model.ResourceLabel) graphql.Marshaler { + return ec.marshalNResourceLabel2ᚕᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋmodelᚐResourceLabelᚄ(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_Postgres_labels(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Postgres", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_ResourceLabel(ctx, field) + }, + } + return fc, nil } func (ec *executionContext) _PostgresAccess_id(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccess) (ret graphql.Marshaler) { @@ -417,48 +571,39 @@ func (ec *executionContext) fieldContext_PostgresAccess_message(_ context.Contex return graphql.NewScalarFieldContext("PostgresAccess", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresAccess_tunnel(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccess) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresAccess_relayAccess(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccess) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresAccess_tunnel(ctx, field) + return ec.fieldContext_PostgresAccess_relayAccess(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Tunnel, nil + return obj.RelayAccess, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v *postgres.PostgresAccessTunnel) graphql.Marshaler { - return ec.marshalOPostgresAccessTunnel2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccessTunnel(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *string) graphql.Marshaler { + return ec.marshalOString2ᚖstring(ctx, selections, v) }, true, false, ) } -func (ec *executionContext) fieldContext_PostgresAccess_tunnel(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "PostgresAccess", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_PostgresAccessTunnel(ctx, field) - }, - } - return fc, nil +func (ec *executionContext) fieldContext_PostgresAccess_relayAccess(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresAccess", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresAccessConnection_password(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccessConnection) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresAccessConnection_username(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccessConnection) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresAccessConnection_password(ctx, field) + return ec.fieldContext_PostgresAccessConnection_username(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Password, nil + return obj.Username, nil }, nil, func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { @@ -468,20 +613,20 @@ func (ec *executionContext) _PostgresAccessConnection_password(ctx context.Conte true, ) } -func (ec *executionContext) fieldContext_PostgresAccessConnection_password(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_PostgresAccessConnection_username(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("PostgresAccessConnection", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresAccessConnection_caCertificate(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccessConnection) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresAccessConnection_password(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccessConnection) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresAccessConnection_caCertificate(ctx, field) + return ec.fieldContext_PostgresAccessConnection_password(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.CACertificate, nil + return obj.Password, nil }, nil, func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { @@ -491,20 +636,20 @@ func (ec *executionContext) _PostgresAccessConnection_caCertificate(ctx context. true, ) } -func (ec *executionContext) fieldContext_PostgresAccessConnection_caCertificate(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_PostgresAccessConnection_password(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("PostgresAccessConnection", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresAccessConnection_serverName(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccessConnection) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresAccessConnection_caCertificate(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccessConnection) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresAccessConnection_serverName(ctx, field) + return ec.fieldContext_PostgresAccessConnection_caCertificate(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.ServerName, nil + return obj.CACertificate, nil }, nil, func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { @@ -514,52 +659,20 @@ func (ec *executionContext) _PostgresAccessConnection_serverName(ctx context.Con true, ) } -func (ec *executionContext) fieldContext_PostgresAccessConnection_serverName(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_PostgresAccessConnection_caCertificate(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("PostgresAccessConnection", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresAccessConnection_tunnel(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccessConnection) (ret graphql.Marshaler) { - return graphql.ResolveField( - ctx, - ec.OperationContext, - field, - func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresAccessConnection_tunnel(ctx, field) - }, - func(ctx context.Context) (any, error) { - return obj.Tunnel, nil - }, - nil, - func(ctx context.Context, selections ast.SelectionSet, v postgres.PostgresAccessConnectionTunnel) graphql.Marshaler { - return ec.marshalNPostgresAccessConnectionTunnel2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccessConnectionTunnel(ctx, selections, v) - }, - true, - true, - ) -} -func (ec *executionContext) fieldContext_PostgresAccessConnection_tunnel(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "PostgresAccessConnection", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_PostgresAccessConnectionTunnel(ctx, field) - }, - } - return fc, nil -} - -func (ec *executionContext) _PostgresAccessConnectionTunnel_endpoint(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccessConnectionTunnel) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresAccessConnection_serverName(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccessConnection) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresAccessConnectionTunnel_endpoint(ctx, field) + return ec.fieldContext_PostgresAccessConnection_serverName(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Endpoint, nil + return obj.ServerName, nil }, nil, func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { @@ -569,20 +682,20 @@ func (ec *executionContext) _PostgresAccessConnectionTunnel_endpoint(ctx context true, ) } -func (ec *executionContext) fieldContext_PostgresAccessConnectionTunnel_endpoint(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresAccessConnectionTunnel", field, false, false, errors.New("field of type String does not have child fields")) +func (ec *executionContext) fieldContext_PostgresAccessConnection_serverName(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresAccessConnection", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresAccessConnectionTunnel_gatewayPublicKey(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccessConnectionTunnel) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresAccessConnection_relayEndpoint(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccessConnection) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresAccessConnectionTunnel_gatewayPublicKey(ctx, field) + return ec.fieldContext_PostgresAccessConnection_relayEndpoint(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.GatewayPublicKey, nil + return obj.RelayEndpoint, nil }, nil, func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { @@ -592,20 +705,20 @@ func (ec *executionContext) _PostgresAccessConnectionTunnel_gatewayPublicKey(ctx true, ) } -func (ec *executionContext) fieldContext_PostgresAccessConnectionTunnel_gatewayPublicKey(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresAccessConnectionTunnel", field, false, false, errors.New("field of type String does not have child fields")) +func (ec *executionContext) fieldContext_PostgresAccessConnection_relayEndpoint(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresAccessConnection", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresAccessTunnel_name(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccessTunnel) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresAccessConnection_relayAccess(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccessConnection) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresAccessTunnel_name(ctx, field) + return ec.fieldContext_PostgresAccessConnection_relayAccess(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Name, nil + return obj.RelayAccess, nil }, nil, func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { @@ -615,54 +728,31 @@ func (ec *executionContext) _PostgresAccessTunnel_name(ctx context.Context, fiel true, ) } -func (ec *executionContext) fieldContext_PostgresAccessTunnel_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresAccessTunnel", field, false, false, errors.New("field of type String does not have child fields")) +func (ec *executionContext) fieldContext_PostgresAccessConnection_relayAccess(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresAccessConnection", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresAccessTunnel_endpoint(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccessTunnel) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresAccessConnection_relayToken(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccessConnection) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresAccessTunnel_endpoint(ctx, field) + return ec.fieldContext_PostgresAccessConnection_relayToken(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Endpoint, nil + return obj.RelayToken, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v *string) graphql.Marshaler { - return ec.marshalOString2ᚖstring(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { + return ec.marshalNString2string(ctx, selections, v) }, true, - false, - ) -} -func (ec *executionContext) fieldContext_PostgresAccessTunnel_endpoint(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresAccessTunnel", field, false, false, errors.New("field of type String does not have child fields")) -} - -func (ec *executionContext) _PostgresAccessTunnel_gatewayPublicKey(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccessTunnel) (ret graphql.Marshaler) { - return graphql.ResolveField( - ctx, - ec.OperationContext, - field, - func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresAccessTunnel_gatewayPublicKey(ctx, field) - }, - func(ctx context.Context) (any, error) { - return obj.GatewayPublicKey, nil - }, - nil, - func(ctx context.Context, selections ast.SelectionSet, v *string) graphql.Marshaler { - return ec.marshalOString2ᚖstring(ctx, selections, v) - }, true, - false, ) } -func (ec *executionContext) fieldContext_PostgresAccessTunnel_gatewayPublicKey(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresAccessTunnel", field, false, false, errors.New("field of type String does not have child fields")) +func (ec *executionContext) fieldContext_PostgresAccessConnection_relayToken(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresAccessConnection", field, false, false, errors.New("field of type String does not have child fields")) } func (ec *executionContext) _PostgresDeletedActivityLogEntry_id(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresDeletedActivityLogEntry) (ret graphql.Marshaler) { @@ -1221,6 +1311,38 @@ func (ec *executionContext) fieldContext_PostgresInstance_teamEnvironment(_ cont return fc, nil } +func (ec *executionContext) _PostgresInstance_postgres(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstance) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_PostgresInstance_postgres(ctx, field) + }, + func(ctx context.Context) (any, error) { + return ec.Resolvers.PostgresInstance().Postgres(ctx, obj) + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *postgres.Postgres) graphql.Marshaler { + return ec.marshalNPostgres2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgres(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_PostgresInstance_postgres(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "PostgresInstance", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_Postgres(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _PostgresInstance_workloads(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstance) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -1265,130 +1387,20 @@ func (ec *executionContext) fieldContext_PostgresInstance_workloads(ctx context. return fc, nil } -func (ec *executionContext) _PostgresInstance_resources(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstance) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresInstance_state(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstance) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstance_resources(ctx, field) + return ec.fieldContext_PostgresInstance_state(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Resources, nil + return obj.State, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v *postgres.PostgresInstanceResources) graphql.Marshaler { - return ec.marshalNPostgresInstanceResources2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceResources(ctx, selections, v) - }, - true, - true, - ) -} -func (ec *executionContext) fieldContext_PostgresInstance_resources(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "PostgresInstance", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_PostgresInstanceResources(ctx, field) - }, - } - return fc, nil -} - -func (ec *executionContext) _PostgresInstance_majorVersion(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstance) (ret graphql.Marshaler) { - return graphql.ResolveField( - ctx, - ec.OperationContext, - field, - func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstance_majorVersion(ctx, field) - }, - func(ctx context.Context) (any, error) { - return obj.MajorVersion, nil - }, - nil, - func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { - return ec.marshalNString2string(ctx, selections, v) - }, - true, - true, - ) -} -func (ec *executionContext) fieldContext_PostgresInstance_majorVersion(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresInstance", field, false, false, errors.New("field of type String does not have child fields")) -} - -func (ec *executionContext) _PostgresInstance_audit(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstance) (ret graphql.Marshaler) { - return graphql.ResolveField( - ctx, - ec.OperationContext, - field, - func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstance_audit(ctx, field) - }, - func(ctx context.Context) (any, error) { - return obj.Audit, nil - }, - nil, - func(ctx context.Context, selections ast.SelectionSet, v postgres.PostgresInstanceAudit) graphql.Marshaler { - return ec.marshalNPostgresInstanceAudit2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceAudit(ctx, selections, v) - }, - true, - true, - ) -} -func (ec *executionContext) fieldContext_PostgresInstance_audit(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "PostgresInstance", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_PostgresInstanceAudit(ctx, field) - }, - } - return fc, nil -} - -func (ec *executionContext) _PostgresInstance_highAvailability(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstance) (ret graphql.Marshaler) { - return graphql.ResolveField( - ctx, - ec.OperationContext, - field, - func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstance_highAvailability(ctx, field) - }, - func(ctx context.Context) (any, error) { - return obj.HighAvailability, nil - }, - nil, - func(ctx context.Context, selections ast.SelectionSet, v bool) graphql.Marshaler { - return ec.marshalNBoolean2bool(ctx, selections, v) - }, - true, - true, - ) -} -func (ec *executionContext) fieldContext_PostgresInstance_highAvailability(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresInstance", field, false, false, errors.New("field of type Boolean does not have child fields")) -} - -func (ec *executionContext) _PostgresInstance_state(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstance) (ret graphql.Marshaler) { - return graphql.ResolveField( - ctx, - ec.OperationContext, - field, - func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstance_state(ctx, field) - }, - func(ctx context.Context) (any, error) { - return obj.State, nil - }, - nil, - func(ctx context.Context, selections ast.SelectionSet, v postgres.PostgresInstanceState) graphql.Marshaler { - return ec.marshalNPostgresInstanceState2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceState(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v postgres.PostgresInstanceState) graphql.Marshaler { + return ec.marshalNPostgresInstanceState2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceState(ctx, selections, v) }, true, true, @@ -1398,38 +1410,6 @@ func (ec *executionContext) fieldContext_PostgresInstance_state(_ context.Contex return graphql.NewScalarFieldContext("PostgresInstance", field, false, false, errors.New("field of type PostgresInstanceState does not have child fields")) } -func (ec *executionContext) _PostgresInstance_maintenanceWindow(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstance) (ret graphql.Marshaler) { - return graphql.ResolveField( - ctx, - ec.OperationContext, - field, - func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstance_maintenanceWindow(ctx, field) - }, - func(ctx context.Context) (any, error) { - return obj.MaintenanceWindow, nil - }, - nil, - func(ctx context.Context, selections ast.SelectionSet, v *postgres.PostgresInstanceMaintenanceWindow) graphql.Marshaler { - return ec.marshalOPostgresInstanceMaintenanceWindow2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceMaintenanceWindow(ctx, selections, v) - }, - true, - false, - ) -} -func (ec *executionContext) fieldContext_PostgresInstance_maintenanceWindow(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "PostgresInstance", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_PostgresInstanceMaintenanceWindow(ctx, field) - }, - } - return fc, nil -} - func (ec *executionContext) _PostgresInstance_labels(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstance) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -1462,75 +1442,6 @@ func (ec *executionContext) fieldContext_PostgresInstance_labels(_ context.Conte return fc, nil } -func (ec *executionContext) _PostgresInstanceAudit_enabled(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstanceAudit) (ret graphql.Marshaler) { - return graphql.ResolveField( - ctx, - ec.OperationContext, - field, - func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstanceAudit_enabled(ctx, field) - }, - func(ctx context.Context) (any, error) { - return obj.Enabled, nil - }, - nil, - func(ctx context.Context, selections ast.SelectionSet, v bool) graphql.Marshaler { - return ec.marshalNBoolean2bool(ctx, selections, v) - }, - true, - true, - ) -} -func (ec *executionContext) fieldContext_PostgresInstanceAudit_enabled(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresInstanceAudit", field, false, false, errors.New("field of type Boolean does not have child fields")) -} - -func (ec *executionContext) _PostgresInstanceAudit_url(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstanceAudit) (ret graphql.Marshaler) { - return graphql.ResolveField( - ctx, - ec.OperationContext, - field, - func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstanceAudit_url(ctx, field) - }, - func(ctx context.Context) (any, error) { - return ec.Resolvers.PostgresInstanceAudit().URL(ctx, obj) - }, - nil, - func(ctx context.Context, selections ast.SelectionSet, v *string) graphql.Marshaler { - return ec.marshalOString2ᚖstring(ctx, selections, v) - }, - true, - false, - ) -} -func (ec *executionContext) fieldContext_PostgresInstanceAudit_url(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresInstanceAudit", field, true, true, errors.New("field of type String does not have child fields")) -} - -func (ec *executionContext) _PostgresInstanceAudit_statementClasses(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstanceAudit) (ret graphql.Marshaler) { - return graphql.ResolveField( - ctx, - ec.OperationContext, - field, - func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstanceAudit_statementClasses(ctx, field) - }, - func(ctx context.Context) (any, error) { - return obj.StatementClasses, nil - }, - nil, - func(ctx context.Context, selections ast.SelectionSet, v []string) graphql.Marshaler { - return ec.marshalOString2ᚕstringᚄ(ctx, selections, v) - }, - true, - false, - ) -} -func (ec *executionContext) fieldContext_PostgresInstanceAudit_statementClasses(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresInstanceAudit", field, false, false, errors.New("field of type String does not have child fields")) -} - func (ec *executionContext) _PostgresInstanceConnection_pageInfo(ctx context.Context, field graphql.CollectedField, obj *pagination.FacetableConnection[*postgres.PostgresInstance, *postgres.PostgresInstanceFilter]) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -1778,70 +1689,6 @@ func (ec *executionContext) fieldContext_PostgresInstanceFacets_states(_ context return fc, nil } -func (ec *executionContext) _PostgresInstanceFacets_highAvailability(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstanceFacets) (ret graphql.Marshaler) { - return graphql.ResolveField( - ctx, - ec.OperationContext, - field, - func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstanceFacets_highAvailability(ctx, field) - }, - func(ctx context.Context) (any, error) { - return obj.HighAvailability(ctx), nil - }, - nil, - func(ctx context.Context, selections ast.SelectionSet, v []model.BooleanFacetItem) graphql.Marshaler { - return ec.marshalNBooleanFacetItem2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋmodelᚐBooleanFacetItemᚄ(ctx, selections, v) - }, - true, - true, - ) -} -func (ec *executionContext) fieldContext_PostgresInstanceFacets_highAvailability(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "PostgresInstanceFacets", - Field: field, - IsMethod: true, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_BooleanFacetItem(ctx, field) - }, - } - return fc, nil -} - -func (ec *executionContext) _PostgresInstanceFacets_majorVersions(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstanceFacets) (ret graphql.Marshaler) { - return graphql.ResolveField( - ctx, - ec.OperationContext, - field, - func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstanceFacets_majorVersions(ctx, field) - }, - func(ctx context.Context) (any, error) { - return obj.MajorVersions(ctx), nil - }, - nil, - func(ctx context.Context, selections ast.SelectionSet, v []model.StringFacetItem) graphql.Marshaler { - return ec.marshalNStringFacetItem2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋmodelᚐStringFacetItemᚄ(ctx, selections, v) - }, - true, - true, - ) -} -func (ec *executionContext) fieldContext_PostgresInstanceFacets_majorVersions(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "PostgresInstanceFacets", - Field: field, - IsMethod: true, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_StringFacetItem(ctx, field) - }, - } - return fc, nil -} - func (ec *executionContext) _PostgresInstanceFacets_labels(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstanceFacets) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -1874,121 +1721,6 @@ func (ec *executionContext) fieldContext_PostgresInstanceFacets_labels(_ context return fc, nil } -func (ec *executionContext) _PostgresInstanceMaintenanceWindow_day(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstanceMaintenanceWindow) (ret graphql.Marshaler) { - return graphql.ResolveField( - ctx, - ec.OperationContext, - field, - func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstanceMaintenanceWindow_day(ctx, field) - }, - func(ctx context.Context) (any, error) { - return obj.Day, nil - }, - nil, - func(ctx context.Context, selections ast.SelectionSet, v int) graphql.Marshaler { - return ec.marshalNInt2int(ctx, selections, v) - }, - true, - true, - ) -} -func (ec *executionContext) fieldContext_PostgresInstanceMaintenanceWindow_day(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresInstanceMaintenanceWindow", field, false, false, errors.New("field of type Int does not have child fields")) -} - -func (ec *executionContext) _PostgresInstanceMaintenanceWindow_hour(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstanceMaintenanceWindow) (ret graphql.Marshaler) { - return graphql.ResolveField( - ctx, - ec.OperationContext, - field, - func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstanceMaintenanceWindow_hour(ctx, field) - }, - func(ctx context.Context) (any, error) { - return obj.Hour, nil - }, - nil, - func(ctx context.Context, selections ast.SelectionSet, v int) graphql.Marshaler { - return ec.marshalNInt2int(ctx, selections, v) - }, - true, - true, - ) -} -func (ec *executionContext) fieldContext_PostgresInstanceMaintenanceWindow_hour(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresInstanceMaintenanceWindow", field, false, false, errors.New("field of type Int does not have child fields")) -} - -func (ec *executionContext) _PostgresInstanceResources_cpu(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstanceResources) (ret graphql.Marshaler) { - return graphql.ResolveField( - ctx, - ec.OperationContext, - field, - func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstanceResources_cpu(ctx, field) - }, - func(ctx context.Context) (any, error) { - return obj.CPU, nil - }, - nil, - func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { - return ec.marshalNString2string(ctx, selections, v) - }, - true, - true, - ) -} -func (ec *executionContext) fieldContext_PostgresInstanceResources_cpu(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresInstanceResources", field, false, false, errors.New("field of type String does not have child fields")) -} - -func (ec *executionContext) _PostgresInstanceResources_memory(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstanceResources) (ret graphql.Marshaler) { - return graphql.ResolveField( - ctx, - ec.OperationContext, - field, - func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstanceResources_memory(ctx, field) - }, - func(ctx context.Context) (any, error) { - return obj.Memory, nil - }, - nil, - func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { - return ec.marshalNString2string(ctx, selections, v) - }, - true, - true, - ) -} -func (ec *executionContext) fieldContext_PostgresInstanceResources_memory(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresInstanceResources", field, false, false, errors.New("field of type String does not have child fields")) -} - -func (ec *executionContext) _PostgresInstanceResources_diskSize(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstanceResources) (ret graphql.Marshaler) { - return graphql.ResolveField( - ctx, - ec.OperationContext, - field, - func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstanceResources_diskSize(ctx, field) - }, - func(ctx context.Context) (any, error) { - return obj.DiskSize, nil - }, - nil, - func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { - return ec.marshalNString2string(ctx, selections, v) - }, - true, - true, - ) -} -func (ec *executionContext) fieldContext_PostgresInstanceResources_diskSize(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresInstanceResources", field, false, false, errors.New("field of type String does not have child fields")) -} - func (ec *executionContext) _PostgresInstanceStateFacetItem_state(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstanceStateFacetItem) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -2454,54 +2186,123 @@ func (ec *executionContext) _PostgresPersonalAccessCreatedActivityLogEntryData_u true, ) } -func (ec *executionContext) fieldContext_PostgresPersonalAccessCreatedActivityLogEntryData_username(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresPersonalAccessCreatedActivityLogEntryData", field, false, false, errors.New("field of type String does not have child fields")) +func (ec *executionContext) fieldContext_PostgresPersonalAccessCreatedActivityLogEntryData_username(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresPersonalAccessCreatedActivityLogEntryData", field, false, false, errors.New("field of type String does not have child fields")) +} + +func (ec *executionContext) _PostgresPersonalAccessCreatedActivityLogEntryData_expiresAt(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresPersonalAccessCreatedActivityLogEntryData) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_PostgresPersonalAccessCreatedActivityLogEntryData_expiresAt(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.ExpiresAt, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v time.Time) graphql.Marshaler { + return ec.marshalNTime2timeᚐTime(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_PostgresPersonalAccessCreatedActivityLogEntryData_expiresAt(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresPersonalAccessCreatedActivityLogEntryData", field, false, false, errors.New("field of type Time does not have child fields")) +} + +func (ec *executionContext) _PostgresPersonalAccessCreatedActivityLogEntryData_reason(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresPersonalAccessCreatedActivityLogEntryData) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_PostgresPersonalAccessCreatedActivityLogEntryData_reason(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Reason, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { + return ec.marshalNString2string(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_PostgresPersonalAccessCreatedActivityLogEntryData_reason(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresPersonalAccessCreatedActivityLogEntryData", field, false, false, errors.New("field of type String does not have child fields")) +} + +func (ec *executionContext) _PostgresResources_cpu(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresResources) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_PostgresResources_cpu(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.CPU, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *string) graphql.Marshaler { + return ec.marshalOString2ᚖstring(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_PostgresResources_cpu(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresResources", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresPersonalAccessCreatedActivityLogEntryData_expiresAt(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresPersonalAccessCreatedActivityLogEntryData) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresResources_memory(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresResources) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresPersonalAccessCreatedActivityLogEntryData_expiresAt(ctx, field) + return ec.fieldContext_PostgresResources_memory(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.ExpiresAt, nil + return obj.Memory, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v time.Time) graphql.Marshaler { - return ec.marshalNTime2timeᚐTime(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *string) graphql.Marshaler { + return ec.marshalOString2ᚖstring(ctx, selections, v) }, true, - true, + false, ) } -func (ec *executionContext) fieldContext_PostgresPersonalAccessCreatedActivityLogEntryData_expiresAt(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresPersonalAccessCreatedActivityLogEntryData", field, false, false, errors.New("field of type Time does not have child fields")) +func (ec *executionContext) fieldContext_PostgresResources_memory(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresResources", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresPersonalAccessCreatedActivityLogEntryData_reason(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresPersonalAccessCreatedActivityLogEntryData) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresResources_diskSize(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresResources) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresPersonalAccessCreatedActivityLogEntryData_reason(ctx, field) + return ec.fieldContext_PostgresResources_diskSize(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Reason, nil + return obj.DiskSize, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { - return ec.marshalNString2string(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *string) graphql.Marshaler { + return ec.marshalOString2ᚖstring(ctx, selections, v) }, true, - true, + false, ) } -func (ec *executionContext) fieldContext_PostgresPersonalAccessCreatedActivityLogEntryData_reason(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresPersonalAccessCreatedActivityLogEntryData", field, false, false, errors.New("field of type String does not have child fields")) +func (ec *executionContext) fieldContext_PostgresResources_diskSize(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresResources", field, false, false, errors.New("field of type String does not have child fields")) } func (ec *executionContext) _TeamInventoryCountPostgresInstances_total(ctx context.Context, field graphql.CollectedField, obj *postgres.TeamInventoryCountPostgresInstances) (ret graphql.Marshaler) { @@ -2542,7 +2343,7 @@ func (ec *executionContext) unmarshalInputCreatePostgresAccessInput(ctx context. asMap[k] = v } - fieldsInOrder := [...]string{"postgresInstance", "teamSlug", "environmentName", "accessLevel", "clientWireGuardPublicKey", "reason", "ttl"} + fieldsInOrder := [...]string{"postgresInstance", "teamSlug", "environmentName", "accessLevel", "reason", "ttl"} for _, k := range fieldsInOrder { v, ok := asMap[k] if !ok { @@ -2577,13 +2378,6 @@ func (ec *executionContext) unmarshalInputCreatePostgresAccessInput(ctx context. return it, err } it.AccessLevel = data - case "clientWireGuardPublicKey": - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("clientWireGuardPublicKey")) - data, err := ec.unmarshalNString2string(ctx, v) - if err != nil { - return it, err - } - it.ClientWireGuardPublicKey = data case "reason": ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("reason")) data, err := ec.unmarshalNString2string(ctx, v) @@ -2647,64 +2441,6 @@ func (ec *executionContext) unmarshalInputDeletePostgresInput(ctx context.Contex return it, nil } -func (ec *executionContext) unmarshalInputGrantPostgresAccessInput(ctx context.Context, obj any) (postgres.GrantPostgresAccessInput, error) { - var it postgres.GrantPostgresAccessInput - if obj == nil { - return it, nil - } - - asMap := map[string]any{} - for k, v := range obj.(map[string]any) { - asMap[k] = v - } - - fieldsInOrder := [...]string{"clusterName", "teamSlug", "environmentName", "grantee", "duration"} - for _, k := range fieldsInOrder { - v, ok := asMap[k] - if !ok { - continue - } - switch k { - case "clusterName": - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("clusterName")) - data, err := ec.unmarshalNString2string(ctx, v) - if err != nil { - return it, err - } - it.ClusterName = data - case "teamSlug": - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("teamSlug")) - data, err := ec.unmarshalNSlug2githubᚗcomᚋnaisᚋapiᚋinternalᚋslugᚐSlug(ctx, v) - if err != nil { - return it, err - } - it.TeamSlug = data - case "environmentName": - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("environmentName")) - data, err := ec.unmarshalNString2string(ctx, v) - if err != nil { - return it, err - } - it.EnvironmentName = data - case "grantee": - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("grantee")) - data, err := ec.unmarshalNString2string(ctx, v) - if err != nil { - return it, err - } - it.Grantee = data - case "duration": - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("duration")) - data, err := ec.unmarshalNString2string(ctx, v) - if err != nil { - return it, err - } - it.Duration = data - } - } - return it, nil -} - func (ec *executionContext) unmarshalInputPostgresAccessConnectionInput(ctx context.Context, obj any) (postgres.PostgresAccessConnectionInput, error) { var it postgres.PostgresAccessConnectionInput if obj == nil { @@ -2760,7 +2496,7 @@ func (ec *executionContext) unmarshalInputPostgresInstanceFilter(ctx context.Con asMap[k] = v } - fieldsInOrder := [...]string{"name", "environments", "states", "highAvailability", "majorVersions", "labels"} + fieldsInOrder := [...]string{"name", "environments", "states", "labels"} for _, k := range fieldsInOrder { v, ok := asMap[k] if !ok { @@ -2788,20 +2524,6 @@ func (ec *executionContext) unmarshalInputPostgresInstanceFilter(ctx context.Con return it, err } it.States = data - case "highAvailability": - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("highAvailability")) - data, err := ec.unmarshalOBoolean2ᚖbool(ctx, v) - if err != nil { - return it, err - } - it.HighAvailability = data - case "majorVersions": - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("majorVersions")) - data, err := ec.unmarshalOString2ᚕstringᚄ(ctx, v) - if err != nil { - return it, err - } - it.MajorVersions = data case "labels": ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("labels")) data, err := ec.unmarshalOLabelFilter2githubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋmodelᚐLabelFiltersᚄ(ctx, v) @@ -2939,19 +2661,49 @@ func (ec *executionContext) _DeletePostgresPayload(ctx context.Context, sel ast. return out } -var grantPostgresAccessPayloadImplementors = []string{"GrantPostgresAccessPayload"} +var postgresImplementors = []string{"Postgres", "Node"} -func (ec *executionContext) _GrantPostgresAccessPayload(ctx context.Context, sel ast.SelectionSet, obj *postgres.GrantPostgresAccessPayload) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, grantPostgresAccessPayloadImplementors) +func (ec *executionContext) _Postgres(ctx context.Context, sel ast.SelectionSet, obj *postgres.Postgres) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, postgresImplementors) out := graphql.NewFieldSet(fields) deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": - out.Values[i] = graphql.MarshalString("GrantPostgresAccessPayload") - case "error": - out.Values[i] = ec._GrantPostgresAccessPayload_error(ctx, field, obj) + out.Values[i] = graphql.MarshalString("Postgres") + case "id": + out.Values[i] = ec._Postgres_id(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "name": + out.Values[i] = ec._Postgres_name(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "majorVersion": + out.Values[i] = ec._Postgres_majorVersion(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "highAvailability": + out.Values[i] = ec._Postgres_highAvailability(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "resources": + out.Values[i] = ec._Postgres_resources(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "activeInstance": + out.Values[i] = ec._Postgres_activeInstance(ctx, field, obj) + case "labels": + out.Values[i] = ec._Postgres_labels(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -3121,8 +2873,8 @@ func (ec *executionContext) _PostgresAccess(ctx context.Context, sel ast.Selecti } case "message": out.Values[i] = ec._PostgresAccess_message(ctx, field, obj) - case "tunnel": - out.Values[i] = ec._PostgresAccess_tunnel(ctx, field, obj) + case "relayAccess": + out.Values[i] = ec._PostgresAccess_relayAccess(ctx, field, obj) default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -3157,6 +2909,11 @@ func (ec *executionContext) _PostgresAccessConnection(ctx context.Context, sel a switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("PostgresAccessConnection") + case "username": + out.Values[i] = ec._PostgresAccessConnection_username(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } case "password": out.Values[i] = ec._PostgresAccessConnection_password(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -3172,98 +2929,21 @@ func (ec *executionContext) _PostgresAccessConnection(ctx context.Context, sel a if out.Values[i] == graphql.Null { out.Invalids++ } - case "tunnel": - out.Values[i] = ec._PostgresAccessConnection_tunnel(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - out.Dispatch(ctx) - if out.Invalids > 0 { - return graphql.Null - } - - atomic.AddInt32(&ec.Deferred, int32(min(len(deferred), math.MaxInt32))) - - for label, dfs := range deferred { - ec.ProcessDeferredGroup(graphql.DeferredGroup{ - Label: label, - Path: graphql.GetPath(ctx), - FieldSet: dfs, - Context: ctx, - }) - } - - return out -} - -var postgresAccessConnectionTunnelImplementors = []string{"PostgresAccessConnectionTunnel"} - -func (ec *executionContext) _PostgresAccessConnectionTunnel(ctx context.Context, sel ast.SelectionSet, obj *postgres.PostgresAccessConnectionTunnel) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, postgresAccessConnectionTunnelImplementors) - - out := graphql.NewFieldSet(fields) - deferred := make(map[string]*graphql.FieldSet) - for i, field := range fields { - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString("PostgresAccessConnectionTunnel") - case "endpoint": - out.Values[i] = ec._PostgresAccessConnectionTunnel_endpoint(ctx, field, obj) + case "relayEndpoint": + out.Values[i] = ec._PostgresAccessConnection_relayEndpoint(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } - case "gatewayPublicKey": - out.Values[i] = ec._PostgresAccessConnectionTunnel_gatewayPublicKey(ctx, field, obj) + case "relayAccess": + out.Values[i] = ec._PostgresAccessConnection_relayAccess(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - out.Dispatch(ctx) - if out.Invalids > 0 { - return graphql.Null - } - - atomic.AddInt32(&ec.Deferred, int32(min(len(deferred), math.MaxInt32))) - - for label, dfs := range deferred { - ec.ProcessDeferredGroup(graphql.DeferredGroup{ - Label: label, - Path: graphql.GetPath(ctx), - FieldSet: dfs, - Context: ctx, - }) - } - - return out -} - -var postgresAccessTunnelImplementors = []string{"PostgresAccessTunnel"} - -func (ec *executionContext) _PostgresAccessTunnel(ctx context.Context, sel ast.SelectionSet, obj *postgres.PostgresAccessTunnel) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, postgresAccessTunnelImplementors) - - out := graphql.NewFieldSet(fields) - deferred := make(map[string]*graphql.FieldSet) - for i, field := range fields { - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString("PostgresAccessTunnel") - case "name": - out.Values[i] = ec._PostgresAccessTunnel_name(ctx, field, obj) + case "relayToken": + out.Values[i] = ec._PostgresAccessConnection_relayToken(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } - case "endpoint": - out.Values[i] = ec._PostgresAccessTunnel_endpoint(ctx, field, obj) - case "gatewayPublicKey": - out.Values[i] = ec._PostgresAccessTunnel_gatewayPublicKey(ctx, field, obj) default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -3571,123 +3251,55 @@ func (ec *executionContext) _PostgresInstance(ctx context.Context, sel ast.Selec } out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) - case "workloads": + case "postgres": field := field innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) - } - }() - res = ec._PostgresInstance_workloads(ctx, field, obj) - if res == graphql.Null { - atomic.AddUint32(&fs.Invalids, 1) - } - return res - } - - if field.Deferrable != nil { - dfs, ok := deferred[field.Deferrable.Label] - di := 0 - if ok { - dfs.AddField(field) - di = len(dfs.Values) - 1 - } else { - dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) - deferred[field.Deferrable.Label] = dfs - } - dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { - return innerFunc(ctx, dfs) - }) - - // don't run the out.Concurrently() call below - out.Values[i] = graphql.Null - continue - } - - out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) - case "resources": - out.Values[i] = ec._PostgresInstance_resources(ctx, field, obj) - if out.Values[i] == graphql.Null { - atomic.AddUint32(&out.Invalids, 1) - } - case "majorVersion": - out.Values[i] = ec._PostgresInstance_majorVersion(ctx, field, obj) - if out.Values[i] == graphql.Null { - atomic.AddUint32(&out.Invalids, 1) - } - case "audit": - out.Values[i] = ec._PostgresInstance_audit(ctx, field, obj) - if out.Values[i] == graphql.Null { - atomic.AddUint32(&out.Invalids, 1) - } - case "highAvailability": - out.Values[i] = ec._PostgresInstance_highAvailability(ctx, field, obj) - if out.Values[i] == graphql.Null { - atomic.AddUint32(&out.Invalids, 1) - } - case "state": - out.Values[i] = ec._PostgresInstance_state(ctx, field, obj) - if out.Values[i] == graphql.Null { - atomic.AddUint32(&out.Invalids, 1) - } - case "maintenanceWindow": - out.Values[i] = ec._PostgresInstance_maintenanceWindow(ctx, field, obj) - case "labels": - out.Values[i] = ec._PostgresInstance_labels(ctx, field, obj) - if out.Values[i] == graphql.Null { - atomic.AddUint32(&out.Invalids, 1) - } - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - out.Dispatch(ctx) - if out.Invalids > 0 { - return graphql.Null - } - - atomic.AddInt32(&ec.Deferred, int32(min(len(deferred), math.MaxInt32))) - - for label, dfs := range deferred { - ec.ProcessDeferredGroup(graphql.DeferredGroup{ - Label: label, - Path: graphql.GetPath(ctx), - FieldSet: dfs, - Context: ctx, - }) - } - - return out -} - -var postgresInstanceAuditImplementors = []string{"PostgresInstanceAudit"} + } + }() + res = ec._PostgresInstance_postgres(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } -func (ec *executionContext) _PostgresInstanceAudit(ctx context.Context, sel ast.SelectionSet, obj *postgres.PostgresInstanceAudit) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, postgresInstanceAuditImplementors) + if field.Deferrable != nil { + dfs, ok := deferred[field.Deferrable.Label] + di := 0 + if ok { + dfs.AddField(field) + di = len(dfs.Values) - 1 + } else { + dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) + deferred[field.Deferrable.Label] = dfs + } + dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { + return innerFunc(ctx, dfs) + }) - out := graphql.NewFieldSet(fields) - deferred := make(map[string]*graphql.FieldSet) - for i, field := range fields { - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString("PostgresInstanceAudit") - case "enabled": - out.Values[i] = ec._PostgresInstanceAudit_enabled(ctx, field, obj) - if out.Values[i] == graphql.Null { - atomic.AddUint32(&out.Invalids, 1) + // don't run the out.Concurrently() call below + out.Values[i] = graphql.Null + continue } - case "url": + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + case "workloads": field := field - innerFunc := func(ctx context.Context, _ *graphql.FieldSet) (res graphql.Marshaler) { + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) } }() - res = ec._PostgresInstanceAudit_url(ctx, field, obj) + res = ec._PostgresInstance_workloads(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } return res } @@ -3711,8 +3323,16 @@ func (ec *executionContext) _PostgresInstanceAudit(ctx context.Context, sel ast. } out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) - case "statementClasses": - out.Values[i] = ec._PostgresInstanceAudit_statementClasses(ctx, field, obj) + case "state": + out.Values[i] = ec._PostgresInstance_state(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } + case "labels": + out.Values[i] = ec._PostgresInstance_labels(ctx, field, obj) + if out.Values[i] == graphql.Null { + atomic.AddUint32(&out.Invalids, 1) + } default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -3944,78 +3564,6 @@ func (ec *executionContext) _PostgresInstanceFacets(ctx context.Context, sel ast continue } - out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) - case "highAvailability": - field := field - - innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - } - }() - res = ec._PostgresInstanceFacets_highAvailability(ctx, field, obj) - if res == graphql.Null { - atomic.AddUint32(&fs.Invalids, 1) - } - return res - } - - if field.Deferrable != nil { - dfs, ok := deferred[field.Deferrable.Label] - di := 0 - if ok { - dfs.AddField(field) - di = len(dfs.Values) - 1 - } else { - dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) - deferred[field.Deferrable.Label] = dfs - } - dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { - return innerFunc(ctx, dfs) - }) - - // don't run the out.Concurrently() call below - out.Values[i] = graphql.Null - continue - } - - out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) - case "majorVersions": - field := field - - innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - } - }() - res = ec._PostgresInstanceFacets_majorVersions(ctx, field, obj) - if res == graphql.Null { - atomic.AddUint32(&fs.Invalids, 1) - } - return res - } - - if field.Deferrable != nil { - dfs, ok := deferred[field.Deferrable.Label] - di := 0 - if ok { - dfs.AddField(field) - di = len(dfs.Values) - 1 - } else { - dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) - deferred[field.Deferrable.Label] = dfs - } - dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { - return innerFunc(ctx, dfs) - }) - - // don't run the out.Concurrently() call below - out.Values[i] = graphql.Null - continue - } - out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) case "labels": field := field @@ -4076,99 +3624,6 @@ func (ec *executionContext) _PostgresInstanceFacets(ctx context.Context, sel ast return out } -var postgresInstanceMaintenanceWindowImplementors = []string{"PostgresInstanceMaintenanceWindow"} - -func (ec *executionContext) _PostgresInstanceMaintenanceWindow(ctx context.Context, sel ast.SelectionSet, obj *postgres.PostgresInstanceMaintenanceWindow) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, postgresInstanceMaintenanceWindowImplementors) - - out := graphql.NewFieldSet(fields) - deferred := make(map[string]*graphql.FieldSet) - for i, field := range fields { - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString("PostgresInstanceMaintenanceWindow") - case "day": - out.Values[i] = ec._PostgresInstanceMaintenanceWindow_day(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "hour": - out.Values[i] = ec._PostgresInstanceMaintenanceWindow_hour(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - out.Dispatch(ctx) - if out.Invalids > 0 { - return graphql.Null - } - - atomic.AddInt32(&ec.Deferred, int32(min(len(deferred), math.MaxInt32))) - - for label, dfs := range deferred { - ec.ProcessDeferredGroup(graphql.DeferredGroup{ - Label: label, - Path: graphql.GetPath(ctx), - FieldSet: dfs, - Context: ctx, - }) - } - - return out -} - -var postgresInstanceResourcesImplementors = []string{"PostgresInstanceResources"} - -func (ec *executionContext) _PostgresInstanceResources(ctx context.Context, sel ast.SelectionSet, obj *postgres.PostgresInstanceResources) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, postgresInstanceResourcesImplementors) - - out := graphql.NewFieldSet(fields) - deferred := make(map[string]*graphql.FieldSet) - for i, field := range fields { - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString("PostgresInstanceResources") - case "cpu": - out.Values[i] = ec._PostgresInstanceResources_cpu(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "memory": - out.Values[i] = ec._PostgresInstanceResources_memory(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "diskSize": - out.Values[i] = ec._PostgresInstanceResources_diskSize(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - out.Dispatch(ctx) - if out.Invalids > 0 { - return graphql.Null - } - - atomic.AddInt32(&ec.Deferred, int32(min(len(deferred), math.MaxInt32))) - - for label, dfs := range deferred { - ec.ProcessDeferredGroup(graphql.DeferredGroup{ - Label: label, - Path: graphql.GetPath(ctx), - FieldSet: dfs, - Context: ctx, - }) - } - - return out -} - var postgresInstanceStateFacetItemImplementors = []string{"PostgresInstanceStateFacetItem"} func (ec *executionContext) _PostgresInstanceStateFacetItem(ctx context.Context, sel ast.SelectionSet, obj *postgres.PostgresInstanceStateFacetItem) graphql.Marshaler { @@ -4409,6 +3864,46 @@ func (ec *executionContext) _PostgresPersonalAccessCreatedActivityLogEntryData(c return out } +var postgresResourcesImplementors = []string{"PostgresResources"} + +func (ec *executionContext) _PostgresResources(ctx context.Context, sel ast.SelectionSet, obj *postgres.PostgresResources) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, postgresResourcesImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("PostgresResources") + case "cpu": + out.Values[i] = ec._PostgresResources_cpu(ctx, field, obj) + case "memory": + out.Values[i] = ec._PostgresResources_memory(ctx, field, obj) + case "diskSize": + out.Values[i] = ec._PostgresResources_diskSize(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.Deferred, int32(min(len(deferred), math.MaxInt32))) + + for label, dfs := range deferred { + ec.ProcessDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + var teamInventoryCountPostgresInstancesImplementors = []string{"TeamInventoryCountPostgresInstances"} func (ec *executionContext) _TeamInventoryCountPostgresInstances(ctx context.Context, sel ast.SelectionSet, obj *postgres.TeamInventoryCountPostgresInstances) graphql.Marshaler { @@ -4490,23 +3985,18 @@ func (ec *executionContext) marshalNDeletePostgresPayload2ᚖgithubᚗcomᚋnais return ec._DeletePostgresPayload(ctx, sel, v) } -func (ec *executionContext) unmarshalNGrantPostgresAccessInput2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐGrantPostgresAccessInput(ctx context.Context, v any) (postgres.GrantPostgresAccessInput, error) { - res, err := ec.unmarshalInputGrantPostgresAccessInput(ctx, v) - return res, graphql.ErrorOnPath(ctx, err) -} - -func (ec *executionContext) marshalNGrantPostgresAccessPayload2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐGrantPostgresAccessPayload(ctx context.Context, sel ast.SelectionSet, v postgres.GrantPostgresAccessPayload) graphql.Marshaler { - return ec._GrantPostgresAccessPayload(ctx, sel, &v) +func (ec *executionContext) marshalNPostgres2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgres(ctx context.Context, sel ast.SelectionSet, v postgres.Postgres) graphql.Marshaler { + return ec._Postgres(ctx, sel, &v) } -func (ec *executionContext) marshalNGrantPostgresAccessPayload2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐGrantPostgresAccessPayload(ctx context.Context, sel ast.SelectionSet, v *postgres.GrantPostgresAccessPayload) graphql.Marshaler { +func (ec *executionContext) marshalNPostgres2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgres(ctx context.Context, sel ast.SelectionSet, v *postgres.Postgres) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { graphql.AddErrorf(ctx, "the requested element is null which the schema does not allow") } return graphql.Null } - return ec._GrantPostgresAccessPayload(ctx, sel, v) + return ec._Postgres(ctx, sel, v) } func (ec *executionContext) marshalNPostgresAccess2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccess(ctx context.Context, sel ast.SelectionSet, v postgres.PostgresAccess) graphql.Marshaler { @@ -4542,10 +4032,6 @@ func (ec *executionContext) unmarshalNPostgresAccessConnectionInput2githubᚗcom return res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) marshalNPostgresAccessConnectionTunnel2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccessConnectionTunnel(ctx context.Context, sel ast.SelectionSet, v postgres.PostgresAccessConnectionTunnel) graphql.Marshaler { - return ec._PostgresAccessConnectionTunnel(ctx, sel, &v) -} - func (ec *executionContext) unmarshalNPostgresAccessLevel2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccessLevel(ctx context.Context, v any) (postgres.PostgresAccessLevel, error) { var res postgres.PostgresAccessLevel err := res.UnmarshalGQL(v) @@ -4606,10 +4092,6 @@ func (ec *executionContext) marshalNPostgresInstance2ᚖgithubᚗcomᚋnaisᚋap return ec._PostgresInstance(ctx, sel, v) } -func (ec *executionContext) marshalNPostgresInstanceAudit2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceAudit(ctx context.Context, sel ast.SelectionSet, v postgres.PostgresInstanceAudit) graphql.Marshaler { - return ec._PostgresInstanceAudit(ctx, sel, &v) -} - func (ec *executionContext) marshalNPostgresInstanceConnection2githubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋpaginationᚐFacetableConnection(ctx context.Context, sel ast.SelectionSet, v pagination.FacetableConnection[*postgres.PostgresInstance, *postgres.PostgresInstanceFilter]) graphql.Marshaler { return ec._PostgresInstanceConnection(ctx, sel, &v) } @@ -4654,16 +4136,6 @@ func (ec *executionContext) marshalNPostgresInstanceOrderField2githubᚗcomᚋna return v } -func (ec *executionContext) marshalNPostgresInstanceResources2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceResources(ctx context.Context, sel ast.SelectionSet, v *postgres.PostgresInstanceResources) graphql.Marshaler { - if v == nil { - if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { - graphql.AddErrorf(ctx, "the requested element is null which the schema does not allow") - } - return graphql.Null - } - return ec._PostgresInstanceResources(ctx, sel, v) -} - func (ec *executionContext) unmarshalNPostgresInstanceState2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceState(ctx context.Context, v any) (postgres.PostgresInstanceState, error) { var res postgres.PostgresInstanceState err := res.UnmarshalGQL(v) @@ -4704,6 +4176,10 @@ func (ec *executionContext) marshalNPostgresPersonalAccessCreatedActivityLogEntr return ec._PostgresPersonalAccessCreatedActivityLogEntryData(ctx, sel, v) } +func (ec *executionContext) marshalNPostgresResources2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresResources(ctx context.Context, sel ast.SelectionSet, v postgres.PostgresResources) graphql.Marshaler { + return ec._PostgresResources(ctx, sel, &v) +} + func (ec *executionContext) marshalNTeamInventoryCountPostgresInstances2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐTeamInventoryCountPostgresInstances(ctx context.Context, sel ast.SelectionSet, v postgres.TeamInventoryCountPostgresInstances) graphql.Marshaler { return ec._TeamInventoryCountPostgresInstances(ctx, sel, &v) } @@ -4718,13 +4194,6 @@ func (ec *executionContext) marshalNTeamInventoryCountPostgresInstances2ᚖgithu return ec._TeamInventoryCountPostgresInstances(ctx, sel, v) } -func (ec *executionContext) marshalOPostgresAccessTunnel2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccessTunnel(ctx context.Context, sel ast.SelectionSet, v *postgres.PostgresAccessTunnel) graphql.Marshaler { - if v == nil { - return graphql.Null - } - return ec._PostgresAccessTunnel(ctx, sel, v) -} - func (ec *executionContext) marshalOPostgresInstanceFacets2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceFacets(ctx context.Context, sel ast.SelectionSet, v *postgres.PostgresInstanceFacets) graphql.Marshaler { if v == nil { return graphql.Null @@ -4740,13 +4209,6 @@ func (ec *executionContext) unmarshalOPostgresInstanceFilter2ᚖgithubᚗcomᚋn return &res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) marshalOPostgresInstanceMaintenanceWindow2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceMaintenanceWindow(ctx context.Context, sel ast.SelectionSet, v *postgres.PostgresInstanceMaintenanceWindow) graphql.Marshaler { - if v == nil { - return graphql.Null - } - return ec._PostgresInstanceMaintenanceWindow(ctx, sel, v) -} - func (ec *executionContext) unmarshalOPostgresInstanceOrder2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceOrder(ctx context.Context, v any) (*postgres.PostgresInstanceOrder, error) { if v == nil { return nil, nil diff --git a/internal/graph/gengql/root_.generated.go b/internal/graph/gengql/root_.generated.go index 32ada8427..f101f8594 100644 --- a/internal/graph/gengql/root_.generated.go +++ b/internal/graph/gengql/root_.generated.go @@ -107,7 +107,6 @@ type ResolverRoot interface { OpenSearchMaintenance() OpenSearchMaintenanceResolver PostgresAccess() PostgresAccessResolver PostgresInstance() PostgresInstanceResolver - PostgresInstanceAudit() PostgresInstanceAuditResolver PostgresInstanceConnection() PostgresInstanceConnectionResolver PrometheusAlert() PrometheusAlertResolver Query() QueryResolver @@ -1039,10 +1038,6 @@ type ComplexityRoot struct { Workflow func(childComplexity int) int } - GrantPostgresAccessPayload struct { - Error func(childComplexity int) int - } - IDPortenAuthIntegration struct { Name func(childComplexity int) int } @@ -1618,7 +1613,6 @@ type ComplexityRoot struct { DeleteValkey func(childComplexity int, input valkey.DeleteValkeyInput) int DisableReconciler func(childComplexity int, input reconciler.DisableReconcilerInput) int EnableReconciler func(childComplexity int, input reconciler.EnableReconcilerInput) int - GrantPostgresAccess func(childComplexity int, input postgres.GrantPostgresAccessInput) int RemoveConfigValue func(childComplexity int, input config.RemoveConfigValueInput) int RemoveRepositoryFromTeam func(childComplexity int, input repository.RemoveRepositoryFromTeamInput) int RemoveSecretValue func(childComplexity int, input secret.RemoveSecretValueInput) int @@ -1859,6 +1853,16 @@ type ComplexityRoot struct { TotalCount func(childComplexity int) int } + Postgres struct { + ActiveInstance func(childComplexity int) int + HighAvailability func(childComplexity int) int + ID func(childComplexity int) int + Labels func(childComplexity int) int + MajorVersion func(childComplexity int) int + Name func(childComplexity int) int + Resources func(childComplexity int) int + } + PostgresAccess struct { AccessLevel func(childComplexity int) int ExpiresAt func(childComplexity int) int @@ -1866,28 +1870,20 @@ type ComplexityRoot struct { Message func(childComplexity int) int Name func(childComplexity int) int PostgresInstance func(childComplexity int) int + RelayAccess func(childComplexity int) int State func(childComplexity int) int Team func(childComplexity int) int TeamEnvironment func(childComplexity int) int - Tunnel func(childComplexity int) int } PostgresAccessConnection struct { CACertificate func(childComplexity int) int Password func(childComplexity int) int + RelayAccess func(childComplexity int) int + RelayEndpoint func(childComplexity int) int + RelayToken func(childComplexity int) int ServerName func(childComplexity int) int - Tunnel func(childComplexity int) int - } - - PostgresAccessConnectionTunnel struct { - Endpoint func(childComplexity int) int - GatewayPublicKey func(childComplexity int) int - } - - PostgresAccessTunnel struct { - Endpoint func(childComplexity int) int - GatewayPublicKey func(childComplexity int) int - Name func(childComplexity int) int + Username func(childComplexity int) int } PostgresDeletedActivityLogEntry struct { @@ -1919,24 +1915,14 @@ type ComplexityRoot struct { } PostgresInstance struct { - Audit func(childComplexity int) int - HighAvailability func(childComplexity int) int - ID func(childComplexity int) int - Labels func(childComplexity int) int - MaintenanceWindow func(childComplexity int) int - MajorVersion func(childComplexity int) int - Name func(childComplexity int) int - Resources func(childComplexity int) int - State func(childComplexity int) int - Team func(childComplexity int) int - TeamEnvironment func(childComplexity int) int - Workloads func(childComplexity int, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor) int - } - - PostgresInstanceAudit struct { - Enabled func(childComplexity int) int - StatementClasses func(childComplexity int) int - URL func(childComplexity int) int + ID func(childComplexity int) int + Labels func(childComplexity int) int + Name func(childComplexity int) int + Postgres func(childComplexity int) int + State func(childComplexity int) int + Team func(childComplexity int) int + TeamEnvironment func(childComplexity int) int + Workloads func(childComplexity int, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor) int } PostgresInstanceConnection struct { @@ -1952,22 +1938,9 @@ type ComplexityRoot struct { } PostgresInstanceFacets struct { - Environments func(childComplexity int) int - HighAvailability func(childComplexity int) int - Labels func(childComplexity int) int - MajorVersions func(childComplexity int) int - States func(childComplexity int) int - } - - PostgresInstanceMaintenanceWindow struct { - Day func(childComplexity int) int - Hour func(childComplexity int) int - } - - PostgresInstanceResources struct { - CPU func(childComplexity int) int - DiskSize func(childComplexity int) int - Memory func(childComplexity int) int + Environments func(childComplexity int) int + Labels func(childComplexity int) int + States func(childComplexity int) int } PostgresInstanceStateFacetItem struct { @@ -2004,6 +1977,12 @@ type ComplexityRoot struct { Username func(childComplexity int) int } + PostgresResources struct { + CPU func(childComplexity int) int + DiskSize func(childComplexity int) int + Memory func(childComplexity int) int + } + Price struct { Value func(childComplexity int) int } @@ -3007,6 +2986,7 @@ type ComplexityRoot struct { KafkaTopic func(childComplexity int, name string) int Name func(childComplexity int) int OpenSearch func(childComplexity int, name string) int + Postgres func(childComplexity int, name string) int PostgresInstance func(childComplexity int, name string) int SQLInstance func(childComplexity int, name string) int Secret func(childComplexity int, name string) int @@ -7360,13 +7340,6 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.GitHubActorClaims.Workflow(childComplexity), true - case "GrantPostgresAccessPayload.error": - if e.ComplexityRoot.GrantPostgresAccessPayload.Error == nil { - break - } - - return e.ComplexityRoot.GrantPostgresAccessPayload.Error(childComplexity), true - case "IDPortenAuthIntegration.name": if e.ComplexityRoot.IDPortenAuthIntegration.Name == nil { break @@ -10075,18 +10048,6 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.Mutation.EnableReconciler(childComplexity, args["input"].(reconciler.EnableReconcilerInput)), true - case "Mutation.grantPostgresAccess": - if e.ComplexityRoot.Mutation.GrantPostgresAccess == nil { - break - } - - args, err := ec.field_Mutation_grantPostgresAccess_args(ctx, rawArgs) - if err != nil { - return 0, false - } - - return e.ComplexityRoot.Mutation.GrantPostgresAccess(childComplexity, args["input"].(postgres.GrantPostgresAccessInput)), true - case "Mutation.removeConfigValue": if e.ComplexityRoot.Mutation.RemoveConfigValue == nil { break @@ -11330,6 +11291,55 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.PageInfo.TotalCount(childComplexity), true + case "Postgres.activeInstance": + if e.ComplexityRoot.Postgres.ActiveInstance == nil { + break + } + + return e.ComplexityRoot.Postgres.ActiveInstance(childComplexity), true + + case "Postgres.highAvailability": + if e.ComplexityRoot.Postgres.HighAvailability == nil { + break + } + + return e.ComplexityRoot.Postgres.HighAvailability(childComplexity), true + + case "Postgres.id": + if e.ComplexityRoot.Postgres.ID == nil { + break + } + + return e.ComplexityRoot.Postgres.ID(childComplexity), true + + case "Postgres.labels": + if e.ComplexityRoot.Postgres.Labels == nil { + break + } + + return e.ComplexityRoot.Postgres.Labels(childComplexity), true + + case "Postgres.majorVersion": + if e.ComplexityRoot.Postgres.MajorVersion == nil { + break + } + + return e.ComplexityRoot.Postgres.MajorVersion(childComplexity), true + + case "Postgres.name": + if e.ComplexityRoot.Postgres.Name == nil { + break + } + + return e.ComplexityRoot.Postgres.Name(childComplexity), true + + case "Postgres.resources": + if e.ComplexityRoot.Postgres.Resources == nil { + break + } + + return e.ComplexityRoot.Postgres.Resources(childComplexity), true + case "PostgresAccess.accessLevel": if e.ComplexityRoot.PostgresAccess.AccessLevel == nil { break @@ -11372,6 +11382,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.PostgresAccess.PostgresInstance(childComplexity), true + case "PostgresAccess.relayAccess": + if e.ComplexityRoot.PostgresAccess.RelayAccess == nil { + break + } + + return e.ComplexityRoot.PostgresAccess.RelayAccess(childComplexity), true + case "PostgresAccess.state": if e.ComplexityRoot.PostgresAccess.State == nil { break @@ -11393,13 +11410,6 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.PostgresAccess.TeamEnvironment(childComplexity), true - case "PostgresAccess.tunnel": - if e.ComplexityRoot.PostgresAccess.Tunnel == nil { - break - } - - return e.ComplexityRoot.PostgresAccess.Tunnel(childComplexity), true - case "PostgresAccessConnection.caCertificate": if e.ComplexityRoot.PostgresAccessConnection.CACertificate == nil { break @@ -11414,54 +11424,40 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.PostgresAccessConnection.Password(childComplexity), true - case "PostgresAccessConnection.serverName": - if e.ComplexityRoot.PostgresAccessConnection.ServerName == nil { - break - } - - return e.ComplexityRoot.PostgresAccessConnection.ServerName(childComplexity), true - - case "PostgresAccessConnection.tunnel": - if e.ComplexityRoot.PostgresAccessConnection.Tunnel == nil { - break - } - - return e.ComplexityRoot.PostgresAccessConnection.Tunnel(childComplexity), true - - case "PostgresAccessConnectionTunnel.endpoint": - if e.ComplexityRoot.PostgresAccessConnectionTunnel.Endpoint == nil { + case "PostgresAccessConnection.relayAccess": + if e.ComplexityRoot.PostgresAccessConnection.RelayAccess == nil { break } - return e.ComplexityRoot.PostgresAccessConnectionTunnel.Endpoint(childComplexity), true + return e.ComplexityRoot.PostgresAccessConnection.RelayAccess(childComplexity), true - case "PostgresAccessConnectionTunnel.gatewayPublicKey": - if e.ComplexityRoot.PostgresAccessConnectionTunnel.GatewayPublicKey == nil { + case "PostgresAccessConnection.relayEndpoint": + if e.ComplexityRoot.PostgresAccessConnection.RelayEndpoint == nil { break } - return e.ComplexityRoot.PostgresAccessConnectionTunnel.GatewayPublicKey(childComplexity), true + return e.ComplexityRoot.PostgresAccessConnection.RelayEndpoint(childComplexity), true - case "PostgresAccessTunnel.endpoint": - if e.ComplexityRoot.PostgresAccessTunnel.Endpoint == nil { + case "PostgresAccessConnection.relayToken": + if e.ComplexityRoot.PostgresAccessConnection.RelayToken == nil { break } - return e.ComplexityRoot.PostgresAccessTunnel.Endpoint(childComplexity), true + return e.ComplexityRoot.PostgresAccessConnection.RelayToken(childComplexity), true - case "PostgresAccessTunnel.gatewayPublicKey": - if e.ComplexityRoot.PostgresAccessTunnel.GatewayPublicKey == nil { + case "PostgresAccessConnection.serverName": + if e.ComplexityRoot.PostgresAccessConnection.ServerName == nil { break } - return e.ComplexityRoot.PostgresAccessTunnel.GatewayPublicKey(childComplexity), true + return e.ComplexityRoot.PostgresAccessConnection.ServerName(childComplexity), true - case "PostgresAccessTunnel.name": - if e.ComplexityRoot.PostgresAccessTunnel.Name == nil { + case "PostgresAccessConnection.username": + if e.ComplexityRoot.PostgresAccessConnection.Username == nil { break } - return e.ComplexityRoot.PostgresAccessTunnel.Name(childComplexity), true + return e.ComplexityRoot.PostgresAccessConnection.Username(childComplexity), true case "PostgresDeletedActivityLogEntry.actor": if e.ComplexityRoot.PostgresDeletedActivityLogEntry.Actor == nil { @@ -11596,20 +11592,6 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.PostgresGrantAccessActivityLogEntryData.Until(childComplexity), true - case "PostgresInstance.audit": - if e.ComplexityRoot.PostgresInstance.Audit == nil { - break - } - - return e.ComplexityRoot.PostgresInstance.Audit(childComplexity), true - - case "PostgresInstance.highAvailability": - if e.ComplexityRoot.PostgresInstance.HighAvailability == nil { - break - } - - return e.ComplexityRoot.PostgresInstance.HighAvailability(childComplexity), true - case "PostgresInstance.id": if e.ComplexityRoot.PostgresInstance.ID == nil { break @@ -11624,20 +11606,6 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.PostgresInstance.Labels(childComplexity), true - case "PostgresInstance.maintenanceWindow": - if e.ComplexityRoot.PostgresInstance.MaintenanceWindow == nil { - break - } - - return e.ComplexityRoot.PostgresInstance.MaintenanceWindow(childComplexity), true - - case "PostgresInstance.majorVersion": - if e.ComplexityRoot.PostgresInstance.MajorVersion == nil { - break - } - - return e.ComplexityRoot.PostgresInstance.MajorVersion(childComplexity), true - case "PostgresInstance.name": if e.ComplexityRoot.PostgresInstance.Name == nil { break @@ -11645,12 +11613,12 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.PostgresInstance.Name(childComplexity), true - case "PostgresInstance.resources": - if e.ComplexityRoot.PostgresInstance.Resources == nil { + case "PostgresInstance.postgres": + if e.ComplexityRoot.PostgresInstance.Postgres == nil { break } - return e.ComplexityRoot.PostgresInstance.Resources(childComplexity), true + return e.ComplexityRoot.PostgresInstance.Postgres(childComplexity), true case "PostgresInstance.state": if e.ComplexityRoot.PostgresInstance.State == nil { @@ -11685,27 +11653,6 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.PostgresInstance.Workloads(childComplexity, args["first"].(*int), args["after"].(*pagination.Cursor), args["last"].(*int), args["before"].(*pagination.Cursor)), true - case "PostgresInstanceAudit.enabled": - if e.ComplexityRoot.PostgresInstanceAudit.Enabled == nil { - break - } - - return e.ComplexityRoot.PostgresInstanceAudit.Enabled(childComplexity), true - - case "PostgresInstanceAudit.statementClasses": - if e.ComplexityRoot.PostgresInstanceAudit.StatementClasses == nil { - break - } - - return e.ComplexityRoot.PostgresInstanceAudit.StatementClasses(childComplexity), true - - case "PostgresInstanceAudit.url": - if e.ComplexityRoot.PostgresInstanceAudit.URL == nil { - break - } - - return e.ComplexityRoot.PostgresInstanceAudit.URL(childComplexity), true - case "PostgresInstanceConnection.edges": if e.ComplexityRoot.PostgresInstanceConnection.Edges == nil { break @@ -11755,13 +11702,6 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.PostgresInstanceFacets.Environments(childComplexity), true - case "PostgresInstanceFacets.highAvailability": - if e.ComplexityRoot.PostgresInstanceFacets.HighAvailability == nil { - break - } - - return e.ComplexityRoot.PostgresInstanceFacets.HighAvailability(childComplexity), true - case "PostgresInstanceFacets.labels": if e.ComplexityRoot.PostgresInstanceFacets.Labels == nil { break @@ -11769,13 +11709,6 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.PostgresInstanceFacets.Labels(childComplexity), true - case "PostgresInstanceFacets.majorVersions": - if e.ComplexityRoot.PostgresInstanceFacets.MajorVersions == nil { - break - } - - return e.ComplexityRoot.PostgresInstanceFacets.MajorVersions(childComplexity), true - case "PostgresInstanceFacets.states": if e.ComplexityRoot.PostgresInstanceFacets.States == nil { break @@ -11783,41 +11716,6 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.PostgresInstanceFacets.States(childComplexity), true - case "PostgresInstanceMaintenanceWindow.day": - if e.ComplexityRoot.PostgresInstanceMaintenanceWindow.Day == nil { - break - } - - return e.ComplexityRoot.PostgresInstanceMaintenanceWindow.Day(childComplexity), true - - case "PostgresInstanceMaintenanceWindow.hour": - if e.ComplexityRoot.PostgresInstanceMaintenanceWindow.Hour == nil { - break - } - - return e.ComplexityRoot.PostgresInstanceMaintenanceWindow.Hour(childComplexity), true - - case "PostgresInstanceResources.cpu": - if e.ComplexityRoot.PostgresInstanceResources.CPU == nil { - break - } - - return e.ComplexityRoot.PostgresInstanceResources.CPU(childComplexity), true - - case "PostgresInstanceResources.diskSize": - if e.ComplexityRoot.PostgresInstanceResources.DiskSize == nil { - break - } - - return e.ComplexityRoot.PostgresInstanceResources.DiskSize(childComplexity), true - - case "PostgresInstanceResources.memory": - if e.ComplexityRoot.PostgresInstanceResources.Memory == nil { - break - } - - return e.ComplexityRoot.PostgresInstanceResources.Memory(childComplexity), true - case "PostgresInstanceStateFacetItem.count": if e.ComplexityRoot.PostgresInstanceStateFacetItem.Count == nil { break @@ -11972,6 +11870,27 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.PostgresPersonalAccessCreatedActivityLogEntryData.Username(childComplexity), true + case "PostgresResources.cpu": + if e.ComplexityRoot.PostgresResources.CPU == nil { + break + } + + return e.ComplexityRoot.PostgresResources.CPU(childComplexity), true + + case "PostgresResources.diskSize": + if e.ComplexityRoot.PostgresResources.DiskSize == nil { + break + } + + return e.ComplexityRoot.PostgresResources.DiskSize(childComplexity), true + + case "PostgresResources.memory": + if e.ComplexityRoot.PostgresResources.Memory == nil { + break + } + + return e.ComplexityRoot.PostgresResources.Memory(childComplexity), true + case "Price.value": if e.ComplexityRoot.Price.Value == nil { break @@ -16689,6 +16608,18 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.TeamEnvironment.OpenSearch(childComplexity, args["name"].(string)), true + case "TeamEnvironment.postgres": + if e.ComplexityRoot.TeamEnvironment.Postgres == nil { + break + } + + args, err := ec.field_TeamEnvironment_postgres_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.ComplexityRoot.TeamEnvironment.Postgres(childComplexity, args["name"].(string)), true + case "TeamEnvironment.postgresInstance": if e.ComplexityRoot.TeamEnvironment.PostgresInstance == nil { break @@ -20309,7 +20240,6 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { ec.unmarshalInputEnableReconcilerInput, ec.unmarshalInputEnvironmentOrder, ec.unmarshalInputEnvironmentWorkloadOrder, - ec.unmarshalInputGrantPostgresAccessInput, ec.unmarshalInputImageVulnerabilityFilter, ec.unmarshalInputImageVulnerabilityOrder, ec.unmarshalInputIssueFilter, @@ -26720,12 +26650,14 @@ type WorkloadLogLine { } extend type TeamEnvironment { - "Postgres instance in the team environment." + "Postgres in the team environment." + postgres(name: String!): Postgres! + "Named PostgresInstance in the team environment." postgresInstance(name: String!): PostgresInstance! } extend interface Workload { - "Postgres instances referenced by the workload. This does not currently support pagination, but will return all available Postgres instances." + "Active PostgresInstances for all Postgres entries in uses.postgres." postgresInstances( "Ordering options for items returned from the connection." orderBy: PostgresInstanceOrder @@ -26733,7 +26665,7 @@ extend interface Workload { } extend type Application { - "Postgres instances referenced by the application. This does not currently support pagination, but will return all available Postgres instances." + "Active PostgresInstances for all Postgres entries in uses.postgres." postgresInstances( "Ordering options for items returned from the connection." orderBy: PostgresInstanceOrder @@ -26741,7 +26673,7 @@ extend type Application { } extend type Job { - "Postgres instances referenced by the job. This does not currently support pagination, but will return all available Postgres instances." + "Active PostgresInstances for all Postgres entries in uses.postgres." postgresInstances( "Ordering options for items returned from the connection." orderBy: PostgresInstanceOrder @@ -26766,12 +26698,6 @@ input PostgresInstanceFilter { "Filter by instance state." states: [PostgresInstanceState!] - "Filter by high availability." - highAvailability: Boolean - - "Filter by major versions." - majorVersions: [String!] - "Filter by user-defined labels. All listed labels must match." labels: [LabelFilter!] } @@ -26781,61 +26707,45 @@ enum PostgresInstanceOrderField { ENVIRONMENT } +"A named PostgresInstance belonging to a Postgres." type PostgresInstance implements Persistence & Node { id: ID! name: String! team: Team! teamEnvironment: TeamEnvironment! - "Workloads that reference the Postgres instance." - workloads( - "Get the first n items in the connection. This can be used in combination with the after parameter." - first: Int - - "Get items after this cursor." - after: Cursor - - "Get the last n items in the connection. This can be used in combination with the before parameter." - last: Int + "Postgres owning this PostgresInstance." + postgres: Postgres! + "Workloads using this instance while it is active." + workloads(first: Int, after: Cursor, last: Int, before: Cursor): WorkloadConnection! + state: PostgresInstanceState! + labels: [ResourceLabel!]! +} - "Get items before this cursor." - before: Cursor - ): WorkloadConnection! - "Resource allocation for the Postgres cluster." - resources: PostgresInstanceResources! - "Major version of PostgreSQL." +"A Postgres whose active instance can change." +type Postgres implements Node { + id: ID! + name: String! majorVersion: String! - "Audit logging configuration for the Postgres cluster." - audit: PostgresInstanceAudit! - "Indicates whether the Postgres cluster is configured for high availability." highAvailability: Boolean! - "Current state of the Postgres cluster." - state: PostgresInstanceState! - "Maintenance window for the Postgres cluster, if configured." - maintenanceWindow: PostgresInstanceMaintenanceWindow - "User-defined labels attached to this instance." + "Requested CPU, memory and disk size, when present on this Postgres." + resources: PostgresResources! + activeInstance: String labels: [ResourceLabel!]! } +"Resource requests configured on Postgres. Omitted requests are null." +type PostgresResources { + cpu: String + memory: String + diskSize: String +} + enum PostgresInstanceState { AVAILABLE PROGRESSING DEGRADED } -type PostgresInstanceMaintenanceWindow { - day: Int! - hour: Int! -} - -type PostgresInstanceAudit { - "Indicates whether audit logging is enabled for the Postgres cluster." - enabled: Boolean! - "URL for accessing the audit logs." - url: String - "List of statement classes that are being logged, such as ` + "`" + `ddl` + "`" + `, ` + "`" + `dml` + "`" + `, and ` + "`" + `read` + "`" + `." - statementClasses: [String!] -} - type PostgresInstanceConnection { pageInfo: PageInfo! nodes: [PostgresInstance!]! @@ -26863,12 +26773,6 @@ type PostgresInstanceFacets { "Distribution of instances by state." states: [PostgresInstanceStateFacetItem!]! - "Distribution of instances by high availability." - highAvailability: [BooleanFacetItem!]! - - "Distribution of instances by major version." - majorVersions: [StringFacetItem!]! - "Distribution of instances by user-defined labels." labels: [LabelFacetItem!]! } @@ -26884,12 +26788,6 @@ type PostgresInstanceStateFacetItem { count: Int! } -type PostgresInstanceResources { - cpu: String! - memory: String! - diskSize: String! -} - extend union SearchNode = PostgresInstance extend enum SearchType { @@ -27036,16 +26934,11 @@ extend enum ActivityLogActivityType { extend type Mutation { """ - Create time-limited personal access to a NAIS Postgres instance through the brokered PostgresAccess and WireGuard tunnel flow. + Create time-limited personal access to a NAIS Postgres instance through the brokered PostgresAccess and relay flow. Use this for new NAIS Postgres personal access. When the access is ready, retrieve its connection materials with postgresAccessConnection. """ createPostgresAccess(input: CreatePostgresAccessInput!): CreatePostgresAccessPayload! - """ - Grant time-limited Kubernetes RBAC access to database pods for kubectl port-forward. - Use this existing flow for Cloud SQL access; it does not create a PostgresAccess, WireGuard tunnel, or database credentials. - """ - grantPostgresAccess(input: GrantPostgresAccessInput!): GrantPostgresAccessPayload! - "Delete an existing Postgres instance." + "Delete a PostgresInstance that is not active on its Postgres." deletePostgres(input: DeletePostgresInput!): DeletePostgresPayload! } @@ -27059,7 +26952,7 @@ type CreatePostgresAccessPayload { "Input for creating a time-limited personal Postgres access." input CreatePostgresAccessInput { - "Name of the available Postgres instance to access." + "Name of the PostgresInstance to access." postgresInstance: String! "Team that owns the Postgres instance." teamSlug: Slug! @@ -27067,11 +26960,9 @@ input CreatePostgresAccessInput { environmentName: String! "Privileges requested for the personal database role." accessLevel: PostgresAccessLevel! - "WireGuard public key generated by the client for this access." - clientWireGuardPublicKey: String! "Reason for personal database access. Must be at least 10 characters." reason: String! - "Requested access lifetime (for example '1h' or '4h'). Defaults to '1h' and cannot exceed '8h'." + "Requested access lifetime (for example '30m' or '1h'). Defaults to '1h' and cannot exceed '1h'." ttl: String } @@ -27085,19 +26976,6 @@ enum PostgresAccessLevel { READWRITECREATE } -type GrantPostgresAccessPayload { - error: String -} - -input GrantPostgresAccessInput { - clusterName: String! - teamSlug: Slug! - environmentName: String! - grantee: String! - "Duration of the access grant (maximum 4 hours)." - duration: String! -} - input DeletePostgresInput { "Name of the Postgres instance." name: String! @@ -27148,7 +27026,7 @@ type PostgresAccess implements Node { team: Team! "Environment for the access." teamEnvironment: TeamEnvironment! - "Postgres instance this access is for." + "PostgresInstance selected by this access." postgresInstance: PostgresInstance! "Requested access level." accessLevel: PostgresAccessLevel! @@ -27158,8 +27036,8 @@ type PostgresAccess implements Node { state: PostgresAccessState! "Human-readable message for the current state." message: String - "Tunnel connection details, once the controller has created them." - tunnel: PostgresAccessTunnel + "Name of the controller-owned relay mapping, once created. Contains no credential." + relayAccess: String } "High-level reconciliation state of a personal Postgres access." @@ -27174,16 +27052,6 @@ enum PostgresAccessState { EXPIRED } -"Tunnel details reported while provisioning a personal Postgres access." -type PostgresAccessTunnel { - "Name of the Tunnel resource owned by this access." - name: String! - "Gateway endpoint the client should connect to." - endpoint: String - "Gateway's WireGuard public key." - gatewayPublicKey: String -} - "Input for retrieving connection materials for a ready personal access." input PostgresAccessConnectionInput { "Name of the PostgresAccess resource." @@ -27196,22 +27064,20 @@ input PostgresAccessConnectionInput { "Sensitive connection materials for a ready personal Postgres access." type PostgresAccessConnection { + "Database username for the caller's personal role." + username: String! "Short-lived password for the caller's database role." password: String! "CA certificate required to verify the PostgreSQL server certificate." caCertificate: String! "PostgreSQL server name used for TLS verification." serverName: String! - "WireGuard tunnel endpoint and server public key." - tunnel: PostgresAccessConnectionTunnel! -} - -"WireGuard connection parameters for a personal Postgres access." -type PostgresAccessConnectionTunnel { - "Public UDP endpoint of the Tunnel forwarder." - endpoint: String! - "WireGuard public key of the Tunnel gateway." - gatewayPublicKey: String! + "Public HTTP/3 relay endpoint." + relayEndpoint: String! + "Relay-Access header value (namespace/name)." + relayAccess: String! + "Owner-only bearer token for this access; never log it." + relayToken: String! } `, BuiltIn: false}, {Name: "../schema/price.graphqls", Input: `extend type Query { @@ -35774,14 +35640,6 @@ func (ec *executionContext) childFields_GitHubActorClaims(ctx context.Context, f return nil, fmt.Errorf("no field named %q was found under type GitHubActorClaims", field.Name) } -func (ec *executionContext) childFields_GrantPostgresAccessPayload(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "error": - return ec.fieldContext_GrantPostgresAccessPayload_error(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type GrantPostgresAccessPayload", field.Name) -} - func (ec *executionContext) childFields_ImageVulnerability(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { switch field.Name { case "id": @@ -36880,6 +36738,26 @@ func (ec *executionContext) childFields_PageInfo(ctx context.Context, field grap return nil, fmt.Errorf("no field named %q was found under type PageInfo", field.Name) } +func (ec *executionContext) childFields_Postgres(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "id": + return ec.fieldContext_Postgres_id(ctx, field) + case "name": + return ec.fieldContext_Postgres_name(ctx, field) + case "majorVersion": + return ec.fieldContext_Postgres_majorVersion(ctx, field) + case "highAvailability": + return ec.fieldContext_Postgres_highAvailability(ctx, field) + case "resources": + return ec.fieldContext_Postgres_resources(ctx, field) + case "activeInstance": + return ec.fieldContext_Postgres_activeInstance(ctx, field) + case "labels": + return ec.fieldContext_Postgres_labels(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type Postgres", field.Name) +} + func (ec *executionContext) childFields_PostgresAccess(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { switch field.Name { case "id": @@ -36900,48 +36778,32 @@ func (ec *executionContext) childFields_PostgresAccess(ctx context.Context, fiel return ec.fieldContext_PostgresAccess_state(ctx, field) case "message": return ec.fieldContext_PostgresAccess_message(ctx, field) - case "tunnel": - return ec.fieldContext_PostgresAccess_tunnel(ctx, field) + case "relayAccess": + return ec.fieldContext_PostgresAccess_relayAccess(ctx, field) } return nil, fmt.Errorf("no field named %q was found under type PostgresAccess", field.Name) } func (ec *executionContext) childFields_PostgresAccessConnection(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { switch field.Name { + case "username": + return ec.fieldContext_PostgresAccessConnection_username(ctx, field) case "password": return ec.fieldContext_PostgresAccessConnection_password(ctx, field) case "caCertificate": return ec.fieldContext_PostgresAccessConnection_caCertificate(ctx, field) case "serverName": return ec.fieldContext_PostgresAccessConnection_serverName(ctx, field) - case "tunnel": - return ec.fieldContext_PostgresAccessConnection_tunnel(ctx, field) + case "relayEndpoint": + return ec.fieldContext_PostgresAccessConnection_relayEndpoint(ctx, field) + case "relayAccess": + return ec.fieldContext_PostgresAccessConnection_relayAccess(ctx, field) + case "relayToken": + return ec.fieldContext_PostgresAccessConnection_relayToken(ctx, field) } return nil, fmt.Errorf("no field named %q was found under type PostgresAccessConnection", field.Name) } -func (ec *executionContext) childFields_PostgresAccessConnectionTunnel(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "endpoint": - return ec.fieldContext_PostgresAccessConnectionTunnel_endpoint(ctx, field) - case "gatewayPublicKey": - return ec.fieldContext_PostgresAccessConnectionTunnel_gatewayPublicKey(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type PostgresAccessConnectionTunnel", field.Name) -} - -func (ec *executionContext) childFields_PostgresAccessTunnel(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "name": - return ec.fieldContext_PostgresAccessTunnel_name(ctx, field) - case "endpoint": - return ec.fieldContext_PostgresAccessTunnel_endpoint(ctx, field) - case "gatewayPublicKey": - return ec.fieldContext_PostgresAccessTunnel_gatewayPublicKey(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type PostgresAccessTunnel", field.Name) -} - func (ec *executionContext) childFields_PostgresGrantAccessActivityLogEntryData(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { switch field.Name { case "grantee": @@ -36962,38 +36824,18 @@ func (ec *executionContext) childFields_PostgresInstance(ctx context.Context, fi return ec.fieldContext_PostgresInstance_team(ctx, field) case "teamEnvironment": return ec.fieldContext_PostgresInstance_teamEnvironment(ctx, field) + case "postgres": + return ec.fieldContext_PostgresInstance_postgres(ctx, field) case "workloads": return ec.fieldContext_PostgresInstance_workloads(ctx, field) - case "resources": - return ec.fieldContext_PostgresInstance_resources(ctx, field) - case "majorVersion": - return ec.fieldContext_PostgresInstance_majorVersion(ctx, field) - case "audit": - return ec.fieldContext_PostgresInstance_audit(ctx, field) - case "highAvailability": - return ec.fieldContext_PostgresInstance_highAvailability(ctx, field) case "state": return ec.fieldContext_PostgresInstance_state(ctx, field) - case "maintenanceWindow": - return ec.fieldContext_PostgresInstance_maintenanceWindow(ctx, field) case "labels": return ec.fieldContext_PostgresInstance_labels(ctx, field) } return nil, fmt.Errorf("no field named %q was found under type PostgresInstance", field.Name) } -func (ec *executionContext) childFields_PostgresInstanceAudit(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "enabled": - return ec.fieldContext_PostgresInstanceAudit_enabled(ctx, field) - case "url": - return ec.fieldContext_PostgresInstanceAudit_url(ctx, field) - case "statementClasses": - return ec.fieldContext_PostgresInstanceAudit_statementClasses(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type PostgresInstanceAudit", field.Name) -} - func (ec *executionContext) childFields_PostgresInstanceConnection(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { switch field.Name { case "pageInfo": @@ -37024,38 +36866,12 @@ func (ec *executionContext) childFields_PostgresInstanceFacets(ctx context.Conte return ec.fieldContext_PostgresInstanceFacets_environments(ctx, field) case "states": return ec.fieldContext_PostgresInstanceFacets_states(ctx, field) - case "highAvailability": - return ec.fieldContext_PostgresInstanceFacets_highAvailability(ctx, field) - case "majorVersions": - return ec.fieldContext_PostgresInstanceFacets_majorVersions(ctx, field) case "labels": return ec.fieldContext_PostgresInstanceFacets_labels(ctx, field) } return nil, fmt.Errorf("no field named %q was found under type PostgresInstanceFacets", field.Name) } -func (ec *executionContext) childFields_PostgresInstanceMaintenanceWindow(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "day": - return ec.fieldContext_PostgresInstanceMaintenanceWindow_day(ctx, field) - case "hour": - return ec.fieldContext_PostgresInstanceMaintenanceWindow_hour(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type PostgresInstanceMaintenanceWindow", field.Name) -} - -func (ec *executionContext) childFields_PostgresInstanceResources(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "cpu": - return ec.fieldContext_PostgresInstanceResources_cpu(ctx, field) - case "memory": - return ec.fieldContext_PostgresInstanceResources_memory(ctx, field) - case "diskSize": - return ec.fieldContext_PostgresInstanceResources_diskSize(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type PostgresInstanceResources", field.Name) -} - func (ec *executionContext) childFields_PostgresInstanceStateFacetItem(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { switch field.Name { case "state": @@ -37078,6 +36894,18 @@ func (ec *executionContext) childFields_PostgresPersonalAccessCreatedActivityLog return nil, fmt.Errorf("no field named %q was found under type PostgresPersonalAccessCreatedActivityLogEntryData", field.Name) } +func (ec *executionContext) childFields_PostgresResources(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "cpu": + return ec.fieldContext_PostgresResources_cpu(ctx, field) + case "memory": + return ec.fieldContext_PostgresResources_memory(ctx, field) + case "diskSize": + return ec.fieldContext_PostgresResources_diskSize(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type PostgresResources", field.Name) +} + func (ec *executionContext) childFields_Price(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { switch field.Name { case "value": @@ -38296,6 +38124,8 @@ func (ec *executionContext) childFields_TeamEnvironment(ctx context.Context, fie return ec.fieldContext_TeamEnvironment_kafkaTopic(ctx, field) case "openSearch": return ec.fieldContext_TeamEnvironment_openSearch(ctx, field) + case "postgres": + return ec.fieldContext_TeamEnvironment_postgres(ctx, field) case "postgresInstance": return ec.fieldContext_TeamEnvironment_postgresInstance(ctx, field) case "secret": diff --git a/internal/graph/gengql/schema.generated.go b/internal/graph/gengql/schema.generated.go index 761ed9f9d..0a1428564 100644 --- a/internal/graph/gengql/schema.generated.go +++ b/internal/graph/gengql/schema.generated.go @@ -85,7 +85,6 @@ type MutationResolver interface { DeleteOpenSearch(ctx context.Context, input opensearch.DeleteOpenSearchInput) (*opensearch.DeleteOpenSearchPayload, error) CreateOpenSearchCredentials(ctx context.Context, input opensearch.CreateOpenSearchCredentialsInput) (*opensearch.CreateOpenSearchCredentialsPayload, error) CreatePostgresAccess(ctx context.Context, input postgres.CreatePostgresAccessInput) (*postgres.CreatePostgresAccessPayload, error) - GrantPostgresAccess(ctx context.Context, input postgres.GrantPostgresAccessInput) (*postgres.GrantPostgresAccessPayload, error) DeletePostgres(ctx context.Context, input postgres.DeletePostgresInput) (*postgres.DeletePostgresPayload, error) EnableReconciler(ctx context.Context, input reconciler.EnableReconcilerInput) (*reconciler.Reconciler, error) DisableReconciler(ctx context.Context, input reconciler.DisableReconcilerInput) (*reconciler.Reconciler, error) @@ -689,20 +688,6 @@ func (ec *executionContext) field_Mutation_enableReconciler_args(ctx context.Con return args, nil } -func (ec *executionContext) field_Mutation_grantPostgresAccess_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { - var err error - args := map[string]any{} - arg0, err := graphql.ProcessArgField(ctx, rawArgs, "input", - func(ctx context.Context, v any) (postgres.GrantPostgresAccessInput, error) { - return ec.unmarshalNGrantPostgresAccessInput2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐGrantPostgresAccessInput(ctx, v) - }) - if err != nil { - return nil, err - } - args["input"] = arg0 - return args, nil -} - func (ec *executionContext) field_Mutation_removeConfigValue_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} @@ -2741,50 +2726,6 @@ func (ec *executionContext) fieldContext_Mutation_createPostgresAccess(ctx conte return fc, nil } -func (ec *executionContext) _Mutation_grantPostgresAccess(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { - return graphql.ResolveField( - ctx, - ec.OperationContext, - field, - func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_Mutation_grantPostgresAccess(ctx, field) - }, - func(ctx context.Context) (any, error) { - fc := graphql.GetFieldContext(ctx) - return ec.Resolvers.Mutation().GrantPostgresAccess(ctx, fc.Args["input"].(postgres.GrantPostgresAccessInput)) - }, - nil, - func(ctx context.Context, selections ast.SelectionSet, v *postgres.GrantPostgresAccessPayload) graphql.Marshaler { - return ec.marshalNGrantPostgresAccessPayload2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐGrantPostgresAccessPayload(ctx, selections, v) - }, - true, - true, - ) -} -func (ec *executionContext) fieldContext_Mutation_grantPostgresAccess(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Mutation", - Field: field, - IsMethod: true, - IsResolver: true, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_GrantPostgresAccessPayload(ctx, field) - }, - } - defer func() { - if r := recover(); r != nil { - err = ec.Recover(ctx, r) - ec.Error(ctx, err) - } - }() - ctx = graphql.WithFieldContext(ctx, fc) - if fc.Args, err = ec.field_Mutation_grantPostgresAccess_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { - ec.Error(ctx, err) - return fc, err - } - return fc, nil -} - func (ec *executionContext) _Mutation_deletePostgres(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -7127,6 +7068,13 @@ func (ec *executionContext) _Node(ctx context.Context, sel ast.SelectionSet, obj return graphql.Null } return ec._PostgresAccess(ctx, sel, obj) + case postgres.Postgres: + return ec._Postgres(ctx, sel, &obj) + case *postgres.Postgres: + if obj == nil { + return graphql.Null + } + return ec._Postgres(ctx, sel, obj) case persistence.Persistence: if obj == nil { return graphql.Null @@ -7455,13 +7403,6 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) if out.Values[i] == graphql.Null { out.Invalids++ } - case "grantPostgresAccess": - out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { - return ec._Mutation_grantPostgresAccess(ctx, field) - }) - if out.Values[i] == graphql.Null { - out.Invalids++ - } case "deletePostgres": out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { return ec._Mutation_deletePostgres(ctx, field) diff --git a/internal/graph/gengql/teams.generated.go b/internal/graph/gengql/teams.generated.go index 0480e03c0..01ebdfff6 100644 --- a/internal/graph/gengql/teams.generated.go +++ b/internal/graph/gengql/teams.generated.go @@ -104,6 +104,7 @@ type TeamEnvironmentResolver interface { Job(ctx context.Context, obj *team.TeamEnvironment, name string) (*job.Job, error) KafkaTopic(ctx context.Context, obj *team.TeamEnvironment, name string) (*kafkatopic.KafkaTopic, error) OpenSearch(ctx context.Context, obj *team.TeamEnvironment, name string) (*opensearch.OpenSearch, error) + Postgres(ctx context.Context, obj *team.TeamEnvironment, name string) (*postgres.Postgres, error) PostgresInstance(ctx context.Context, obj *team.TeamEnvironment, name string) (*postgres.PostgresInstance, error) Secret(ctx context.Context, obj *team.TeamEnvironment, name string) (*secret.Secret, error) SQLInstance(ctx context.Context, obj *team.TeamEnvironment, name string) (*sqlinstance.SQLInstance, error) @@ -302,6 +303,20 @@ func (ec *executionContext) field_TeamEnvironment_postgresInstance_args(ctx cont return args, nil } +func (ec *executionContext) field_TeamEnvironment_postgres_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := graphql.ProcessArgField(ctx, rawArgs, "name", + func(ctx context.Context, v any) (string, error) { + return ec.unmarshalNString2string(ctx, v) + }) + if err != nil { + return nil, err + } + args["name"] = arg0 + return args, nil +} + func (ec *executionContext) field_TeamEnvironment_secret_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} @@ -4743,6 +4758,50 @@ func (ec *executionContext) fieldContext_TeamEnvironment_openSearch(ctx context. return fc, nil } +func (ec *executionContext) _TeamEnvironment_postgres(ctx context.Context, field graphql.CollectedField, obj *team.TeamEnvironment) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_TeamEnvironment_postgres(ctx, field) + }, + func(ctx context.Context) (any, error) { + fc := graphql.GetFieldContext(ctx) + return ec.Resolvers.TeamEnvironment().Postgres(ctx, obj, fc.Args["name"].(string)) + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *postgres.Postgres) graphql.Marshaler { + return ec.marshalNPostgres2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgres(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_TeamEnvironment_postgres(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "TeamEnvironment", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_Postgres(ctx, field) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_TeamEnvironment_postgres_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + func (ec *executionContext) _TeamEnvironment_postgresInstance(ctx context.Context, field graphql.CollectedField, obj *team.TeamEnvironment) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -10356,6 +10415,42 @@ func (ec *executionContext) _TeamEnvironment(ctx context.Context, sel ast.Select continue } + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + case "postgres": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._TeamEnvironment_postgres(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + if field.Deferrable != nil { + dfs, ok := deferred[field.Deferrable.Label] + di := 0 + if ok { + dfs.AddField(field) + di = len(dfs.Values) - 1 + } else { + dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) + deferred[field.Deferrable.Label] = dfs + } + dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { + return innerFunc(ctx, dfs) + }) + + // don't run the out.Concurrently() call below + out.Values[i] = graphql.Null + continue + } + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) case "postgresInstance": field := field diff --git a/internal/graph/postgres.resolvers.go b/internal/graph/postgres.resolvers.go index fd932fa53..7d17184ff 100644 --- a/internal/graph/postgres.resolvers.go +++ b/internal/graph/postgres.resolvers.go @@ -15,38 +15,24 @@ import ( ) func (r *applicationResolver) PostgresInstances(ctx context.Context, obj *application.Application, orderBy *postgres.PostgresInstanceOrder) (*pagination.FacetableConnection[*postgres.PostgresInstance, *postgres.PostgresInstanceFilter], error) { - if obj.Spec.Postgres == nil || obj.Spec.Postgres.ClusterName == "" { + if obj.Spec == nil || obj.Spec.Uses == nil { return pagination.NewFacetableConnection(pagination.EmptyConnection[*postgres.PostgresInstance](), nil, (*postgres.PostgresInstanceFilter)(nil)), nil } - - instance, err := postgres.GetForWorkload(ctx, obj.TeamSlug, obj.EnvironmentName, obj.Spec.Postgres.ClusterName) + instances, err := postgres.ListForWorkload(ctx, obj.TeamSlug, obj.EnvironmentName, obj.Spec.Uses.Postgres) if err != nil { return nil, err } - - if instance == nil { - return pagination.NewFacetableConnection(pagination.EmptyConnection[*postgres.PostgresInstance](), nil, (*postgres.PostgresInstanceFilter)(nil)), nil - } - - instances := []*postgres.PostgresInstance{instance} return pagination.NewFacetableConnection(pagination.NewConnectionWithoutPagination(instances), instances, (*postgres.PostgresInstanceFilter)(nil)), nil } func (r *jobResolver) PostgresInstances(ctx context.Context, obj *job.Job, orderBy *postgres.PostgresInstanceOrder) (*pagination.FacetableConnection[*postgres.PostgresInstance, *postgres.PostgresInstanceFilter], error) { - if obj.Spec.Postgres == nil || obj.Spec.Postgres.ClusterName == "" { + if obj.Spec == nil || obj.Spec.Uses == nil { return pagination.NewFacetableConnection(pagination.EmptyConnection[*postgres.PostgresInstance](), nil, (*postgres.PostgresInstanceFilter)(nil)), nil } - - instance, err := postgres.GetForWorkload(ctx, obj.TeamSlug, obj.EnvironmentName, obj.Spec.Postgres.ClusterName) + instances, err := postgres.ListForWorkload(ctx, obj.TeamSlug, obj.EnvironmentName, obj.Spec.Uses.Postgres) if err != nil { return nil, err } - - if instance == nil { - return pagination.NewFacetableConnection(pagination.EmptyConnection[*postgres.PostgresInstance](), nil, (*postgres.PostgresInstanceFilter)(nil)), nil - } - - instances := []*postgres.PostgresInstance{instance} return pagination.NewFacetableConnection(pagination.NewConnectionWithoutPagination(instances), instances, (*postgres.PostgresInstanceFilter)(nil)), nil } @@ -58,20 +44,6 @@ func (r *mutationResolver) CreatePostgresAccess(ctx context.Context, input postg return postgres.CreatePostgresAccess(ctx, input) } -func (r *mutationResolver) GrantPostgresAccess(ctx context.Context, input postgres.GrantPostgresAccessInput) (*postgres.GrantPostgresAccessPayload, error) { - if err := authz.CanGrantPostgresAccess(ctx, input.TeamSlug); err != nil { - return nil, err - } - - if err := postgres.GrantPostgresAccess(ctx, input); err != nil { - return nil, err - } - - return &postgres.GrantPostgresAccessPayload{ - Error: new(string), - }, nil -} - func (r *mutationResolver) DeletePostgres(ctx context.Context, input postgres.DeletePostgresInput) (*postgres.DeletePostgresPayload, error) { if err := authz.CanDeletePostgres(ctx, input.TeamSlug); err != nil { return nil, err @@ -88,7 +60,7 @@ func (r *postgresAccessResolver) TeamEnvironment(ctx context.Context, obj *postg } func (r *postgresAccessResolver) PostgresInstance(ctx context.Context, obj *postgres.PostgresAccess) (*postgres.PostgresInstance, error) { - return postgres.GetPostgres(ctx, obj.TeamSlug, obj.EnvironmentName, obj.PostgresInstanceName) + return postgres.GetPostgresInstance(ctx, obj.TeamSlug, obj.EnvironmentName, obj.PostgresInstanceName) } func (r *postgresInstanceResolver) Team(ctx context.Context, obj *postgres.PostgresInstance) (*team.Team, error) { @@ -99,6 +71,10 @@ func (r *postgresInstanceResolver) TeamEnvironment(ctx context.Context, obj *pos return team.GetTeamEnvironment(ctx, obj.TeamSlug, obj.EnvironmentName) } +func (r *postgresInstanceResolver) Postgres(ctx context.Context, obj *postgres.PostgresInstance) (*postgres.Postgres, error) { + return postgres.GetPostgres(ctx, obj.TeamSlug, obj.EnvironmentName, obj.PostgresName) +} + func (r *postgresInstanceResolver) Workloads(ctx context.Context, obj *postgres.PostgresInstance, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor) (*pagination.Connection[workload.Workload], error) { page, err := pagination.ParsePage(first, after, last, before) if err != nil { @@ -110,10 +86,6 @@ func (r *postgresInstanceResolver) Workloads(ctx context.Context, obj *postgres. return pagination.NewConnection(pagination.Slice(workloads, page), page, len(workloads)), nil } -func (r *postgresInstanceAuditResolver) URL(ctx context.Context, obj *postgres.PostgresInstanceAudit) (*string, error) { - return postgres.GetAuditURL(ctx, obj) -} - func (r *postgresInstanceConnectionResolver) Facets(ctx context.Context, obj *pagination.FacetableConnection[*postgres.PostgresInstance, *postgres.PostgresInstanceFilter]) (*postgres.PostgresInstanceFacets, error) { return &postgres.PostgresInstanceFacets{ AllInstances: obj.GetAllItems(), @@ -138,10 +110,14 @@ func (r *teamResolver) PostgresInstances(ctx context.Context, obj *team.Team, fi return postgres.ListForTeam(ctx, obj.Slug, page, orderBy, filter) } -func (r *teamEnvironmentResolver) PostgresInstance(ctx context.Context, obj *team.TeamEnvironment, name string) (*postgres.PostgresInstance, error) { +func (r *teamEnvironmentResolver) Postgres(ctx context.Context, obj *team.TeamEnvironment, name string) (*postgres.Postgres, error) { return postgres.GetPostgres(ctx, obj.TeamSlug, obj.EnvironmentName, name) } +func (r *teamEnvironmentResolver) PostgresInstance(ctx context.Context, obj *team.TeamEnvironment, name string) (*postgres.PostgresInstance, error) { + return postgres.GetPostgresInstance(ctx, obj.TeamSlug, obj.EnvironmentName, name) +} + func (r *teamInventoryCountsResolver) PostgresInstances(ctx context.Context, obj *team.TeamInventoryCounts) (*postgres.TeamInventoryCountPostgresInstances, error) { return &postgres.TeamInventoryCountPostgresInstances{ Total: postgres.CountForTeam(ctx, obj.TeamSlug), @@ -154,10 +130,6 @@ func (r *Resolver) PostgresInstance() gengql.PostgresInstanceResolver { return &postgresInstanceResolver{r} } -func (r *Resolver) PostgresInstanceAudit() gengql.PostgresInstanceAuditResolver { - return &postgresInstanceAuditResolver{r} -} - func (r *Resolver) PostgresInstanceConnection() gengql.PostgresInstanceConnectionResolver { return &postgresInstanceConnectionResolver{r} } @@ -165,6 +137,5 @@ func (r *Resolver) PostgresInstanceConnection() gengql.PostgresInstanceConnectio type ( postgresAccessResolver struct{ *Resolver } postgresInstanceResolver struct{ *Resolver } - postgresInstanceAuditResolver struct{ *Resolver } postgresInstanceConnectionResolver struct{ *Resolver } ) diff --git a/internal/graph/schema/postgres.graphqls b/internal/graph/schema/postgres.graphqls index 2efef5694..c836500b2 100644 --- a/internal/graph/schema/postgres.graphqls +++ b/internal/graph/schema/postgres.graphqls @@ -22,12 +22,14 @@ extend type Team { } extend type TeamEnvironment { - "Postgres instance in the team environment." + "Postgres in the team environment." + postgres(name: String!): Postgres! + "Named PostgresInstance in the team environment." postgresInstance(name: String!): PostgresInstance! } extend interface Workload { - "Postgres instances referenced by the workload. This does not currently support pagination, but will return all available Postgres instances." + "Active PostgresInstances for all Postgres entries in uses.postgres." postgresInstances( "Ordering options for items returned from the connection." orderBy: PostgresInstanceOrder @@ -35,7 +37,7 @@ extend interface Workload { } extend type Application { - "Postgres instances referenced by the application. This does not currently support pagination, but will return all available Postgres instances." + "Active PostgresInstances for all Postgres entries in uses.postgres." postgresInstances( "Ordering options for items returned from the connection." orderBy: PostgresInstanceOrder @@ -43,7 +45,7 @@ extend type Application { } extend type Job { - "Postgres instances referenced by the job. This does not currently support pagination, but will return all available Postgres instances." + "Active PostgresInstances for all Postgres entries in uses.postgres." postgresInstances( "Ordering options for items returned from the connection." orderBy: PostgresInstanceOrder @@ -68,12 +70,6 @@ input PostgresInstanceFilter { "Filter by instance state." states: [PostgresInstanceState!] - "Filter by high availability." - highAvailability: Boolean - - "Filter by major versions." - majorVersions: [String!] - "Filter by user-defined labels. All listed labels must match." labels: [LabelFilter!] } @@ -83,61 +79,45 @@ enum PostgresInstanceOrderField { ENVIRONMENT } +"A named PostgresInstance belonging to a Postgres." type PostgresInstance implements Persistence & Node { id: ID! name: String! team: Team! teamEnvironment: TeamEnvironment! - "Workloads that reference the Postgres instance." - workloads( - "Get the first n items in the connection. This can be used in combination with the after parameter." - first: Int - - "Get items after this cursor." - after: Cursor - - "Get the last n items in the connection. This can be used in combination with the before parameter." - last: Int + "Postgres owning this PostgresInstance." + postgres: Postgres! + "Workloads using this instance while it is active." + workloads(first: Int, after: Cursor, last: Int, before: Cursor): WorkloadConnection! + state: PostgresInstanceState! + labels: [ResourceLabel!]! +} - "Get items before this cursor." - before: Cursor - ): WorkloadConnection! - "Resource allocation for the Postgres cluster." - resources: PostgresInstanceResources! - "Major version of PostgreSQL." +"A Postgres whose active instance can change." +type Postgres implements Node { + id: ID! + name: String! majorVersion: String! - "Audit logging configuration for the Postgres cluster." - audit: PostgresInstanceAudit! - "Indicates whether the Postgres cluster is configured for high availability." highAvailability: Boolean! - "Current state of the Postgres cluster." - state: PostgresInstanceState! - "Maintenance window for the Postgres cluster, if configured." - maintenanceWindow: PostgresInstanceMaintenanceWindow - "User-defined labels attached to this instance." + "Requested CPU, memory and disk size, when present on this Postgres." + resources: PostgresResources! + activeInstance: String labels: [ResourceLabel!]! } +"Resource requests configured on Postgres. Omitted requests are null." +type PostgresResources { + cpu: String + memory: String + diskSize: String +} + enum PostgresInstanceState { AVAILABLE PROGRESSING DEGRADED } -type PostgresInstanceMaintenanceWindow { - day: Int! - hour: Int! -} - -type PostgresInstanceAudit { - "Indicates whether audit logging is enabled for the Postgres cluster." - enabled: Boolean! - "URL for accessing the audit logs." - url: String - "List of statement classes that are being logged, such as `ddl`, `dml`, and `read`." - statementClasses: [String!] -} - type PostgresInstanceConnection { pageInfo: PageInfo! nodes: [PostgresInstance!]! @@ -165,12 +145,6 @@ type PostgresInstanceFacets { "Distribution of instances by state." states: [PostgresInstanceStateFacetItem!]! - "Distribution of instances by high availability." - highAvailability: [BooleanFacetItem!]! - - "Distribution of instances by major version." - majorVersions: [StringFacetItem!]! - "Distribution of instances by user-defined labels." labels: [LabelFacetItem!]! } @@ -186,12 +160,6 @@ type PostgresInstanceStateFacetItem { count: Int! } -type PostgresInstanceResources { - cpu: String! - memory: String! - diskSize: String! -} - extend union SearchNode = PostgresInstance extend enum SearchType { @@ -338,16 +306,11 @@ extend enum ActivityLogActivityType { extend type Mutation { """ - Create time-limited personal access to a NAIS Postgres instance through the brokered PostgresAccess and WireGuard tunnel flow. + Create time-limited personal access to a NAIS Postgres instance through the brokered PostgresAccess and relay flow. Use this for new NAIS Postgres personal access. When the access is ready, retrieve its connection materials with postgresAccessConnection. """ createPostgresAccess(input: CreatePostgresAccessInput!): CreatePostgresAccessPayload! - """ - Grant time-limited Kubernetes RBAC access to database pods for kubectl port-forward. - Use this existing flow for Cloud SQL access; it does not create a PostgresAccess, WireGuard tunnel, or database credentials. - """ - grantPostgresAccess(input: GrantPostgresAccessInput!): GrantPostgresAccessPayload! - "Delete an existing Postgres instance." + "Delete a PostgresInstance that is not active on its Postgres." deletePostgres(input: DeletePostgresInput!): DeletePostgresPayload! } @@ -361,7 +324,7 @@ type CreatePostgresAccessPayload { "Input for creating a time-limited personal Postgres access." input CreatePostgresAccessInput { - "Name of the available Postgres instance to access." + "Name of the PostgresInstance to access." postgresInstance: String! "Team that owns the Postgres instance." teamSlug: Slug! @@ -369,11 +332,9 @@ input CreatePostgresAccessInput { environmentName: String! "Privileges requested for the personal database role." accessLevel: PostgresAccessLevel! - "WireGuard public key generated by the client for this access." - clientWireGuardPublicKey: String! "Reason for personal database access. Must be at least 10 characters." reason: String! - "Requested access lifetime (for example '1h' or '4h'). Defaults to '1h' and cannot exceed '8h'." + "Requested access lifetime (for example '30m' or '1h'). Defaults to '1h' and cannot exceed '1h'." ttl: String } @@ -387,19 +348,6 @@ enum PostgresAccessLevel { READWRITECREATE } -type GrantPostgresAccessPayload { - error: String -} - -input GrantPostgresAccessInput { - clusterName: String! - teamSlug: Slug! - environmentName: String! - grantee: String! - "Duration of the access grant (maximum 4 hours)." - duration: String! -} - input DeletePostgresInput { "Name of the Postgres instance." name: String! @@ -450,7 +398,7 @@ type PostgresAccess implements Node { team: Team! "Environment for the access." teamEnvironment: TeamEnvironment! - "Postgres instance this access is for." + "PostgresInstance selected by this access." postgresInstance: PostgresInstance! "Requested access level." accessLevel: PostgresAccessLevel! @@ -460,8 +408,8 @@ type PostgresAccess implements Node { state: PostgresAccessState! "Human-readable message for the current state." message: String - "Tunnel connection details, once the controller has created them." - tunnel: PostgresAccessTunnel + "Name of the controller-owned relay mapping, once created. Contains no credential." + relayAccess: String } "High-level reconciliation state of a personal Postgres access." @@ -476,16 +424,6 @@ enum PostgresAccessState { EXPIRED } -"Tunnel details reported while provisioning a personal Postgres access." -type PostgresAccessTunnel { - "Name of the Tunnel resource owned by this access." - name: String! - "Gateway endpoint the client should connect to." - endpoint: String - "Gateway's WireGuard public key." - gatewayPublicKey: String -} - "Input for retrieving connection materials for a ready personal access." input PostgresAccessConnectionInput { "Name of the PostgresAccess resource." @@ -498,20 +436,18 @@ input PostgresAccessConnectionInput { "Sensitive connection materials for a ready personal Postgres access." type PostgresAccessConnection { + "Database username for the caller's personal role." + username: String! "Short-lived password for the caller's database role." password: String! "CA certificate required to verify the PostgreSQL server certificate." caCertificate: String! "PostgreSQL server name used for TLS verification." serverName: String! - "WireGuard tunnel endpoint and server public key." - tunnel: PostgresAccessConnectionTunnel! -} - -"WireGuard connection parameters for a personal Postgres access." -type PostgresAccessConnectionTunnel { - "Public UDP endpoint of the Tunnel forwarder." - endpoint: String! - "WireGuard public key of the Tunnel gateway." - gatewayPublicKey: String! + "Public HTTP/3 relay endpoint." + relayEndpoint: String! + "Relay-Access header value (namespace/name)." + relayAccess: String! + "Owner-only bearer token for this access; never log it." + relayToken: String! } diff --git a/internal/grpc/grpcdatabase/server.go b/internal/grpc/grpcdatabase/server.go index e7ac9de59..bd1a71ffd 100644 --- a/internal/grpc/grpcdatabase/server.go +++ b/internal/grpc/grpcdatabase/server.go @@ -83,6 +83,6 @@ func postgresInstanceToProto(p *postgres.PostgresInstance) *protoapi.Database { Database: "app", Environment: p.EnvironmentName, TeamSlug: p.TeamSlug.String(), - Type: protoapi.DatabaseType_ZALANDO_POSTGRES, + Type: protoapi.DatabaseType_NAIS_POSTGRES, } } diff --git a/internal/grpc/grpcdatabase/server_test.go b/internal/grpc/grpcdatabase/server_test.go index a1c6c2700..319860134 100644 --- a/internal/grpc/grpcdatabase/server_test.go +++ b/internal/grpc/grpcdatabase/server_test.go @@ -28,8 +28,8 @@ func TestDatabasesServer_List(t *testing.T) { // CLOUD_SQL dev-gcp instance-a db-a // CLOUD_SQL dev-gcp instance-a db-b // CLOUD_SQL prod-gcp instance-a db-a - // ZALANDO_POSTGRES dev-gcp pg-a app - // ZALANDO_POSTGRES dev-gcp pg-b app + // NAIS_POSTGRES dev-gcp pg-a app + // NAIS_POSTGRES dev-gcp pg-b app // // Fixtures live under testdata/ — the fake client harness // (internal/kubernetes/fake) sets the object namespace from the parent @@ -78,8 +78,8 @@ func TestDatabasesServer_List(t *testing.T) { {typ: protoapi.DatabaseType_CLOUD_SQL, environment: "dev-gcp", name: "instance-a", database: "db-a"}, {typ: protoapi.DatabaseType_CLOUD_SQL, environment: "dev-gcp", name: "instance-a", database: "db-b"}, {typ: protoapi.DatabaseType_CLOUD_SQL, environment: "prod-gcp", name: "instance-a", database: "db-a"}, - {typ: protoapi.DatabaseType_ZALANDO_POSTGRES, environment: "dev-gcp", name: "pg-a", database: "app"}, - {typ: protoapi.DatabaseType_ZALANDO_POSTGRES, environment: "dev-gcp", name: "pg-b", database: "app"}, + {typ: protoapi.DatabaseType_NAIS_POSTGRES, environment: "dev-gcp", name: "pg-a", database: "app"}, + {typ: protoapi.DatabaseType_NAIS_POSTGRES, environment: "dev-gcp", name: "pg-b", database: "app"}, } // Repeated calls must return the same order. diff --git a/internal/grpc/grpcdatabase/testdata/dev-gcp/myteam/postgres.yaml b/internal/grpc/grpcdatabase/testdata/dev-gcp/myteam/postgres.yaml index ea34f1c0a..6b8b3310e 100644 --- a/internal/grpc/grpcdatabase/testdata/dev-gcp/myteam/postgres.yaml +++ b/internal/grpc/grpcdatabase/testdata/dev-gcp/myteam/postgres.yaml @@ -1,23 +1,52 @@ -apiVersion: data.nais.io/v1 +--- +apiVersion: nais.io/v1 kind: Postgres metadata: name: pg-b + namespace: myteam +spec: + majorVersion: "17" +status: + activeInstance: pg-b +--- +apiVersion: nais.io/v1 +kind: PostgresInstance +metadata: + name: pg-b + namespace: myteam spec: - cluster: - majorVersion: "17" - resources: - diskSize: "2Gi" - cpu: "100m" - memory: "1Gi" + postgres: pg-b +status: + reconcilePhase: Completed + conditions: + - type: cluster.postgresql.cnpg.io/ObservedState + status: "True" + reason: Reconciled + message: "Cluster is in phase: Cluster in healthy state" + lastTransitionTime: "2026-09-17T00:00:00Z" --- -apiVersion: data.nais.io/v1 +apiVersion: nais.io/v1 kind: Postgres metadata: name: pg-a + namespace: myteam +spec: + majorVersion: "17" +status: + activeInstance: pg-a +--- +apiVersion: nais.io/v1 +kind: PostgresInstance +metadata: + name: pg-a + namespace: myteam spec: - cluster: - majorVersion: "17" - resources: - diskSize: "2Gi" - cpu: "100m" - memory: "1Gi" + postgres: pg-a +status: + reconcilePhase: Completed + conditions: + - type: cluster.postgresql.cnpg.io/ObservedState + status: "True" + reason: Reconciled + message: "Cluster is in phase: Cluster in healthy state" + lastTransitionTime: "2026-09-17T00:00:00Z" diff --git a/internal/kubernetes/fake/fake.go b/internal/kubernetes/fake/fake.go index bb0e3848a..8b1ad8cee 100644 --- a/internal/kubernetes/fake/fake.go +++ b/internal/kubernetes/fake/fake.go @@ -15,7 +15,6 @@ import ( "github.com/nais/api/internal/kubernetes/watcher" liberator_aiven_io_v1alpha1 "github.com/nais/liberator/pkg/apis/aiven.io/v1alpha1" nais_io_v1alpha1 "github.com/nais/liberator/pkg/apis/nais.io/v1alpha1" - data_nais_io_v1 "github.com/nais/pgrator/pkg/api/datav1" mapperatorv1 "github.com/nais/pgrator/pkg/api/v1" unleash_nais_io_v1 "github.com/nais/unleasherator/api/v1" "k8s.io/apimachinery/pkg/api/meta" @@ -216,7 +215,8 @@ func NewDynamicClient(scheme *runtime.Scheme) *dynfake.FakeDynamicClient { liberator_aiven_io_v1alpha1.GroupVersion.WithResource("opensearches"): "OpenSearchList", unleash_nais_io_v1.GroupVersion.WithResource("unleashes"): "UnleashList", unleash_nais_io_v1.GroupVersion.WithResource("remoteunleashes"): "RemoteUnleashList", - data_nais_io_v1.GroupVersion.WithResource("postgres"): "PostgresList", + mapperatorv1.GroupVersion.WithResource("postgres"): "PostgresList", + mapperatorv1.GroupVersion.WithResource("postgresinstances"): "PostgresInstanceList", nais_io_v1alpha1.GroupVersion.WithResource("tunnels"): "TunnelList", mapperatorv1.GroupVersion.WithResource("valkeys"): "ValkeyList", mapperatorv1.GroupVersion.WithResource("opensearches"): "OpenSearchList", diff --git a/internal/kubernetes/fake/postgres_fixtures_test.go b/internal/kubernetes/fake/postgres_fixtures_test.go new file mode 100644 index 000000000..abb4d9d9f --- /dev/null +++ b/internal/kubernetes/fake/postgres_fixtures_test.go @@ -0,0 +1,39 @@ +package fake_test + +import ( + "os" + "testing" + + "github.com/nais/api/internal/kubernetes" + "github.com/nais/api/internal/kubernetes/fake" +) + +func TestPostgresFixturesUseRegisteredV1Kinds(t *testing.T) { + scheme, err := kubernetes.NewScheme() + if err != nil { + t.Fatal(err) + } + for _, path := range []string{ + "../../../integration_tests/k8s_resources/create_postgres_access", + "../../../integration_tests/k8s_resources/postgres_instances", + "../../../integration_tests/k8s_resources/postgres_workloads", + "../../../integration_tests/k8s_resources/postgres_delete", + "../../../integration_tests/k8s_resources/postgres_audit_log", + "../../../integration_tests/k8s_resources/label_selectors", + "../../../data/k8s", + } { + resources, err := fake.ParseResources(scheme, os.DirFS(path)) + if err != nil { + t.Fatalf("%s: %v", path, err) + } + if len(resources) == 0 { + t.Errorf("%s: no fixtures", path) + } + // Parsing alone does not detect two files declaring the same resource. + // Insert every object into the same fake tracker used by the Lua suite. + for _, objects := range resources { + client := fake.NewDynamicClient(scheme) + fake.AddObjectToDynamicClient(scheme, client, objects...) + } + } +} diff --git a/internal/kubernetes/scheme.go b/internal/kubernetes/scheme.go index 60e0a63e2..c6c6ce159 100644 --- a/internal/kubernetes/scheme.go +++ b/internal/kubernetes/scheme.go @@ -9,7 +9,6 @@ import ( kafka_nais_io_v1 "github.com/nais/liberator/pkg/apis/kafka.nais.io/v1" nais_io_v1 "github.com/nais/liberator/pkg/apis/nais.io/v1" nais_io_v1alpha1 "github.com/nais/liberator/pkg/apis/nais.io/v1alpha1" - data_nais_io_v1 "github.com/nais/pgrator/pkg/api/datav1" mapperatorv1 "github.com/nais/pgrator/pkg/api/v1" unleash_nais_io_v1 "github.com/nais/unleasherator/api/v1" appsv1 "k8s.io/api/apps/v1" @@ -18,7 +17,9 @@ import ( corev1 "k8s.io/api/core/v1" netv1 "k8s.io/api/networking/v1" rbacv1 "k8s.io/api/rbac/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" ) func NewScheme() (*runtime.Scheme, error) { @@ -39,7 +40,6 @@ func NewScheme() (*runtime.Scheme, error) { unleash_nais_io_v1.AddToScheme, batchv1.AddToScheme, aiven_nais_io_v1.AddToScheme, - data_nais_io_v1.AddToScheme, authorizationv1.AddToScheme, mapperatorv1.AddToScheme, } @@ -50,5 +50,17 @@ func NewScheme() (*runtime.Scheme, error) { } } + // The API reads these CRDs through dynamic clients without importing their + // controller implementations. Register their GVKs for local fake clients. + for _, gv := range []struct { + group, version, kind string + }{ + {"nais.io", "v1alpha1", "RelayAccess"}, + {"postgresql.cnpg.io", "v1", "Cluster"}, + } { + version := schema.GroupVersion{Group: gv.group, Version: gv.version} + scheme.AddKnownTypeWithName(version.WithKind(gv.kind), &unstructured.Unstructured{}) + scheme.AddKnownTypeWithName(version.WithKind(gv.kind+"List"), &unstructured.UnstructuredList{}) + } return scheme, nil } diff --git a/internal/persistence/bigquery/models.go b/internal/persistence/bigquery/models.go index e9637a511..22f35ca9e 100644 --- a/internal/persistence/bigquery/models.go +++ b/internal/persistence/bigquery/models.go @@ -52,7 +52,6 @@ type BigQueryDataset struct { TeamSlug slug.Slug `json:"-"` EnvironmentName string `json:"-"` WorkloadReference *workload.Reference `json:"-"` - ProjectID string `json:"-"` K8sResourceName string `json:"-"` } @@ -195,7 +194,6 @@ func toBigQueryDataset(u *unstructured.Unstructured, environmentName string) (*B TeamSlug: slug.Slug(obj.GetNamespace()), EnvironmentName: environmentName, WorkloadReference: workload.ReferenceFromOwnerReferences(obj.GetOwnerReferences()), - ProjectID: obj.Spec.Project, } if obj.Spec.Description != "" { diff --git a/internal/persistence/postgres/connection.go b/internal/persistence/postgres/connection.go new file mode 100644 index 000000000..8a6020b12 --- /dev/null +++ b/internal/persistence/postgres/connection.go @@ -0,0 +1,160 @@ +package postgres + +import ( + "context" + "crypto/sha256" + "encoding/base64" + "encoding/hex" + "fmt" + "strings" + + "github.com/nais/api/internal/graph/apierror" + "github.com/nais/api/internal/kubernetes/watcher" + pgratorv1 "github.com/nais/pgrator/pkg/api/v1" + corev1 "k8s.io/api/core/v1" + k8serrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" +) + +// All connection resources are read on demand after the caller has been +// authorized as the PostgresAccess owner. No credentials enter the watch cache. +func loadPostgresAccessConnection(ctx context.Context, access *unstructured.Unstructured, input PostgresAccessConnectionInput, connection *PostgresAccessConnection, tokenSecretName string) error { + instance, _, err := unstructured.NestedString(access.Object, "spec", "postgresInstance") + if err != nil || instance == "" || access.GetUID() == "" { + return apierror.Errorf("PostgresAccess %q is not ready", access.GetName()) + } + clusterName := pgratorv1.CNPGClusterName(instance) + if clusterName == "" { + return apierror.Errorf("PostgresAccess %q is not ready", access.GetName()) + } + namespace := input.TeamSlug.String() + mapping, err := getAccessResource(ctx, input.EnvironmentName, namespace, access.GetName(), schema.GroupVersionResource{Group: "nais.io", Version: "v1alpha1", Resource: "relayaccesses"}) + if err != nil { + return err + } + service, _, err := unstructured.NestedString(mapping.Object, "spec", "target", "serviceName") + if err != nil { + return err + } + port, _, err := unstructured.NestedInt64(mapping.Object, "spec", "target", "port") + if err != nil { + return err + } + expires, _, err := unstructured.NestedString(mapping.Object, "spec", "expiresAt") + if err != nil { + return err + } + accessExpires, _, err := unstructured.NestedString(access.Object, "spec", "expiresAt") + if err != nil { + return err + } + if !metav1.IsControlledBy(mapping, access) || mapping.GetDeletionTimestamp() != nil || service != clusterName+"-rw" || port != 5432 || expires != accessExpires { + return apierror.Errorf("relay mapping for PostgresAccess %q is not available", access.GetName()) + } + + tokenSecret, err := getAccessResource(ctx, input.EnvironmentName, namespace, tokenSecretName, schema.GroupVersionResource{Version: "v1", Resource: "secrets"}) + if err != nil { + return err + } + token, err := accessSecretData(tokenSecret, access, "token") + if err != nil { + return err + } + raw, decodeErr := base64.RawURLEncoding.DecodeString(token) + digest, _, err := unstructured.NestedString(mapping.Object, "spec", "tokenSHA256") + if err != nil { + return err + } + if decodeErr != nil || len(raw) != 32 || base64.RawURLEncoding.EncodeToString(raw) != token || !tokenMatchesDigest(raw, digest) { + return apierror.Errorf("relay credentials for PostgresAccess %q are not available", access.GetName()) + } + + // The broker creates short names (postgres-access-), so this is the + // pgrator-owned credential Secret for this access, not a client-supplied name. + credential, err := getAccessResource(ctx, input.EnvironmentName, namespace, access.GetName()+"-credentials", schema.GroupVersionResource{Version: "v1", Resource: "secrets"}) + if err != nil { + return err + } + password, err := accessSecretData(credential, access, corev1.BasicAuthPasswordKey) + if err != nil { + return err + } + username, err := accessSecretData(credential, access, corev1.BasicAuthUsernameKey) + if err != nil { + return err + } + role, _, err := unstructured.NestedString(access.Object, "status", "databaseRole") + if err != nil || role != username { + return apierror.Errorf("credentials for PostgresAccess %q are not available", access.GetName()) + } + + cluster, err := getAccessResource(ctx, input.EnvironmentName, namespace, clusterName, schema.GroupVersionResource{Group: "postgresql.cnpg.io", Version: "v1", Resource: "clusters"}) + if err != nil { + return err + } + serverCA, _, err := unstructured.NestedString(cluster.Object, "spec", "certificates", "serverCASecret") + if err != nil { + return err + } + if serverCA == "" { + serverCA = clusterName + "-ca" // CNPG's default server CA Secret name. + } + caSecret, err := getAccessResource(ctx, input.EnvironmentName, namespace, serverCA, schema.GroupVersionResource{Version: "v1", Resource: "secrets"}) + if err != nil { + return err + } + var ca corev1.Secret + if err := runtime.DefaultUnstructuredConverter.FromUnstructured(caSecret.Object, &ca); err != nil { + return fmt.Errorf("reading server CA for PostgresAccess %q: %w", access.GetName(), err) + } + if len(ca.Data["ca.crt"]) == 0 { + return apierror.Errorf("server CA for PostgresAccess %q is not available", access.GetName()) + } + + connection.Username = username + connection.Password = password + connection.CACertificate = string(ca.Data["ca.crt"]) + connection.ServerName = service + "." + namespace + ".svc.cluster.local" + connection.RelayEndpoint = fmt.Sprintf("https://relay.external.%s.%s.cloud.nais.io:8443", input.EnvironmentName, fromContext(ctx).tenantName) + connection.RelayAccess = namespace + "/" + mapping.GetName() + connection.RelayToken = token + return nil +} + +func tokenMatchesDigest(raw []byte, digest string) bool { + sum := sha256.Sum256(raw) + return hex.EncodeToString(sum[:]) == digest +} + +func accessSecretData(secret, access *unstructured.Unstructured, key string) (string, error) { + if !metav1.IsControlledBy(secret, access) || secret.GetDeletionTimestamp() != nil { + return "", apierror.Errorf("credentials for PostgresAccess %q are not available", access.GetName()) + } + var typed corev1.Secret + if err := runtime.DefaultUnstructuredConverter.FromUnstructured(secret.Object, &typed); err != nil { + return "", fmt.Errorf("reading credentials for PostgresAccess %q: %w", access.GetName(), err) + } + value := string(typed.Data[key]) + if strings.TrimSpace(value) == "" { + return "", apierror.Errorf("credentials for PostgresAccess %q are incomplete", access.GetName()) + } + return value, nil +} + +func getAccessResource(ctx context.Context, environment, namespace, name string, gvr schema.GroupVersionResource) (*unstructured.Unstructured, error) { + client, err := fromContext(ctx).postgresWatcher.SystemAuthenticatedClient(ctx, environment, watcher.WithImpersonatedClientGVR(gvr)) + if err != nil { + return nil, fmt.Errorf("creating %s client: %w", gvr.Resource, err) + } + resource, err := client.Namespace(namespace).Get(ctx, name, metav1.GetOptions{}) + if k8serrors.IsNotFound(err) { + return nil, apierror.Errorf("%s for PostgresAccess is not available", gvr.Resource) + } + if err != nil { + return nil, fmt.Errorf("getting %s for PostgresAccess: %w", gvr.Resource, err) + } + return resource, nil +} diff --git a/internal/persistence/postgres/connection_test.go b/internal/persistence/postgres/connection_test.go new file mode 100644 index 000000000..c919e24d3 --- /dev/null +++ b/internal/persistence/postgres/connection_test.go @@ -0,0 +1,66 @@ +package postgres + +import ( + "crypto/sha256" + "encoding/hex" + "strings" + "testing" + + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/types" +) + +func TestAccessSecretDataRequiresAccessOwnership(t *testing.T) { + access := &unstructured.Unstructured{} + access.SetName("personal-access") + access.SetUID(types.UID("original-access")) + secret := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "personal-access-relay-token", + OwnerReferences: []metav1.OwnerReference{{ + APIVersion: "nais.io/v1", Kind: "PostgresAccess", Name: "personal-access", + UID: types.UID("original-access"), Controller: new(true), + }}, + }, + Data: map[string][]byte{"token": []byte("private-proof")}, + } + check := func() (string, error) { + t.Helper() + obj, err := runtime.DefaultUnstructuredConverter.ToUnstructured(secret) + if err != nil { + t.Fatal(err) + } + return accessSecretData(&unstructured.Unstructured{Object: obj}, access, "token") + } + if got, err := check(); err != nil || got != "private-proof" { + t.Fatalf("owned token = %q, %v", got, err) + } + secret.OwnerReferences[0].UID = types.UID("replaced-access") + if _, err := check(); err == nil || !strings.Contains(err.Error(), "not available") { + t.Fatalf("replaced owner error = %v", err) + } + secret.OwnerReferences[0].UID = access.GetUID() + delete(secret.Data, "token") + if _, err := check(); err == nil || !strings.Contains(err.Error(), "incomplete") { + t.Fatalf("missing token error = %v", err) + } +} + +func TestRelayTokenDigest(t *testing.T) { + raw := make([]byte, 32) + for i := range raw { + raw[i] = byte(i) + } + sum := sha256.Sum256(raw) + if !tokenMatchesDigest(raw, hex.EncodeToString(sum[:])) { + t.Fatal("valid token is not accepted") + } + wrong := append([]byte(nil), raw...) + wrong[0]++ + if tokenMatchesDigest(wrong, hex.EncodeToString(sum[:])) { + t.Fatal("wrong token accepted") + } +} diff --git a/internal/persistence/postgres/dataloader.go b/internal/persistence/postgres/dataloader.go index fa711dcfd..7759e8b55 100644 --- a/internal/persistence/postgres/dataloader.go +++ b/internal/persistence/postgres/dataloader.go @@ -17,25 +17,29 @@ func NewLoaderContext( postgresWatcher *watcher.Watcher[*PostgresInstance], auditLogProjectID string, auditLogLocation string, + tenantName string, ) context.Context { - return context.WithValue(ctx, loadersKey, newLoaders(postgresWatcher, auditLogProjectID, auditLogLocation)) + return context.WithValue(ctx, loadersKey, newLoaders(postgresWatcher, auditLogProjectID, auditLogLocation, tenantName)) } type loaders struct { postgresWatcher *watcher.Watcher[*PostgresInstance] auditLogProjectID string auditLogLocation string + tenantName string } func newLoaders( postgresWatcher *watcher.Watcher[*PostgresInstance], auditLogProjectID string, auditLogLocation string, + tenantName string, ) *loaders { return &loaders{ postgresWatcher: postgresWatcher, auditLogProjectID: auditLogProjectID, auditLogLocation: auditLogLocation, + tenantName: tenantName, } } @@ -47,15 +51,15 @@ func GetAuditLogConfig(ctx context.Context) (projectID, location string) { func NewPostgresWatcher(ctx context.Context, mgr *watcher.Manager) *watcher.Watcher[*PostgresInstance] { w := watcher.Watch(mgr, &PostgresInstance{}, watcher.WithConverter(func(o *unstructured.Unstructured, environmentName string) (obj any, ok bool) { - ret, err := toPostgres(o, environmentName) + ret, err := toPostgresInstance(o, environmentName) if err != nil { return nil, false } return ret, true }), watcher.WithGVR(schema.GroupVersionResource{ - Group: "data.nais.io", + Group: "nais.io", Version: "v1", - Resource: "postgres", + Resource: "postgresinstances", })) w.Start(ctx) return w diff --git a/internal/persistence/postgres/delete_test.go b/internal/persistence/postgres/delete_test.go new file mode 100644 index 000000000..d1104e60b --- /dev/null +++ b/internal/persistence/postgres/delete_test.go @@ -0,0 +1,176 @@ +package postgres + +import ( + "context" + "errors" + "os" + "strings" + "testing" + "time" + + "github.com/nais/api/internal/kubernetes" + "github.com/nais/api/internal/kubernetes/fake" + "github.com/nais/api/internal/kubernetes/watcher" + "github.com/nais/api/internal/slug" + "github.com/nais/api/internal/workload/application" + "github.com/nais/api/internal/workload/job" + "github.com/sirupsen/logrus/hooks/test" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" +) + +func TestDeletePostgresInstanceRequiresInactiveInstance(t *testing.T) { + instance := &unstructured.Unstructured{Object: map[string]any{ + "metadata": map[string]any{"name": "orders-restored"}, + }} + tests := []struct { + name string + postgres map[string]any + wantDenied bool + }{ + {"selected in status", map[string]any{"status": map[string]any{"activeInstance": "orders-restored"}}, true}, + {"selected in spec", map[string]any{"spec": map[string]any{"activeInstance": "orders-restored"}}, true}, + {"pending switch", map[string]any{"spec": map[string]any{"activeInstance": "orders-restored"}, "status": map[string]any{"activeInstance": "orders-original"}}, true}, + {"inactive", map[string]any{"status": map[string]any{"activeInstance": "orders-original"}}, false}, + {"default active", map[string]any{}, true}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + postgres := &unstructured.Unstructured{Object: tt.postgres} + if tt.name == "default active" { + postgres.SetName("orders-restored") + } else { + postgres.SetName("orders") + } + err := ensureInstanceMayBeDeleted(instance, postgres) + if (err != nil) != tt.wantDenied { + t.Errorf("deletion error = %v; denied = %v", err, tt.wantDenied) + } + }) + } +} + +func TestWorkloadUsesMultiplePostgresResources(t *testing.T) { + scheme, err := kubernetes.NewScheme() + if err != nil { + t.Fatal(err) + } + clusters, err := kubernetes.CreateClusterConfigMap("nav", []string{"dev"}, nil) + if err != nil { + t.Fatal(err) + } + log, _ := test.NewNullLogger() + mgr, err := watcher.NewManager(scheme, clusters, log, watcher.WithClientCreator(fake.Clients(os.DirFS("../../../integration_tests/k8s_resources/postgres_workloads")))) + if err != nil { + t.Fatal(err) + } + t.Cleanup(mgr.Stop) + ctx := context.Background() + postgresWatcher := NewPostgresWatcher(ctx, mgr) + appWatcher := application.NewWatcher(ctx, mgr) + jobWatcher := job.NewWatcher(ctx, mgr) + wait, cancel := context.WithTimeout(ctx, 5*time.Second) + defer cancel() + if !mgr.WaitForReady(wait) { + t.Fatal("watchers did not synchronize") + } + ctx = NewLoaderContext(ctx, postgresWatcher, "", "", "nav") + ctx = application.NewLoaderContext(ctx, appWatcher, nil, log) + ctx = job.NewLoaderContext(ctx, jobWatcher, nil) + team := slug.Slug("postgres-workload-team") + apps := application.ListAllForTeamInEnvironment(ctx, team, "dev") + if len(apps) != 1 || apps[0].Spec.Uses == nil { + t.Fatalf("application uses not loaded: %+v", apps) + } + instances, err := ListForWorkload(ctx, team, "dev", apps[0].Spec.Uses.Postgres) + if err != nil || len(instances) != 2 || instances[0].Name != "orders-green" || instances[1].Name != "reports-recovered" { + t.Fatalf("selected instances = %+v, error = %v", instances, err) + } + jobs := job.ListAllForTeamInEnvironment(ctx, team, "dev") + if len(jobs) != 1 || jobs[0].Spec.Uses == nil { + t.Fatalf("job uses not loaded: %+v", jobs) + } + instances, err = ListForWorkload(ctx, team, "dev", jobs[0].Spec.Uses.Postgres) + if err != nil || len(instances) != 2 || instances[0].Name != "orders-green" || instances[1].Name != "reports-recovered" { + t.Fatalf("job selected instances = %+v, error = %v", instances, err) + } + for _, name := range []string{"orders-green", "reports-recovered"} { + workloads := WorkloadsForInstance(ctx, team, "dev", name) + if len(workloads) != 2 || workloads[0].GetName() != "consumer" || workloads[1].GetName() != "scheduled-reader" { + t.Errorf("workloads for %q = %+v", name, workloads) + } + } +} + +func TestReadyPostgresInstanceUsesConcreteName(t *testing.T) { + scheme, err := kubernetes.NewScheme() + if err != nil { + t.Fatal(err) + } + clusters, err := kubernetes.CreateClusterConfigMap("nav", []string{"dev"}, nil) + if err != nil { + t.Fatal(err) + } + log, _ := test.NewNullLogger() + mgr, err := watcher.NewManager(scheme, clusters, log, watcher.WithClientCreator(fake.Clients(os.DirFS("../../../integration_tests/k8s_resources/create_postgres_access")))) + if err != nil { + t.Fatal(err) + } + t.Cleanup(mgr.Stop) + ctx := context.Background() + postgresWatcher := NewPostgresWatcher(ctx, mgr) + wait, cancel := context.WithTimeout(ctx, 5*time.Second) + defer cancel() + if !mgr.WaitForReady(wait) { + t.Fatal("PostgresInstance watcher did not synchronize") + } + ctx = NewLoaderContext(ctx, postgresWatcher, "", "", "nav") + team := slug.Slug("someteamname") + for _, name := range []string{"foobar", "foobar-recovered"} { + instance, err := GetReadyPostgresInstance(ctx, team, "dev", name) + if err != nil || instance.State != PostgresInstanceStateAvailable || instance.Name != name || instance.PostgresName != "foobar" { + t.Errorf("%s: got instance %+v, error %v", name, instance, err) + } + } + instance, err := GetReadyPostgresInstance(ctx, team, "dev", "progressing") + if err != nil || instance.State == PostgresInstanceStateAvailable { + t.Errorf("progressing instance = %+v, error %v", instance, err) + } + _, err = GetReadyPostgresInstance(ctx, team, "dev", "missing") + if !errors.Is(err, &watcher.ErrorNotFound{}) { + t.Errorf("missing instance error = %v", err) + } +} + +func TestCreatePostgresAccessRejectsMissingInstance(t *testing.T) { + scheme, err := kubernetes.NewScheme() + if err != nil { + t.Fatal(err) + } + clusters, err := kubernetes.CreateClusterConfigMap("nav", []string{"dev"}, nil) + if err != nil { + t.Fatal(err) + } + log, _ := test.NewNullLogger() + mgr, err := watcher.NewManager(scheme, clusters, log, watcher.WithClientCreator(fake.Clients(nil))) + if err != nil { + t.Fatal(err) + } + t.Cleanup(mgr.Stop) + ctx := context.Background() + postgresWatcher := NewPostgresWatcher(ctx, mgr) + wait, cancel := context.WithTimeout(ctx, 5*time.Second) + defer cancel() + if !mgr.WaitForReady(wait) { + t.Fatal("PostgresInstance watcher did not synchronize") + } + ctx = NewLoaderContext(ctx, postgresWatcher, "", "", "nav") + input := CreatePostgresAccessInput{ + PostgresInstance: "missing", TeamSlug: slug.Slug("myteam"), + EnvironmentName: "dev", AccessLevel: PostgresAccessLevelRead, + Reason: "Investigating missing instance", + } + err = input.Validate(ctx) + if err == nil || !strings.Contains(err.Error(), `Could not find PostgresInstance named "missing"`) { + t.Errorf("validation error = %v, want named missing instance", err) + } +} diff --git a/internal/persistence/postgres/facets.go b/internal/persistence/postgres/facets.go index 797cad459..6f0eb3b1a 100644 --- a/internal/persistence/postgres/facets.go +++ b/internal/persistence/postgres/facets.go @@ -50,54 +50,6 @@ func (f *PostgresInstanceFacets) States(ctx context.Context) []PostgresInstanceS return states } -// HighAvailability computes high availability facets for a Postgres query. -func (f *PostgresInstanceFacets) HighAvailability(ctx context.Context) []model.BooleanFacetItem { - haCounts := map[bool]int{} - for _, inst := range f.AllInstances { - haCounts[inst.HighAvailability] = 0 - } - - filtered := f.Filtered(ctx) - for _, inst := range filtered { - haCounts[inst.HighAvailability]++ - } - - ha := make([]model.BooleanFacetItem, 0, len(haCounts)) - for val, count := range haCounts { - ha = append(ha, model.BooleanFacetItem{ - Value: val, - Count: count, - }) - } - model.SortBooleanFacetItems(ha) - - return ha -} - -// MajorVersions computes major version facets for a Postgres query. -func (f *PostgresInstanceFacets) MajorVersions(ctx context.Context) []model.StringFacetItem { - versionCounts := map[string]int{} - for _, inst := range f.AllInstances { - versionCounts[inst.MajorVersion] = 0 - } - - filtered := f.Filtered(ctx) - for _, inst := range filtered { - versionCounts[inst.MajorVersion]++ - } - - versions := make([]model.StringFacetItem, 0, len(versionCounts)) - for val, count := range versionCounts { - versions = append(versions, model.StringFacetItem{ - Value: val, - Count: count, - }) - } - model.SortStringFacetItems(versions) - - return versions -} - // Labels computes labels facets for a Postgres query. func (f *PostgresInstanceFacets) Labels(ctx context.Context) []model.LabelFacetItem { filtered := f.Filtered(ctx) diff --git a/internal/persistence/postgres/facets_test.go b/internal/persistence/postgres/facets_test.go index 9859fd851..bff04e2a7 100644 --- a/internal/persistence/postgres/facets_test.go +++ b/internal/persistence/postgres/facets_test.go @@ -6,234 +6,32 @@ import ( "testing" "github.com/nais/api/internal/graph/model" - "github.com/nais/api/internal/slug" ) func TestComputeFacets(t *testing.T) { - boolPtr := func(v bool) *bool { return &v } - - allInstances := []*PostgresInstance{ - { - Name: "app-db-1", - EnvironmentName: "dev", - TeamSlug: slug.Slug("my-team"), - MajorVersion: "15", - HighAvailability: false, - State: PostgresInstanceStateAvailable, - }, - { - Name: "app-db-2", - EnvironmentName: "dev", - TeamSlug: slug.Slug("my-team"), - MajorVersion: "16", - HighAvailability: true, - State: PostgresInstanceStateProgressing, - }, - { - Name: "app-db-3", - EnvironmentName: "prod", - TeamSlug: slug.Slug("my-team"), - MajorVersion: "15", - HighAvailability: true, - State: PostgresInstanceStateAvailable, - }, - { - Name: "app-db-4", - EnvironmentName: "prod", - TeamSlug: slug.Slug("my-team"), - MajorVersion: "17", - HighAvailability: false, - State: PostgresInstanceStateDegraded, - }, + all := []*PostgresInstance{ + {Name: "first", EnvironmentName: "dev", State: PostgresInstanceStateAvailable}, + {Name: "second", EnvironmentName: "dev", State: PostgresInstanceStateProgressing}, + {Name: "third", EnvironmentName: "prod", State: PostgresInstanceStateDegraded}, } - tests := []struct { - name string - instances []*PostgresInstance - filter *PostgresInstanceFilter - wantEnvironments []model.StringFacetItem - wantStates []PostgresInstanceStateFacetItem - wantHA []model.BooleanFacetItem - wantMajorVersions []model.StringFacetItem + name string + filter *PostgresInstanceFilter + wantEnvironments []model.StringFacetItem + wantStates []PostgresInstanceStateFacetItem }{ - { - name: "no filter counts all instances", - instances: allInstances, - filter: nil, - wantEnvironments: []model.StringFacetItem{ - {Value: "dev", Count: 2}, - {Value: "prod", Count: 2}, - }, - wantStates: []PostgresInstanceStateFacetItem{ - {State: PostgresInstanceStateAvailable, Count: 2}, - {State: PostgresInstanceStateDegraded, Count: 1}, - {State: PostgresInstanceStateProgressing, Count: 1}, - }, - wantHA: []model.BooleanFacetItem{ - {Value: false, Count: 2}, - {Value: true, Count: 2}, - }, - wantMajorVersions: []model.StringFacetItem{ - {Value: "15", Count: 2}, - {Value: "16", Count: 1}, - {Value: "17", Count: 1}, - }, - }, - { - name: "filter by environment counts only matching but seeds all", - instances: allInstances, - filter: &PostgresInstanceFilter{Environments: []string{"dev"}}, - wantEnvironments: []model.StringFacetItem{ - {Value: "dev", Count: 2}, - {Value: "prod", Count: 0}, - }, - wantStates: []PostgresInstanceStateFacetItem{ - {State: PostgresInstanceStateAvailable, Count: 1}, - {State: PostgresInstanceStateDegraded, Count: 0}, - {State: PostgresInstanceStateProgressing, Count: 1}, - }, - wantHA: []model.BooleanFacetItem{ - {Value: false, Count: 1}, - {Value: true, Count: 1}, - }, - wantMajorVersions: []model.StringFacetItem{ - {Value: "15", Count: 1}, - {Value: "16", Count: 1}, - {Value: "17", Count: 0}, - }, - }, - { - name: "filter by state counts only matching state", - instances: allInstances, - filter: &PostgresInstanceFilter{States: []PostgresInstanceState{PostgresInstanceStateAvailable}}, - wantEnvironments: []model.StringFacetItem{ - {Value: "dev", Count: 1}, - {Value: "prod", Count: 1}, - }, - wantStates: []PostgresInstanceStateFacetItem{ - {State: PostgresInstanceStateAvailable, Count: 2}, - {State: PostgresInstanceStateDegraded, Count: 0}, - {State: PostgresInstanceStateProgressing, Count: 0}, - }, - wantHA: []model.BooleanFacetItem{ - {Value: false, Count: 1}, - {Value: true, Count: 1}, - }, - wantMajorVersions: []model.StringFacetItem{ - {Value: "15", Count: 2}, - {Value: "16", Count: 0}, - {Value: "17", Count: 0}, - }, - }, - { - name: "filter by high availability", - instances: allInstances, - filter: &PostgresInstanceFilter{HighAvailability: boolPtr(true)}, - wantEnvironments: []model.StringFacetItem{ - {Value: "dev", Count: 1}, - {Value: "prod", Count: 1}, - }, - wantStates: []PostgresInstanceStateFacetItem{ - {State: PostgresInstanceStateAvailable, Count: 1}, - {State: PostgresInstanceStateDegraded, Count: 0}, - {State: PostgresInstanceStateProgressing, Count: 1}, - }, - wantHA: []model.BooleanFacetItem{ - {Value: false, Count: 0}, - {Value: true, Count: 2}, - }, - wantMajorVersions: []model.StringFacetItem{ - {Value: "15", Count: 1}, - {Value: "16", Count: 1}, - {Value: "17", Count: 0}, - }, - }, - { - name: "filter by major version", - instances: allInstances, - filter: &PostgresInstanceFilter{MajorVersions: []string{"15"}}, - wantEnvironments: []model.StringFacetItem{ - {Value: "dev", Count: 1}, - {Value: "prod", Count: 1}, - }, - wantStates: []PostgresInstanceStateFacetItem{ - {State: PostgresInstanceStateAvailable, Count: 2}, - {State: PostgresInstanceStateDegraded, Count: 0}, - {State: PostgresInstanceStateProgressing, Count: 0}, - }, - wantHA: []model.BooleanFacetItem{ - {Value: false, Count: 1}, - {Value: true, Count: 1}, - }, - wantMajorVersions: []model.StringFacetItem{ - {Value: "15", Count: 2}, - {Value: "16", Count: 0}, - {Value: "17", Count: 0}, - }, - }, - { - name: "combined filter environment and state", - instances: allInstances, - filter: &PostgresInstanceFilter{ - Environments: []string{"prod"}, - States: []PostgresInstanceState{PostgresInstanceStateAvailable}, - }, - wantEnvironments: []model.StringFacetItem{ - {Value: "dev", Count: 0}, - {Value: "prod", Count: 1}, - }, - wantStates: []PostgresInstanceStateFacetItem{ - {State: PostgresInstanceStateAvailable, Count: 1}, - {State: PostgresInstanceStateDegraded, Count: 0}, - {State: PostgresInstanceStateProgressing, Count: 0}, - }, - wantHA: []model.BooleanFacetItem{ - {Value: false, Count: 0}, - {Value: true, Count: 1}, - }, - wantMajorVersions: []model.StringFacetItem{ - {Value: "15", Count: 1}, - {Value: "16", Count: 0}, - {Value: "17", Count: 0}, - }, - }, - { - name: "empty input returns empty facets", - instances: nil, - filter: nil, - wantEnvironments: []model.StringFacetItem{}, - wantStates: []PostgresInstanceStateFacetItem{}, - wantHA: []model.BooleanFacetItem{}, - wantMajorVersions: []model.StringFacetItem{}, - }, + {"all", nil, []model.StringFacetItem{{Value: "dev", Count: 2}, {Value: "prod", Count: 1}}, []PostgresInstanceStateFacetItem{{State: PostgresInstanceStateAvailable, Count: 1}, {State: PostgresInstanceStateDegraded, Count: 1}, {State: PostgresInstanceStateProgressing, Count: 1}}}, + {"filter by environment", &PostgresInstanceFilter{Environments: []string{"dev"}}, []model.StringFacetItem{{Value: "dev", Count: 2}, {Value: "prod", Count: 0}}, []PostgresInstanceStateFacetItem{{State: PostgresInstanceStateAvailable, Count: 1}, {State: PostgresInstanceStateDegraded, Count: 0}, {State: PostgresInstanceStateProgressing, Count: 1}}}, + {"filter by state", &PostgresInstanceFilter{States: []PostgresInstanceState{PostgresInstanceStateAvailable}}, []model.StringFacetItem{{Value: "dev", Count: 1}, {Value: "prod", Count: 0}}, []PostgresInstanceStateFacetItem{{State: PostgresInstanceStateAvailable, Count: 1}, {State: PostgresInstanceStateDegraded, Count: 0}, {State: PostgresInstanceStateProgressing, Count: 0}}}, } - for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - ctx := context.Background() - got := &PostgresInstanceFacets{ - AllInstances: tt.instances, - Filter: tt.filter, - } - - gotEnvironments := got.Environments(ctx) - if !reflect.DeepEqual(gotEnvironments, tt.wantEnvironments) { - t.Errorf("Environments =\n %v\nwant\n %v", gotEnvironments, tt.wantEnvironments) + f := &PostgresInstanceFacets{AllInstances: all, Filter: tt.filter} + if got := f.Environments(context.Background()); !reflect.DeepEqual(got, tt.wantEnvironments) { + t.Errorf("environments=%v want %v", got, tt.wantEnvironments) } - - gotStates := got.States(ctx) - if !reflect.DeepEqual(gotStates, tt.wantStates) { - t.Errorf("States =\n %v\nwant\n %v", gotStates, tt.wantStates) - } - - gotHA := got.HighAvailability(ctx) - if !reflect.DeepEqual(gotHA, tt.wantHA) { - t.Errorf("HighAvailability =\n %v\nwant\n %v", gotHA, tt.wantHA) - } - - gotVersions := got.MajorVersions(ctx) - if !reflect.DeepEqual(gotVersions, tt.wantMajorVersions) { - t.Errorf("MajorVersions =\n %v\nwant\n %v", gotVersions, tt.wantMajorVersions) + if got := f.States(context.Background()); !reflect.DeepEqual(got, tt.wantStates) { + t.Errorf("states=%v want %v", got, tt.wantStates) } }) } diff --git a/internal/persistence/postgres/models.go b/internal/persistence/postgres/models.go index 0870fd8b5..bd6cbe86b 100644 --- a/internal/persistence/postgres/models.go +++ b/internal/persistence/postgres/models.go @@ -17,9 +17,9 @@ import ( "github.com/nais/api/internal/kubernetes/watcher" "github.com/nais/api/internal/slug" "github.com/nais/api/internal/validate" - "github.com/nais/api/internal/workload" - data_nais_io_v1 "github.com/nais/pgrator/pkg/api/datav1" - "k8s.io/apimachinery/pkg/api/meta" + nais_io_v1 "github.com/nais/pgrator/pkg/api/v1" + k8serrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime" @@ -29,12 +29,10 @@ import ( type PostgresInstanceEdge = pagination.Edge[*PostgresInstance] type PostgresInstanceFilter struct { - Name string `json:"name"` - Environments []string `json:"environments"` - States []PostgresInstanceState `json:"states"` - HighAvailability *bool `json:"highAvailability"` - MajorVersions []string `json:"majorVersions"` - Labels model.LabelFilters `json:"labels,omitempty"` + Name string `json:"name"` + Environments []string `json:"environments"` + States []PostgresInstanceState `json:"states"` + Labels model.LabelFilters `json:"labels,omitempty"` } type PostgresInstanceConnection = pagination.FacetableConnection[*PostgresInstance, *PostgresInstanceFilter] @@ -51,30 +49,44 @@ type PostgresInstanceStateFacetItem struct { Count int `json:"count"` } +// PostgresInstance represents an independently running database instance. type PostgresInstance struct { - Name string `json:"name"` - EnvironmentName string `json:"-"` - WorkloadReference *workload.Reference `json:"-"` - TeamSlug slug.Slug `json:"-"` - Resources *PostgresInstanceResources `json:"resources"` - MajorVersion string `json:"majorVersion"` - Audit PostgresInstanceAudit `json:"audit"` - MaintenanceWindow *PostgresInstanceMaintenanceWindow `json:"maintenanceWindow,omitempty"` - HighAvailability bool `json:"highAvailability"` - State PostgresInstanceState `json:"state"` - Labels []*model.ResourceLabel `json:"labels"` + Name string `json:"name"` + EnvironmentName string `json:"-"` + TeamSlug slug.Slug `json:"-"` + PostgresName string `json:"postgres"` + State PostgresInstanceState `json:"state"` + Labels []*model.ResourceLabel `json:"labels"` } +// Postgres selects the instance that workloads use. +type Postgres struct { + Name string `json:"name"` + EnvironmentName string `json:"-"` + TeamSlug slug.Slug `json:"-"` + ActiveInstance *string `json:"activeInstance,omitempty"` + MajorVersion string `json:"majorVersion"` + HighAvailability bool `json:"highAvailability"` + Resources PostgresResources `json:"resources"` + Labels []*model.ResourceLabel `json:"labels"` +} + +// PostgresResources contains only resource requests observed on the Postgres CR. +type PostgresResources struct { + CPU *string `json:"cpu,omitempty"` + Memory *string `json:"memory,omitempty"` + DiskSize *string `json:"diskSize,omitempty"` +} + +func (Postgres) IsNode() {} +func (p *Postgres) ID() ident.Ident { return newPostgresIdent(p.TeamSlug, p.EnvironmentName, p.Name) } + type PostgresInstanceState string const ( PostgresInstanceStateAvailable PostgresInstanceState = "AVAILABLE" PostgresInstanceStateProgressing PostgresInstanceState = "PROGRESSING" PostgresInstanceStateDegraded PostgresInstanceState = "DEGRADED" - - postgresConditionTypeAvailable = "Available" - postgresConditionTypeProgressing = "Progressing" - postgresConditionTypeDegraded = "Degraded" ) var AllPostgresInstanceState = []PostgresInstanceState{ @@ -126,31 +138,12 @@ func (e PostgresInstanceState) MarshalJSON() ([]byte, error) { return buf.Bytes(), nil } -type PostgresInstanceAudit struct { - Enabled bool `json:"enabled"` - StatementClasses []string `json:"statementClasses,omitempty"` - TeamSlug slug.Slug `json:"-"` - EnvironmentName string `json:"-"` - InstanceName string `json:"-"` -} - -type PostgresInstanceMaintenanceWindow struct { - Day int `json:"day"` - Hour int `json:"hour"` -} - func (PostgresInstance) IsPersistence() {} func (PostgresInstance) IsNode() {} func (PostgresInstance) IsSearchNode() {} -type PostgresInstanceResources struct { - CPU string `json:"cpu"` - Memory string `json:"memory"` - DiskSize string `json:"diskSize"` -} - type DeletePostgresInput struct { Name string `json:"name"` EnvironmentName string `json:"environmentName"` @@ -183,69 +176,15 @@ type DeletePostgresPayload struct { PostgresDeleted *bool `json:"postgresDeleted,omitempty"` } -type GrantPostgresAccessInput struct { - ClusterName string `json:"clusterName"` - TeamSlug slug.Slug `json:"teamSlug"` - EnvironmentName string `json:"environmentName"` - Grantee string `json:"grantee"` - Duration string `json:"duration"` -} - -func (i *GrantPostgresAccessInput) Validate(ctx context.Context) error { - return i.ValidationErrors(ctx).NilIfEmpty() -} - -func (i *GrantPostgresAccessInput) ValidationErrors(ctx context.Context) *validate.ValidationErrors { - verr := validate.New() - i.ClusterName = strings.TrimSpace(i.ClusterName) - i.EnvironmentName = strings.TrimSpace(i.EnvironmentName) - - if i.ClusterName == "" { - verr.Add("clusterName", "ClusterName must not be empty.") - } - if i.EnvironmentName == "" { - verr.Add("environmentName", "Environment name must not be empty.") - } - if i.TeamSlug == "" { - verr.Add("teamSlug", "Team slug must not be empty.") - } - if i.Grantee == "" { - verr.Add("grantee", "Grantee must not be empty.") - } - - duration, err := time.ParseDuration(i.Duration) - if err != nil { - verr.Add("duration", "%s", err) - } else if duration > 4*time.Hour { - verr.Add("duration", "Duration \"%s\" is out-of-bounds. Must be less than 4 hours.", i.Duration) - } - - _, err = GetPostgres(ctx, i.TeamSlug, i.EnvironmentName, i.ClusterName) - if err != nil { - if errors.Is(err, &watcher.ErrorNotFound{}) { - verr.Add("clusterName", "Could not find postgres cluster named \"%s\"", i.ClusterName) - } else { - verr.Add("clusterName", "%s", err) - } - } - - return verr -} - -type GrantPostgresAccessPayload struct { - Error *string `json:"error,omitempty"` -} - // CreatePostgresAccessInput requests a new, time-limited personal database access. // The authenticated actor and final expiry are server-controlled. type CreatePostgresAccessInput struct { - PostgresInstance string `json:"postgresInstance"` - TeamSlug slug.Slug `json:"teamSlug"` - EnvironmentName string `json:"environmentName"` - AccessLevel PostgresAccessLevel `json:"accessLevel"` - ClientWireGuardPublicKey string `json:"clientWireGuardPublicKey"` - Reason string `json:"reason"` - TTL string `json:"ttl"` + PostgresInstance string `json:"postgresInstance"` + TeamSlug slug.Slug `json:"teamSlug"` + EnvironmentName string `json:"environmentName"` + AccessLevel PostgresAccessLevel `json:"accessLevel"` + Reason string `json:"reason"` + TTL string `json:"ttl"` } func (i *CreatePostgresAccessInput) Validate(ctx context.Context) error { @@ -256,7 +195,6 @@ func (i *CreatePostgresAccessInput) ValidationErrors(ctx context.Context) *valid verr := validate.New() i.PostgresInstance = strings.TrimSpace(i.PostgresInstance) i.EnvironmentName = strings.TrimSpace(i.EnvironmentName) - i.ClientWireGuardPublicKey = strings.TrimSpace(i.ClientWireGuardPublicKey) i.Reason = strings.TrimSpace(i.Reason) i.TTL = strings.TrimSpace(i.TTL) @@ -272,9 +210,6 @@ func (i *CreatePostgresAccessInput) ValidationErrors(ctx context.Context) *valid if !i.AccessLevel.IsValid() { verr.Add("accessLevel", "Access level %q is not valid.", i.AccessLevel) } - if i.ClientWireGuardPublicKey == "" { - verr.Add("clientWireGuardPublicKey", "Client WireGuard public key must not be empty.") - } if len(i.Reason) < 10 { verr.Add("reason", "Reason must be at least 10 characters.") } @@ -286,10 +221,10 @@ func (i *CreatePostgresAccessInput) ValidationErrors(ctx context.Context) *valid return verr } - instance, err := GetPostgres(ctx, i.TeamSlug, i.EnvironmentName, i.PostgresInstance) + instance, err := GetReadyPostgresInstance(ctx, i.TeamSlug, i.EnvironmentName, i.PostgresInstance) if err != nil { - if errors.Is(err, &watcher.ErrorNotFound{}) { - verr.Add("postgresInstance", "Could not find postgres cluster named %q", i.PostgresInstance) + if k8serrors.IsNotFound(err) || errors.Is(err, &watcher.ErrorNotFound{}) { + verr.Add("postgresInstance", "Could not find PostgresInstance named %q", i.PostgresInstance) } else { verr.Add("postgresInstance", "%s", err) } @@ -365,77 +300,73 @@ func (p *PostgresInstance) ID() ident.Ident { return newIdent(p.TeamSlug, p.EnvironmentName, p.Name) } -func toPostgres(u *unstructured.Unstructured, environmentName string) (*PostgresInstance, error) { - obj := &data_nais_io_v1.Postgres{} - +func toPostgresInstance(u *unstructured.Unstructured, environmentName string) (*PostgresInstance, error) { + obj := &nais_io_v1.PostgresInstance{} if err := runtime.DefaultUnstructuredConverter.FromUnstructured(u.Object, obj); err != nil { - return nil, fmt.Errorf("converting to Postgres: %w", err) - } - - audit := false - statementClasses := []string(nil) - if obj.Spec.Cluster.Audit != nil { - audit = obj.Spec.Cluster.Audit.Enabled - if len(obj.Spec.Cluster.Audit.StatementClasses) > 0 { - statementClasses = make([]string, 0, len(obj.Spec.Cluster.Audit.StatementClasses)) - for _, statementClass := range obj.Spec.Cluster.Audit.StatementClasses { - statementClasses = append(statementClasses, string(statementClass)) - } - } + return nil, fmt.Errorf("converting PostgresInstance: %w", err) } - - state := PostgresInstanceStateAvailable + if obj.Spec.Postgres == "" { + return nil, fmt.Errorf("PostgresInstance %q has no Postgres", obj.Name) + } + state := PostgresInstanceStateProgressing if obj.Status != nil { - state = postgresStateFromConditions(obj.Status.Conditions) - } - - return &PostgresInstance{ - Name: obj.GetName(), - EnvironmentName: environmentName, - TeamSlug: slug.Slug(obj.GetNamespace()), - WorkloadReference: workload.ReferenceFromOwnerReferences(obj.GetOwnerReferences()), - Resources: &PostgresInstanceResources{ - CPU: obj.Spec.Cluster.Resources.Cpu.String(), - Memory: obj.Spec.Cluster.Resources.Memory.String(), - DiskSize: obj.Spec.Cluster.Resources.DiskSize.String(), - }, - MajorVersion: obj.Spec.Cluster.MajorVersion, - Audit: PostgresInstanceAudit{ - Enabled: audit, - StatementClasses: statementClasses, - TeamSlug: slug.Slug(obj.GetNamespace()), - EnvironmentName: environmentName, - InstanceName: obj.GetName(), - }, - HighAvailability: obj.Spec.Cluster.HighAvailability, - MaintenanceWindow: func() *PostgresInstanceMaintenanceWindow { - if obj.Spec.MaintenanceWindow == nil { - return nil - } - hour := 0 - if obj.Spec.MaintenanceWindow.Hour != nil { - hour = *obj.Spec.MaintenanceWindow.Hour - } - return &PostgresInstanceMaintenanceWindow{ - Day: obj.Spec.MaintenanceWindow.Day, - Hour: hour, - } - }(), - State: state, - Labels: model.UserLabels(obj.GetLabels()), - }, nil + state = postgresStateFromConditions(obj.Status.Conditions, obj.Status.ReconcilePhase == "Completed" && obj.Status.ObservedGeneration >= obj.Generation) + } + return &PostgresInstance{Name: obj.Name, EnvironmentName: environmentName, TeamSlug: slug.Slug(obj.Namespace), PostgresName: obj.Spec.Postgres, State: state, Labels: model.UserLabels(obj.Labels)}, nil } -func postgresStateFromConditions(conditions []metav1.Condition) PostgresInstanceState { - if meta.IsStatusConditionTrue(conditions, postgresConditionTypeDegraded) { - return PostgresInstanceStateDegraded +func toPostgres(u *unstructured.Unstructured, environmentName string) (*Postgres, error) { + obj := &nais_io_v1.Postgres{} + if err := runtime.DefaultUnstructuredConverter.FromUnstructured(u.Object, obj); err != nil { + return nil, fmt.Errorf("converting Postgres: %w", err) } + var active *string + if obj.Status != nil && obj.Status.ActiveInstance != "" { + active = &obj.Status.ActiveInstance + } + quantity := func(value resource.Quantity) *string { + if value.IsZero() { + return nil + } + text := value.String() + return &text + } + return &Postgres{ + Name: obj.Name, EnvironmentName: environmentName, TeamSlug: slug.Slug(obj.Namespace), + ActiveInstance: active, MajorVersion: obj.Spec.MajorVersion, HighAvailability: obj.Spec.HighAvailability, + Resources: PostgresResources{ + CPU: quantity(obj.Spec.Resources.Cpu), Memory: quantity(obj.Spec.Resources.Memory), + DiskSize: quantity(obj.Spec.Resources.DiskSize), + }, + Labels: model.UserLabels(obj.Labels), + }, nil +} - if meta.IsStatusConditionTrue(conditions, postgresConditionTypeProgressing) { +// postgresStateFromConditions interprets the CNPG phase mirrored by pgrator. +// ObservedState=False means no phase has been observed, not a failed cluster. +func postgresStateFromConditions(conditions []metav1.Condition, reconciled bool) PostgresInstanceState { + if !reconciled { return PostgresInstanceStateProgressing } - - return PostgresInstanceStateAvailable + for _, condition := range conditions { + if condition.Type != "cluster.postgresql.cnpg.io/ObservedState" || condition.Status != metav1.ConditionTrue { + continue + } + phase, ok := strings.CutPrefix(condition.Message, "Cluster is in phase: ") + if !ok { + continue + } + switch phase { + case "Cluster in healthy state": + return PostgresInstanceStateAvailable + case "Cluster is unrecoverable and needs manual intervention", + "Cluster cannot proceed to reconciliation due to an unknown plugin being required", + "Cluster cannot proceed to reconciliation due to an error while interacting with plugins", + "Cluster has incomplete or invalid image catalog": + return PostgresInstanceStateDegraded + } + } + return PostgresInstanceStateProgressing } type PostgresInstanceOrder struct { @@ -506,16 +437,16 @@ type TeamInventoryCountPostgresInstances struct { // database access. Credentials are read from the controller-owned Secret on // demand; they are never cached by the watcher. type PostgresAccess struct { - Name string `json:"name"` - TeamSlug slug.Slug `json:"-"` - EnvironmentName string `json:"-"` - PostgresInstanceName string `json:"postgresInstance"` - Username string `json:"username"` - AccessLevel PostgresAccessLevel `json:"accessLevel"` - ExpiresAt time.Time `json:"expiresAt"` - State PostgresAccessState `json:"state"` - Message *string `json:"message,omitempty"` - Tunnel *PostgresAccessTunnel `json:"tunnel,omitempty"` + Name string `json:"name"` + TeamSlug slug.Slug `json:"-"` + EnvironmentName string `json:"-"` + PostgresInstanceName string `json:"postgresInstance"` + Username string `json:"username"` + AccessLevel PostgresAccessLevel `json:"accessLevel"` + ExpiresAt time.Time `json:"expiresAt"` + State PostgresAccessState `json:"state"` + Message *string `json:"message,omitempty"` + RelayAccess *string `json:"relayAccess,omitempty"` } func (PostgresAccess) IsNode() {} @@ -583,12 +514,6 @@ func (e PostgresAccessState) MarshalJSON() ([]byte, error) { return buf.Bytes(), nil } -type PostgresAccessTunnel struct { - Name string `json:"name"` - Endpoint *string `json:"endpoint,omitempty"` - GatewayPublicKey *string `json:"gatewayPublicKey,omitempty"` -} - type PostgresAccessConnectionInput struct { Name string `json:"name"` TeamSlug slug.Slug `json:"teamSlug"` @@ -616,13 +541,11 @@ func (i *PostgresAccessConnectionInput) ValidationErrors(_ context.Context) *val } type PostgresAccessConnection struct { - Password string `json:"password"` - CACertificate string `json:"caCertificate"` - ServerName string `json:"serverName"` - Tunnel PostgresAccessConnectionTunnel `json:"tunnel"` -} - -type PostgresAccessConnectionTunnel struct { - Endpoint string `json:"endpoint"` - GatewayPublicKey string `json:"gatewayPublicKey"` + Username string `json:"username"` + Password string `json:"password"` + CACertificate string `json:"caCertificate"` + ServerName string `json:"serverName"` + RelayEndpoint string `json:"relayEndpoint"` + RelayAccess string `json:"relayAccess"` + RelayToken string `json:"relayToken"` } diff --git a/internal/persistence/postgres/models_test.go b/internal/persistence/postgres/models_test.go index 91e046c71..43bd76580 100644 --- a/internal/persistence/postgres/models_test.go +++ b/internal/persistence/postgres/models_test.go @@ -6,236 +6,69 @@ import ( "testing" "github.com/nais/api/internal/slug" - data_nais_io_v1 "github.com/nais/pgrator/pkg/api/datav1" - "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime" ) -func TestPostgresStateFromConditions(t *testing.T) { - tests := []struct { - name string - conditions []metav1.Condition - want PostgresInstanceState - }{ - { - name: "degraded when degraded is true", - conditions: []metav1.Condition{ - {Type: postgresConditionTypeAvailable, Status: metav1.ConditionTrue}, - {Type: postgresConditionTypeDegraded, Status: metav1.ConditionTrue}, - }, - want: PostgresInstanceStateDegraded, - }, - { - name: "progressing when progressing is true", - conditions: []metav1.Condition{ - {Type: postgresConditionTypeProgressing, Status: metav1.ConditionTrue}, - }, - want: PostgresInstanceStateProgressing, - }, - { - name: "available when available is true", - conditions: []metav1.Condition{ - {Type: postgresConditionTypeAvailable, Status: metav1.ConditionTrue}, - }, - want: PostgresInstanceStateAvailable, - }, - { - name: "available when no recognized true condition", - conditions: []metav1.Condition{ - {Type: postgresConditionTypeAvailable, Status: metav1.ConditionFalse}, - {Type: postgresConditionTypeProgressing, Status: metav1.ConditionFalse}, - }, - want: PostgresInstanceStateAvailable, - }, - { - name: "available when no conditions", - want: PostgresInstanceStateAvailable, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - got := postgresStateFromConditions(tt.conditions) - if got != tt.want { - t.Errorf("postgresStateFromConditions() = %q, want %q", got, tt.want) - } - }) - } -} - -func TestToPostgres_MaintenanceWindow(t *testing.T) { - intPtr := func(v int) *int { return &v } - - tests := []struct { - name string - maintenance *data_nais_io_v1.Maintenance - wantNil bool - wantDay int - wantHour int - }{ - { - name: "populates day and hour when maintenance window is present", - maintenance: &data_nais_io_v1.Maintenance{ - Day: 2, - Hour: intPtr(5), - }, - wantDay: 2, - wantHour: 5, - }, - { - name: "defaults hour to 0 when maintenance window hour is omitted", - maintenance: &data_nais_io_v1.Maintenance{ - Day: 6, - }, - wantDay: 6, - wantHour: 0, - }, - { - name: "returns nil maintenance window when not configured", - wantNil: true, - }, - } - - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - obj := newPostgresTestObject(tt.maintenance, nil) - got := toPostgresFromCRD(t, obj) - - if tt.wantNil { - if got.MaintenanceWindow != nil { - t.Fatalf("MaintenanceWindow = %#v, want nil", got.MaintenanceWindow) - } - return - } - - if got.MaintenanceWindow == nil { - t.Fatalf("MaintenanceWindow = nil, want non-nil") - } - - if got.MaintenanceWindow.Day != tt.wantDay { - t.Errorf("MaintenanceWindow.Day = %d, want %d", got.MaintenanceWindow.Day, tt.wantDay) - } - - if got.MaintenanceWindow.Hour != tt.wantHour { - t.Errorf("MaintenanceWindow.Hour = %d, want %d", got.MaintenanceWindow.Hour, tt.wantHour) - } - }) - } -} - -func TestToPostgres_MaintenanceWindow_WithConditions(t *testing.T) { - hour := 7 - obj := newPostgresTestObject(&data_nais_io_v1.Maintenance{ - Day: 3, - Hour: &hour, - }, []metav1.Condition{ - {Type: postgresConditionTypeAvailable, Status: metav1.ConditionTrue}, - {Type: postgresConditionTypeDegraded, Status: metav1.ConditionTrue}, - }) - - got := toPostgresFromCRD(t, obj) - - if got.MaintenanceWindow == nil { - t.Fatalf("MaintenanceWindow = nil, want non-nil") - } - - if got.MaintenanceWindow.Day != 3 { - t.Errorf("MaintenanceWindow.Day = %d, want %d", got.MaintenanceWindow.Day, 3) +func TestToPostgresInstance(t *testing.T) { + obj := &unstructured.Unstructured{Object: map[string]any{ + "apiVersion": "nais.io/v1", "kind": "PostgresInstance", + "metadata": map[string]any{"name": "orders-restored", "namespace": "my-team"}, + "spec": map[string]any{"postgres": "orders"}, + "status": map[string]any{"reconcilePhase": "Completed", "conditions": []any{map[string]any{"type": "cluster.postgresql.cnpg.io/ObservedState", "status": "True", "lastTransitionTime": "2026-01-01T00:00:00Z", "reason": "Reconciled", "message": "Cluster is in phase: Cluster in healthy state"}}}, + }} + got, err := toPostgresInstance(obj, "dev") + if err != nil { + t.Fatal(err) } - - if got.MaintenanceWindow.Hour != 7 { - t.Errorf("MaintenanceWindow.Hour = %d, want %d", got.MaintenanceWindow.Hour, 7) - } - - if got.State != PostgresInstanceStateDegraded { - t.Errorf("State = %q, want %q", got.State, PostgresInstanceStateDegraded) + if got.Name != "orders-restored" || got.PostgresName != "orders" || got.State != PostgresInstanceStateAvailable { + t.Errorf("unexpected physical instance: %+v", got) } } -func TestToPostgres_AuditStatementClasses(t *testing.T) { - obj := newPostgresTestObject(nil, nil) - obj.Spec.Cluster.Audit = &data_nais_io_v1.PostgresAudit{ - Enabled: true, - StatementClasses: []data_nais_io_v1.PostgresAuditStatementClass{ - "ddl", - "write", - }, +func TestToLogicalPostgres(t *testing.T) { + obj := &unstructured.Unstructured{Object: map[string]any{ + "apiVersion": "nais.io/v1", "kind": "Postgres", + "metadata": map[string]any{"name": "orders", "namespace": "my-team"}, + "spec": map[string]any{"majorVersion": "17", "highAvailability": true, "resources": map[string]any{"cpu": "100m", "memory": "2Gi", "diskSize": "10Gi"}}, + "status": map[string]any{"activeInstance": "orders-restored"}, + }} + got, err := toPostgres(obj, "dev") + if err != nil { + t.Fatal(err) } - - got := toPostgresFromCRD(t, obj) - - if !got.Audit.Enabled { - t.Fatalf("Audit.Enabled = %v, want true", got.Audit.Enabled) + if got.Name != "orders" || got.MajorVersion != "17" || got.ActiveInstance == nil || *got.ActiveInstance != "orders-restored" { + t.Errorf("unexpected Postgres: %+v", got) } - - want := []string{"ddl", "write"} - if !reflect.DeepEqual(got.Audit.StatementClasses, want) { - t.Errorf("Audit.StatementClasses = %#v, want %#v", got.Audit.StatementClasses, want) + if got.Resources.CPU == nil || *got.Resources.CPU != "100m" || got.Resources.Memory == nil || *got.Resources.Memory != "2Gi" || got.Resources.DiskSize == nil || *got.Resources.DiskSize != "10Gi" { + t.Errorf("unexpected Postgres resources: %+v", got.Resources) } } -func TestToPostgres_AuditStatementClasses_EmptyWhenAuditMissingOrEmpty(t *testing.T) { +func TestPostgresStateFromConditions(t *testing.T) { tests := []struct { - name string - audit *data_nais_io_v1.PostgresAudit + name string + reconciled bool + conditions []metav1.Condition + want PostgresInstanceState }{ - { - name: "missing audit config", - audit: nil, - }, - { - name: "empty audit config", - audit: &data_nais_io_v1.PostgresAudit{}, - }, + {name: "not reconciled", want: PostgresInstanceStateProgressing}, + {name: "healthy", reconciled: true, conditions: []metav1.Condition{{Type: "cluster.postgresql.cnpg.io/ObservedState", Status: metav1.ConditionTrue, Message: "Cluster is in phase: Cluster in healthy state"}}, want: PostgresInstanceStateAvailable}, + {name: "still starting", reconciled: true, conditions: []metav1.Condition{{Type: "cluster.postgresql.cnpg.io/ObservedState", Status: metav1.ConditionFalse, Message: "Cluster is in phase: "}}, want: PostgresInstanceStateProgressing}, + {name: "unrecoverable", reconciled: true, conditions: []metav1.Condition{{Type: "cluster.postgresql.cnpg.io/ObservedState", Status: metav1.ConditionTrue, Message: "Cluster is in phase: Cluster is unrecoverable and needs manual intervention"}}, want: PostgresInstanceStateDegraded}, + {name: "plugin failure", reconciled: true, conditions: []metav1.Condition{{Type: "cluster.postgresql.cnpg.io/ObservedState", Status: metav1.ConditionTrue, Message: "Cluster is in phase: Cluster cannot proceed to reconciliation due to an error while interacting with plugins"}}, want: PostgresInstanceStateDegraded}, + {name: "other phase", reconciled: true, conditions: []metav1.Condition{{Type: "cluster.postgresql.cnpg.io/ObservedState", Status: metav1.ConditionTrue, Message: "Cluster is in phase: Online upgrade in progress"}}, want: PostgresInstanceStateProgressing}, + {name: "missing", reconciled: true, want: PostgresInstanceStateProgressing}, } - for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - obj := newPostgresTestObject(nil, nil) - obj.Spec.Cluster.Audit = tt.audit - - got := toPostgresFromCRD(t, obj) - - if got.Audit.Enabled { - t.Errorf("Audit.Enabled = %v, want false", got.Audit.Enabled) - } - - if len(got.Audit.StatementClasses) != 0 { - t.Errorf("Audit.StatementClasses = %#v, want empty", got.Audit.StatementClasses) + if got := postgresStateFromConditions(tt.conditions, tt.reconciled); got != tt.want { + t.Errorf("state = %s, want %s", got, tt.want) } }) } } -func newPostgresTestObject(maintenance *data_nais_io_v1.Maintenance, conditions []metav1.Condition) *data_nais_io_v1.Postgres { - obj := &data_nais_io_v1.Postgres{ - ObjectMeta: metav1.ObjectMeta{ - Name: "my-db", - Namespace: "my-team", - }, - Spec: data_nais_io_v1.PostgresSpec{ - Cluster: data_nais_io_v1.PostgresCluster{ - Resources: data_nais_io_v1.PostgresResources{ - DiskSize: resource.MustParse("10Gi"), - Cpu: resource.MustParse("100m"), - Memory: resource.MustParse("1Gi"), - }, - MajorVersion: "17", - }, - MaintenanceWindow: maintenance, - }, - } - - if len(conditions) > 0 { - obj.Status = &data_nais_io_v1.PostgresStatus{} - obj.Status.Conditions = conditions - } - - return obj -} - func TestDeletePostgresInput_ValidationErrors(t *testing.T) { tests := []struct { name string @@ -313,19 +146,3 @@ func TestDeletePostgresInput_ValidationErrors(t *testing.T) { }) } } - -func toPostgresFromCRD(t *testing.T, obj *data_nais_io_v1.Postgres) *PostgresInstance { - t.Helper() - - uMap, err := runtime.DefaultUnstructuredConverter.ToUnstructured(obj) - if err != nil { - t.Fatalf("ToUnstructured() error = %v", err) - } - - got, err := toPostgres(&unstructured.Unstructured{Object: uMap}, "dev") - if err != nil { - t.Fatalf("toPostgres() error = %v", err) - } - - return got -} diff --git a/internal/persistence/postgres/node.go b/internal/persistence/postgres/node.go index 9bf4b2df8..7f63751f5 100644 --- a/internal/persistence/postgres/node.go +++ b/internal/persistence/postgres/node.go @@ -10,13 +10,15 @@ import ( type identType int const ( - identPostgres identType = iota + identPostgresInstance identType = iota identPostgresAccess + identPostgres ) func init() { - ident.RegisterIdentType(identPostgres, "PP", GetPostgresByIdent) + ident.RegisterIdentType(identPostgresInstance, "PP", GetPostgresInstanceByIdent) ident.RegisterIdentType(identPostgresAccess, "PA", GetPostgresAccessByIdent) + ident.RegisterIdentType(identPostgres, "PG", GetPostgresByIdent) } func parsePostgresInstanceIdent(id ident.Ident) (teamSlug slug.Slug, environmentName, postgresInstanceName string, err error) { @@ -29,7 +31,7 @@ func parsePostgresInstanceIdent(id ident.Ident) (teamSlug slug.Slug, environment } func newIdent(teamSlug slug.Slug, environmentName, postgresInstanceName string) ident.Ident { - return ident.NewIdent(identPostgres, teamSlug.String(), environmentName, postgresInstanceName) + return ident.NewIdent(identPostgresInstance, teamSlug.String(), environmentName, postgresInstanceName) } func parseAccessIdent(id ident.Ident) (teamSlug slug.Slug, environmentName, name string, err error) { @@ -44,3 +46,7 @@ func parseAccessIdent(id ident.Ident) (teamSlug slug.Slug, environmentName, name func newAccessIdent(teamSlug slug.Slug, environmentName, name string) ident.Ident { return ident.NewIdent(identPostgresAccess, teamSlug.String(), environmentName, name) } + +func newPostgresIdent(teamSlug slug.Slug, environmentName, name string) ident.Ident { + return ident.NewIdent(identPostgres, teamSlug.String(), environmentName, name) +} diff --git a/internal/persistence/postgres/queries.go b/internal/persistence/postgres/queries.go index 287e9c6a2..caf8f0c24 100644 --- a/internal/persistence/postgres/queries.go +++ b/internal/persistence/postgres/queries.go @@ -4,10 +4,7 @@ import ( "cmp" "context" "fmt" - "hash/crc32" - "net/url" "slices" - "strconv" "strings" "time" @@ -21,17 +18,16 @@ import ( "github.com/nais/api/internal/kubernetes" "github.com/nais/api/internal/kubernetes/watcher" "github.com/nais/api/internal/slug" - "github.com/nais/api/internal/team" "github.com/nais/api/internal/workload" "github.com/nais/api/internal/workload/application" "github.com/nais/api/internal/workload/job" - corev1 "k8s.io/api/core/v1" + liberatorv1 "github.com/nais/liberator/pkg/apis/nais.io/v1" + nais_io_v1 "github.com/nais/pgrator/pkg/api/v1" k8serrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" - "k8s.io/client-go/dynamic" + "k8s.io/utils/ptr" ) func Delete(ctx context.Context, input DeletePostgresInput) (*DeletePostgresPayload, error) { @@ -39,30 +35,32 @@ func Delete(ctx context.Context, input DeletePostgresInput) (*DeletePostgresPayl return nil, err } - client, err := fromContext(ctx).postgresWatcher.ImpersonatedClientWithNamespace(ctx, input.EnvironmentName, input.TeamSlug.String()) + client, err := fromContext(ctx).postgresWatcher.SystemAuthenticatedClient(ctx, input.EnvironmentName) if err != nil { return nil, err } - - obj, err := client.Get(ctx, input.Name, metav1.GetOptions{}) + instance, err := client.Namespace(input.TeamSlug.String()).Get(ctx, input.Name, metav1.GetOptions{}) if err != nil { - return nil, err + return nil, fmt.Errorf("getting PostgresInstance %q before deletion: %w", input.Name, err) } - - allowDeletion, _, err := unstructured.NestedBool(obj.Object, "spec", "cluster", "allowDeletion") + postgresName, _, err := unstructured.NestedString(instance.Object, "spec", "postgres") + if err != nil || postgresName == "" { + return nil, apierror.Errorf("PostgresInstance %q has no Postgres", input.Name) + } + postgresClient, err := fromContext(ctx).postgresWatcher.SystemAuthenticatedClient(ctx, input.EnvironmentName, watcher.WithImpersonatedClientGVR(schema.GroupVersionResource{ + Group: "nais.io", Version: "v1", Resource: "postgres", + })) if err != nil { return nil, err } - if !allowDeletion { - if err := unstructured.SetNestedField(obj.Object, true, "spec", "cluster", "allowDeletion"); err != nil { - return nil, err - } - if _, err = client.Update(ctx, obj, metav1.UpdateOptions{}); err != nil { - return nil, fmt.Errorf("enabling deletion: %w", err) - } + postgres, err := postgresClient.Namespace(input.TeamSlug.String()).Get(ctx, postgresName, metav1.GetOptions{}) + if err != nil { + return nil, fmt.Errorf("getting Postgres %q before instance deletion: %w", postgresName, err) } - - if err := fromContext(ctx).postgresWatcher.Delete(ctx, input.EnvironmentName, input.TeamSlug.String(), input.Name); err != nil { + if err := ensureInstanceMayBeDeleted(instance, postgres); err != nil { + return nil, err + } + if err := client.Namespace(input.TeamSlug.String()).Delete(ctx, input.Name, metav1.DeleteOptions{Preconditions: &metav1.Preconditions{UID: ptr.To(instance.GetUID())}}); err != nil { return nil, err } @@ -80,12 +78,56 @@ func Delete(ctx context.Context, input DeletePostgresInput) (*DeletePostgresPayl return &DeletePostgresPayload{PostgresDeleted: new(true)}, nil } -func GetForWorkload(ctx context.Context, teamSlug slug.Slug, environmentName, clusterName string) (*PostgresInstance, error) { - if clusterName == "" { +// ensureInstanceMayBeDeleted prevents an API request from marking the active +// instance as terminating. Pgrator independently blocks finalization as well. +func ensureInstanceMayBeDeleted(instance, postgres *unstructured.Unstructured) error { + requested, _, err := unstructured.NestedString(postgres.Object, "spec", "activeInstance") + if err != nil { + return err + } + current, _, err := unstructured.NestedString(postgres.Object, "status", "activeInstance") + if err != nil { + return err + } + // Pgrator falls back to the Postgres name when neither field is set. + if requested == "" && current == "" { + current = postgres.GetName() + } + if instance.GetName() == requested || instance.GetName() == current { + return apierror.Errorf("PostgresInstance %q is active and cannot be deleted", instance.GetName()) + } + return nil +} + +func GetForWorkload(ctx context.Context, teamSlug slug.Slug, environmentName, postgresName string) (*PostgresInstance, error) { + if postgresName == "" { + return nil, nil + } + postgres, err := GetPostgres(ctx, teamSlug, environmentName, postgresName) + if err != nil { + return nil, err + } + if postgres.ActiveInstance == nil { return nil, nil } + return GetPostgresInstance(ctx, teamSlug, environmentName, *postgres.ActiveInstance) +} - return GetPostgres(ctx, teamSlug, environmentName, clusterName) +// ListForWorkload resolves each Postgres use to the instance selected by that +// Postgres. A workload can use several databases, each with its own active instance. +func ListForWorkload(ctx context.Context, teamSlug slug.Slug, environmentName string, uses []liberatorv1.PostgresUse) ([]*PostgresInstance, error) { + instances := make([]*PostgresInstance, 0, len(uses)) + for _, use := range uses { + instance, err := GetForWorkload(ctx, teamSlug, environmentName, use.Name) + if err != nil { + return nil, err + } + if instance != nil { + instances = append(instances, instance) + } + } + slices.SortFunc(instances, func(a, b *PostgresInstance) int { return cmp.Compare(a.Name, b.Name) }) + return instances, nil } func ListForTeam(ctx context.Context, teamSlug slug.Slug, page *pagination.Pagination, orderBy *PostgresInstanceOrder, filter *PostgresInstanceFilter) (*PostgresInstanceConnection, error) { @@ -110,13 +152,21 @@ func CountForTeam(ctx context.Context, teamSlug slug.Slug) int { return len(fromContext(ctx).postgresWatcher.GetByNamespace(teamSlug.String())) } -func GetPostgresByIdent(ctx context.Context, id ident.Ident) (*PostgresInstance, error) { +func GetPostgresInstanceByIdent(ctx context.Context, id ident.Ident) (*PostgresInstance, error) { teamSlug, environmentName, clusterName, err := parsePostgresInstanceIdent(id) if err != nil { return nil, err } - return GetPostgres(ctx, teamSlug, environmentName, clusterName) + return GetPostgresInstance(ctx, teamSlug, environmentName, clusterName) +} + +func GetPostgresByIdent(ctx context.Context, id ident.Ident) (*Postgres, error) { + teamSlug, environmentName, name, err := parseAccessIdent(id) + if err != nil { + return nil, err + } + return GetPostgres(ctx, teamSlug, environmentName, name) } func GetPostgresAccessByIdent(ctx context.Context, id ident.Ident) (*PostgresAccess, error) { @@ -180,27 +230,9 @@ func GetPostgresAccessConnection(ctx context.Context, input PostgresAccessConnec return nil, err } - secretClient, err := fromContext(ctx).postgresWatcher.SystemAuthenticatedClient(ctx, input.EnvironmentName, watcher.WithImpersonatedClientGVR(schema.GroupVersionResource{ - Version: "v1", - Resource: "secrets", - })) - if err != nil { - return nil, fmt.Errorf("creating credential Secret client: %w", err) - } - secret, err := secretClient.Namespace(input.TeamSlug.String()).Get(ctx, credentialSecretName, metav1.GetOptions{}) - if err != nil { - if k8serrors.IsNotFound(err) { - return nil, apierror.Errorf("credentials for PostgresAccess %q are not available", input.Name) - } - return nil, fmt.Errorf("getting credential Secret for PostgresAccess %q: %w", input.Name, err) - } - - password, caCertificate, err := postgresAccessConnectionSecret(secret) - if err != nil { + if err := loadPostgresAccessConnection(ctx, access, input, connection, credentialSecretName); err != nil { return nil, err } - connection.Password = password - connection.CACertificate = caCertificate if err := activitylog.Create(ctx, activitylog.CreateInput{ Action: activityLogEntryActionGetPersonalAccessConnection, @@ -252,29 +284,22 @@ func postgresAccessConnectionDetails(access *unstructured.Unstructured, now time return nil, "", apierror.Errorf("PostgresAccess %q is not ready", access.GetName()) } - credentialSecretName, _, err := unstructured.NestedString(access.Object, "status", "credentialSecretName") - if err != nil || credentialSecretName == "" { + if access.GetDeletionTimestamp() != nil { return nil, "", apierror.Errorf("PostgresAccess %q is not ready", access.GetName()) } - serverName, _, err := unstructured.NestedString(access.Object, "status", "serverName") - if err != nil || serverName == "" { + relayName, _, err := unstructured.NestedString(access.Object, "status", "relayAccess") + if err != nil || relayName != access.GetName() { return nil, "", apierror.Errorf("PostgresAccess %q is not ready", access.GetName()) } - endpoint, _, err := unstructured.NestedString(access.Object, "status", "tunnel", "endpoint") - if err != nil || endpoint == "" { + tokenSecret, _, err := unstructured.NestedString(access.Object, "status", "tokenSecret") + if err != nil || tokenSecret == "" { return nil, "", apierror.Errorf("PostgresAccess %q is not ready", access.GetName()) } - gatewayPublicKey, _, err := unstructured.NestedString(access.Object, "status", "tunnel", "gatewayPublicKey") - if err != nil || gatewayPublicKey == "" { + role, _, err := unstructured.NestedString(access.Object, "status", "databaseRole") + if err != nil || role == "" { return nil, "", apierror.Errorf("PostgresAccess %q is not ready", access.GetName()) } - - return &PostgresAccessConnection{ - ServerName: serverName, - Tunnel: PostgresAccessConnectionTunnel{ - Endpoint: endpoint, GatewayPublicKey: gatewayPublicKey, - }, - }, credentialSecretName, nil + return &PostgresAccessConnection{}, tokenSecret, nil } func postgresAccessIsReady(obj map[string]any) bool { @@ -294,19 +319,6 @@ func postgresAccessIsReady(obj map[string]any) bool { return false } -func postgresAccessConnectionSecret(secret *unstructured.Unstructured) (password, caCertificate string, err error) { - var typed corev1.Secret - if err := runtime.DefaultUnstructuredConverter.FromUnstructured(secret.Object, &typed); err != nil { - return "", "", fmt.Errorf("converting credential Secret %q: %w", secret.GetName(), err) - } - password = string(typed.Data[corev1.BasicAuthPasswordKey]) - caCertificate = string(typed.Data["ca.crt"]) - if password == "" || caCertificate == "" { - return "", "", apierror.Errorf("credentials for PostgresAccess are incomplete") - } - return password, caCertificate, nil -} - func toPostgresAccess(u *unstructured.Unstructured, teamSlug slug.Slug, environmentName string) (*PostgresAccess, error) { name := u.GetName() postgresInstance, _, _ := unstructured.NestedString(u.Object, "spec", "postgresInstance") @@ -326,14 +338,7 @@ func toPostgresAccess(u *unstructured.Unstructured, teamSlug slug.Slug, environm state, message := postgresAccessState(u.Object, expiresAt) - var tunnel *PostgresAccessTunnel - if t, ok, _ := unstructured.NestedStringMap(u.Object, "status", "tunnel"); ok && t["name"] != "" { - tunnel = &PostgresAccessTunnel{ - Name: t["name"], - Endpoint: strPtr(t["endpoint"]), - GatewayPublicKey: strPtr(t["gatewayPublicKey"]), - } - } + relayName, _, _ := unstructured.NestedString(u.Object, "status", "relayAccess") return &PostgresAccess{ Name: name, @@ -345,7 +350,7 @@ func toPostgresAccess(u *unstructured.Unstructured, teamSlug slug.Slug, environm ExpiresAt: expiresAt, State: state, Message: strPtr(message), - Tunnel: tunnel, + RelayAccess: strPtr(relayName), }, nil } @@ -392,44 +397,69 @@ func postgresAccessState(obj map[string]any, expiresAt time.Time) (PostgresAcces return PostgresAccessStatePending, "waiting for controller" } -func GetPostgres(ctx context.Context, teamSlug slug.Slug, environmentName string, clusterName string) (*PostgresInstance, error) { - return fromContext(ctx).postgresWatcher.Get(environmentName, teamSlug.String(), clusterName) -} - -func GetAuditURL(ctx context.Context, audit *PostgresInstanceAudit) (*string, error) { - if audit == nil || !audit.Enabled { - return nil, nil +func GetReadyPostgresInstance(ctx context.Context, teamSlug slug.Slug, environmentName, name string) (*PostgresInstance, error) { + instance, err := GetPostgresInstance(ctx, teamSlug, environmentName, name) + if err != nil { + return nil, err } - - auditProjectID, location := GetAuditLogConfig(ctx) - if auditProjectID == "" || location == "" { - return nil, nil + if instance.State != PostgresInstanceStateAvailable { + return instance, nil + } + if _, err := GetPostgres(ctx, teamSlug, environmentName, instance.PostgresName); err != nil { + return nil, fmt.Errorf("getting Postgres %q for instance %q: %w", instance.PostgresName, name, err) + } + // The pgrator reconciliation condition reflects the CNPG phase, but must be + // corroborated with CNPG's own Ready condition before issuing access. + client, err := fromContext(ctx).postgresWatcher.SystemAuthenticatedClient(ctx, environmentName, watcher.WithImpersonatedClientGVR(schema.GroupVersionResource{Group: "postgresql.cnpg.io", Version: "v1", Resource: "clusters"})) + if err != nil { + return nil, err + } + cluster, err := client.Namespace(teamSlug.String()).Get(ctx, nais_io_v1.CNPGClusterName(name), metav1.GetOptions{}) + if k8serrors.IsNotFound(err) { + instance.State = PostgresInstanceStateProgressing + return instance, nil } - - teamEnv, err := team.GetTeamEnvironment(ctx, audit.TeamSlug, audit.EnvironmentName) if err != nil { - return nil, fmt.Errorf("failed to get team environment for audit URL (team=%s, env=%s): %w", audit.TeamSlug, audit.EnvironmentName, err) + return nil, fmt.Errorf("getting CNPG Cluster for PostgresInstance %q: %w", name, err) } - if teamEnv.GCPProjectID == nil || *teamEnv.GCPProjectID == "" { - return nil, nil + conditions, found, err := unstructured.NestedSlice(cluster.Object, "status", "conditions") + if err != nil { + return nil, err + } + if !found { + instance.State = PostgresInstanceStateProgressing + return instance, nil } + for _, raw := range conditions { + condition, ok := raw.(map[string]any) + if ok && condition["type"] == "Ready" && condition["status"] == "True" { + return instance, nil + } + } + instance.State = PostgresInstanceStateProgressing + return instance, nil +} - databaseProjectID := *teamEnv.GCPProjectID - databaseID := fmt.Sprintf("%s:%s", databaseProjectID, audit.InstanceName) - query := fmt.Sprintf("labels.databaseId=\"%s\"", databaseID) - storageScope := fmt.Sprintf("storage,projects/%s/locations/%s/buckets/%s-%s/views/_AllLogs", auditProjectID, location, audit.TeamSlug.String(), audit.EnvironmentName) - logURL := fmt.Sprintf("https://console.cloud.google.com/logs/query;query=%s;storageScope=%s?project=%s", - url.QueryEscape(query), - url.QueryEscape(storageScope), - databaseProjectID, - ) - return &logURL, nil +func GetPostgresInstance(ctx context.Context, teamSlug slug.Slug, environmentName, name string) (*PostgresInstance, error) { + return fromContext(ctx).postgresWatcher.Get(environmentName, teamSlug.String(), name) +} + +func GetPostgres(ctx context.Context, teamSlug slug.Slug, environmentName, name string) (*Postgres, error) { + client, err := fromContext(ctx).postgresWatcher.SystemAuthenticatedClient(ctx, environmentName, watcher.WithImpersonatedClientGVR(schema.GroupVersionResource{Group: "nais.io", Version: "v1", Resource: "postgres"})) + if err != nil { + return nil, err + } + obj, err := client.Namespace(teamSlug.String()).Get(ctx, name, metav1.GetOptions{}) + if err != nil { + return nil, err + } + return toPostgres(obj, environmentName) } const ( postgresAccessAPIVersion = "nais.io/v1" defaultPostgresAccessTTL = time.Hour - maxPostgresAccessTTL = 8 * time.Hour + maxPostgresAccessTTL = time.Hour ) func CreatePostgresAccess(ctx context.Context, input CreatePostgresAccessInput) (*CreatePostgresAccessPayload, error) { @@ -505,185 +535,33 @@ func newPostgresAccessResource(input CreatePostgresAccessInput, username, name s res.SetAnnotations(kubernetes.WithCommonAnnotations(nil, username)) kubernetes.SetManagedByConsoleLabel(res) res.Object["spec"] = map[string]any{ - "postgresInstance": input.PostgresInstance, - "username": username, - "accessLevel": input.AccessLevel.CRDValue(), - "expiresAt": expiresAt.Format(time.RFC3339), - "clientWireGuardPublicKey": input.ClientWireGuardPublicKey, + "postgresInstance": input.PostgresInstance, + "username": username, + "accessLevel": input.AccessLevel.CRDValue(), + "expiresAt": expiresAt.Format(time.RFC3339), } return res } -func GrantPostgresAccess(ctx context.Context, input GrantPostgresAccessInput) error { - err := input.Validate(ctx) - if err != nil { - return err - } - - namespace := fmt.Sprintf("pg-%s", input.TeamSlug.String()) - name, err := resourceNamer(input.TeamSlug, input.Grantee, input.ClusterName) - if err != nil { - return err - } - - annotations := make(map[string]string) - d, err := time.ParseDuration(input.Duration) +func WorkloadsForInstance(ctx context.Context, teamSlug slug.Slug, environmentName, instanceName string) []workload.Workload { + instance, err := GetPostgresInstance(ctx, teamSlug, environmentName, instanceName) if err != nil { - return fmt.Errorf("parsing TTL: %w", err) - } - until := time.Now().Add(d) - - labels := make(map[string]string) - labels["euthanaisa.nais.io/kill-after"] = strconv.FormatInt(until.Unix(), 10) - labels["postgres.data.nais.io/name"] = input.ClusterName - - err = createRole(ctx, input, name, namespace, annotations, labels) - if err != nil { - return err - } - - err = createRoleBinding(ctx, input, name, namespace, annotations, labels) - if err != nil { - return err - } - - return activitylog.Create(ctx, activitylog.CreateInput{ - Action: activityLogEntryActionGrantAccess, - Actor: authz.ActorFromContext(ctx).User, - ResourceType: activityLogEntryResourceTypePostgres, - ResourceName: input.ClusterName, - EnvironmentName: new(input.EnvironmentName), - TeamSlug: new(input.TeamSlug), - Data: PostgresGrantAccessActivityLogEntryData{ - Grantee: input.Grantee, - Until: until, - }, - }) -} - -func createRoleBinding(ctx context.Context, input GrantPostgresAccessInput, name string, namespace string, annotations map[string]string, labels map[string]string) error { - gvr := schema.GroupVersionResource{ - Group: "rbac.authorization.k8s.io", - Version: "v1", - Resource: "rolebindings", - } - client, err := fromContext(ctx).postgresWatcher.SystemAuthenticatedClient(ctx, input.EnvironmentName, watcher.WithImpersonatedClientGVR(gvr)) - if err != nil { - return err - } - namespacedClient := client.Namespace(namespace) - - res := &unstructured.Unstructured{} - res.SetAPIVersion(gvr.GroupVersion().String()) - res.SetKind("RoleBinding") - res.SetName(name) - res.SetNamespace(namespace) - res.SetAnnotations(kubernetes.WithCommonAnnotations(annotations, authz.ActorFromContext(ctx).User.Identity())) - res.SetLabels(labels) - kubernetes.SetManagedByConsoleLabel(res) - - res.Object["roleRef"] = map[string]any{ - "apiGroup": "rbac.authorization.k8s.io", - "kind": "Role", - "name": name, - } - - res.Object["subjects"] = []any{ - map[string]any{ - "kind": "User", - "name": input.Grantee, - }, - } - - return createOrUpdateResource(ctx, res, namespacedClient) -} - -func createRole(ctx context.Context, input GrantPostgresAccessInput, name string, namespace string, annotations map[string]string, labels map[string]string) error { - gvr := schema.GroupVersionResource{ - Group: "rbac.authorization.k8s.io", - Version: "v1", - Resource: "roles", - } - - client, err := fromContext(ctx).postgresWatcher.SystemAuthenticatedClient(ctx, input.EnvironmentName, watcher.WithImpersonatedClientGVR(gvr)) - if err != nil { - return err - } - namespacedClient := client.Namespace(namespace) - - res := &unstructured.Unstructured{} - res.SetAPIVersion(gvr.GroupVersion().String()) - res.SetKind("Role") - res.SetName(name) - res.SetNamespace(namespace) - res.SetAnnotations(kubernetes.WithCommonAnnotations(annotations, authz.ActorFromContext(ctx).User.Identity())) - res.SetLabels(labels) - kubernetes.SetManagedByConsoleLabel(res) - - res.Object["rules"] = []any{ - map[string]any{ - "apiGroups": []any{""}, - "resources": []any{"pods"}, - "verbs": []any{"get", "list", "watch"}, - "resourceNames": []any{ - fmt.Sprintf("%s-0", input.ClusterName), - fmt.Sprintf("%s-1", input.ClusterName), - fmt.Sprintf("%s-2", input.ClusterName), - }, - }, - map[string]any{ - "apiGroups": []any{""}, - "resources": []any{"pods/portforward"}, - "verbs": []any{"get", "list", "watch", "create"}, - "resourceNames": []any{ - fmt.Sprintf("%s-0", input.ClusterName), - fmt.Sprintf("%s-1", input.ClusterName), - fmt.Sprintf("%s-2", input.ClusterName), - }, - }, - } - - return createOrUpdateResource(ctx, res, namespacedClient) -} - -func createOrUpdateResource(ctx context.Context, res *unstructured.Unstructured, client dynamic.ResourceInterface) error { - _, err := client.Create(ctx, res, metav1.CreateOptions{}) - if err != nil { - if k8serrors.IsAlreadyExists(err) { - _, err = client.Update(ctx, res, metav1.UpdateOptions{}) - if err != nil { - return err - } - return nil - } - return err + return nil } - return nil -} - -func resourceNamer(teamSlug slug.Slug, grantee string, name string) (string, error) { - hasher := crc32.NewIEEE() - _, err := fmt.Fprintf(hasher, "%s-%s-%s", teamSlug.String(), grantee, name) - if err != nil { - return "", err + postgres, err := GetPostgres(ctx, teamSlug, environmentName, instance.PostgresName) + if err != nil || postgres.ActiveInstance == nil || *postgres.ActiveInstance != instanceName { + return nil } - hashStr := fmt.Sprintf("%08x", hasher.Sum32()) - return fmt.Sprintf("pg-grant-%s", hashStr), nil -} - -func WorkloadsForInstance(ctx context.Context, teamSlug slug.Slug, environmentName, clusterName string) []workload.Workload { apps := application.ListAllForTeamInEnvironment(ctx, teamSlug, environmentName) jobs := job.ListAllForTeamInEnvironment(ctx, teamSlug, environmentName) - ret := make([]workload.Workload, 0) for _, app := range apps { - if app.Spec != nil && app.Spec.Postgres != nil && app.Spec.Postgres.ClusterName == clusterName { + if app.Spec != nil && app.Spec.Uses != nil && slices.ContainsFunc(app.Spec.Uses.Postgres, func(use liberatorv1.PostgresUse) bool { return use.Name == instance.PostgresName }) { ret = append(ret, app) } } - for _, j := range jobs { - if j.Spec != nil && j.Spec.Postgres != nil && j.Spec.Postgres.ClusterName == clusterName { + if j.Spec != nil && j.Spec.Uses != nil && slices.ContainsFunc(j.Spec.Uses.Postgres, func(use liberatorv1.PostgresUse) bool { return use.Name == instance.PostgresName }) { ret = append(ret, j) } } diff --git a/internal/persistence/postgres/queries_test.go b/internal/persistence/postgres/queries_test.go index 524332b92..860641d44 100644 --- a/internal/persistence/postgres/queries_test.go +++ b/internal/persistence/postgres/queries_test.go @@ -7,19 +7,16 @@ import ( "time" "github.com/nais/api/internal/slug" - corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" - "k8s.io/apimachinery/pkg/runtime" ) func TestNewPostgresAccessResource(t *testing.T) { expiresAt := time.Date(2026, time.September, 17, 12, 0, 0, 0, time.UTC) resource := newPostgresAccessResource(CreatePostgresAccessInput{ - PostgresInstance: "orders", - TeamSlug: slug.Slug("team-a"), - EnvironmentName: "dev", - AccessLevel: PostgresAccessLevelReadWrite, - ClientWireGuardPublicKey: "client-public-key", + PostgresInstance: "orders", + TeamSlug: slug.Slug("team-a"), + EnvironmentName: "dev", + AccessLevel: PostgresAccessLevelReadWrite, }, "user@example.com", "postgres-access-12345678", expiresAt) if got, want := resource.GetAPIVersion(), "nais.io/v1"; got != want { @@ -40,11 +37,10 @@ func TestNewPostgresAccessResource(t *testing.T) { t.Fatalf("spec = (%v, %t, %v), want a spec", spec, found, err) } wantSpec := map[string]any{ - "postgresInstance": "orders", - "username": "user@example.com", - "accessLevel": "readwrite", - "expiresAt": "2026-09-17T12:00:00Z", - "clientWireGuardPublicKey": "client-public-key", + "postgresInstance": "orders", + "username": "user@example.com", + "accessLevel": "readwrite", + "expiresAt": "2026-09-17T12:00:00Z", } if !reflect.DeepEqual(wantSpec, spec) { t.Errorf("spec = %#v, want %#v", spec, wantSpec) @@ -59,11 +55,11 @@ func TestCreatePostgresAccessTTL(t *testing.T) { wantErr string }{ {name: "default", want: time.Hour}, - {name: "requested", ttl: "4h", want: 4 * time.Hour}, - {name: "maximum", ttl: "8h", want: 8 * time.Hour}, + {name: "requested", ttl: "30m", want: 30 * time.Minute}, + {name: "maximum", ttl: "1h", want: time.Hour}, {name: "invalid", ttl: "tomorrow", wantErr: "TTL must be a Go duration"}, {name: "zero", ttl: "0s", wantErr: "TTL must be positive"}, - {name: "too long", ttl: "8h1m", wantErr: "TTL cannot exceed 8h0m0s"}, + {name: "too long", ttl: "1h1m", wantErr: "TTL cannot exceed 1h0m0s"}, } for _, tt := range tests { @@ -116,12 +112,12 @@ func TestPostgresAccessState(t *testing.T) { map[string]any{ "type": "Ready", "status": "True", - "message": "Database role and tunnel are ready", + "message": "database role and relay mapping are ready", }, }, }, wantState: PostgresAccessStateReady, - wantMsg: "Database role and tunnel are ready", + wantMsg: "database role and relay mapping are ready", }, { name: "failed unsupported access level", @@ -140,19 +136,19 @@ func TestPostgresAccessState(t *testing.T) { wantMsg: "readwritecreate requires an instance initialized with the app_readwritecreate group role", }, { - name: "pending waiting on tunnel", + name: "pending waiting on relay", expiresAt: future, status: map[string]any{ "conditions": []any{ map[string]any{ "type": "Ready", "status": "False", - "message": "waiting for tunnel", + "message": "waiting for relay", }, }, }, wantState: PostgresAccessStatePending, - wantMsg: "waiting for tunnel", + wantMsg: "waiting for relay", }, } @@ -180,10 +176,10 @@ func TestPostgresAccessConnectionDetails(t *testing.T) { "metadata": map[string]any{"name": "access"}, "spec": map[string]any{"expiresAt": "2026-09-17T13:00:00Z"}, "status": map[string]any{ - "credentialSecretName": "access-credentials", - "serverName": "postgres.example", - "conditions": []any{map[string]any{"type": "Ready", "status": "True"}}, - "tunnel": map[string]any{"endpoint": "endpoint:1234", "gatewayPublicKey": "gateway-key"}, + "databaseRole": "personal-role", + "relayAccess": "access", + "tokenSecret": "access-relay-token", + "conditions": []any{map[string]any{"type": "Ready", "status": "True"}}, }, }} } @@ -200,8 +196,11 @@ func TestPostgresAccessConnectionDetails(t *testing.T) { {name: "not ready", edit: func(u *unstructured.Unstructured) { _ = unstructured.SetNestedField(u.Object, []any{map[string]any{"type": "Ready", "status": "False"}}, "status", "conditions") }, want: "not ready"}, - {name: "missing secret name", edit: func(u *unstructured.Unstructured) { - unstructured.RemoveNestedField(u.Object, "status", "credentialSecretName") + {name: "missing token secret name", edit: func(u *unstructured.Unstructured) { + unstructured.RemoveNestedField(u.Object, "status", "tokenSecret") + }, want: "not ready"}, + {name: "missing relay mapping", edit: func(u *unstructured.Unstructured) { + unstructured.RemoveNestedField(u.Object, "status", "relayAccess") }, want: "not ready"}, } for _, tt := range tests { @@ -220,39 +219,12 @@ func TestPostgresAccessConnectionDetails(t *testing.T) { if err != nil { t.Fatalf("postgresAccessConnectionDetails: %v", err) } - if secretName != "access-credentials" { + if secretName != "access-relay-token" { t.Errorf("secret name = %q", secretName) } - if got.ServerName != "postgres.example" || got.Tunnel.Endpoint != "endpoint:1234" || got.Tunnel.GatewayPublicKey != "gateway-key" { - t.Errorf("connection = %#v", got) + if got == nil { + t.Fatal("connection is nil") } }) } } - -func TestPostgresAccessConnectionSecret(t *testing.T) { - secret := &corev1.Secret{Data: map[string][]byte{ - corev1.BasicAuthPasswordKey: []byte("supersecret"), - "ca.crt": []byte("test-ca-certificate"), - }} - u, err := runtime.DefaultUnstructuredConverter.ToUnstructured(secret) - if err != nil { - t.Fatalf("ToUnstructured: %v", err) - } - password, ca, err := postgresAccessConnectionSecret(&unstructured.Unstructured{Object: u}) - if err != nil { - t.Fatalf("postgresAccessConnectionSecret: %v", err) - } - if password != "supersecret" || ca != "test-ca-certificate" { - t.Errorf("got password=%q ca=%q", password, ca) - } - - delete(secret.Data, "ca.crt") - u, err = runtime.DefaultUnstructuredConverter.ToUnstructured(secret) - if err != nil { - t.Fatalf("ToUnstructured: %v", err) - } - if _, _, err := postgresAccessConnectionSecret(&unstructured.Unstructured{Object: u}); err == nil { - t.Fatal("missing ca.crt did not fail") - } -} diff --git a/internal/persistence/postgres/search.go b/internal/persistence/postgres/search.go index 14c2826d0..dd9eaef50 100644 --- a/internal/persistence/postgres/search.go +++ b/internal/persistence/postgres/search.go @@ -15,7 +15,7 @@ func AddSearchPostgres(client search.Client, watcher *watcher.Watcher[*PostgresI } gbi := func(ctx context.Context, id ident.Ident) (search.SearchNode, error) { - return GetPostgresByIdent(ctx, id) + return GetPostgresInstanceByIdent(ctx, id) } client.AddClient("POSTGRES", search.NewK8sSearch("POSTGRES", watcher, gbi, createIdent)) diff --git a/internal/persistence/postgres/sortfilter.go b/internal/persistence/postgres/sortfilter.go index 57a580b70..30ebbb47b 100644 --- a/internal/persistence/postgres/sortfilter.go +++ b/internal/persistence/postgres/sortfilter.go @@ -38,18 +38,6 @@ func init() { } } - if filter.HighAvailability != nil { - if v.HighAvailability != *filter.HighAvailability { - return false - } - } - - if len(filter.MajorVersions) > 0 { - if !slices.Contains(filter.MajorVersions, v.MajorVersion) { - return false - } - } - if !model.MatchesLabelFilters(v.Labels, filter.Labels) { return false } diff --git a/internal/workload/secret/queries.go b/internal/workload/secret/queries.go index 96a98c44d..e6f191cb5 100644 --- a/internal/workload/secret/queries.go +++ b/internal/workload/secret/queries.go @@ -731,6 +731,18 @@ func ViewSecretValues(ctx context.Context, input ViewSecretValuesInput) (*ViewSe actor := authz.ActorFromContext(ctx) loaders := fromContext(ctx) + clusterName := environmentmapper.ClusterName(input.Environment) + k8sClient, exists := loaders.K8sClient(clusterName) + if !exists { + return nil, apierror.Errorf("Environment %q does not exist.", input.Environment) + } + current, err := k8sClient.Resource(schema.GroupVersionResource{Version: "v1", Resource: "secrets"}).Namespace(input.Team.String()).Get(ctx, input.Name, v1.GetOptions{}) + if err != nil { + return nil, fmt.Errorf("checking secret ownership: %w", err) + } + if isPostgresAccessSecret(current) { + return nil, apierror.Errorf("PostgresAccess credentials are only available through postgresAccessConnection") + } // Create temporary Role and RoleBinding for the user (1 minute TTL) elevationID, err := createTemporaryRBAC(ctx, loaders, input, actor) @@ -739,7 +751,6 @@ func ViewSecretValues(ctx context.Context, input ViewSecretValuesInput) (*ViewSe } // Use impersonated client to read secret values (defense in depth) - clusterName := environmentmapper.ClusterName(input.Environment) impersonatedClient, err := loaders.Client(ctx, clusterName) if err != nil { return nil, fmt.Errorf("creating impersonated client: %w", err) @@ -768,6 +779,10 @@ func ViewSecretValues(ctx context.Context, input ViewSecretValuesInput) (*ViewSe } } + if isPostgresAccessSecret(u) { + return nil, apierror.Errorf("PostgresAccess credentials are only available through postgresAccessConnection") + } + data, _, err := unstructured.NestedStringMap(u.Object, "data") if err != nil { return nil, err @@ -811,6 +826,15 @@ func ViewSecretValues(ctx context.Context, input ViewSecretValuesInput) (*ViewSe }, nil } +func isPostgresAccessSecret(secret *unstructured.Unstructured) bool { + for _, owner := range secret.GetOwnerReferences() { + if owner.APIVersion == "nais.io/v1" && owner.Kind == "PostgresAccess" { + return true + } + } + return false +} + var ( roleGVR = schema.GroupVersionResource{Group: "rbac.authorization.k8s.io", Version: "v1", Resource: "roles"} roleBindingGVR = schema.GroupVersionResource{Group: "rbac.authorization.k8s.io", Version: "v1", Resource: "rolebindings"} diff --git a/internal/workload/secret/queries_test.go b/internal/workload/secret/queries_test.go new file mode 100644 index 000000000..5c25e4552 --- /dev/null +++ b/internal/workload/secret/queries_test.go @@ -0,0 +1,27 @@ +package secret + +import ( + "testing" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" +) + +func TestPersonalAccessSecretsAreNotAvailableThroughGenericSecretView(t *testing.T) { + for _, name := range []string{"postgres-access-12345678-relay-token", "postgres-access-12345678-credentials"} { + t.Run(name, func(t *testing.T) { + secret := &unstructured.Unstructured{} + secret.SetName(name) + secret.SetOwnerReferences([]metav1.OwnerReference{{APIVersion: "nais.io/v1", Kind: "PostgresAccess", Name: "postgres-access-12345678"}}) + if !isPostgresAccessSecret(secret) { + t.Fatal("personal access credentials must not be readable through generic Secret view") + } + }) + } + + ordinary := &unstructured.Unstructured{} + ordinary.SetName("application-credentials") + if isPostgresAccessSecret(ordinary) { + t.Fatal("ordinary Secrets must remain readable through generic Secret view") + } +} diff --git a/pkg/apiclient/protoapi/databases.pb.go b/pkg/apiclient/protoapi/databases.pb.go index c92a0491b..29efa0ad7 100644 --- a/pkg/apiclient/protoapi/databases.pb.go +++ b/pkg/apiclient/protoapi/databases.pb.go @@ -27,7 +27,7 @@ type DatabaseType int32 const ( DatabaseType_DATABASE_TYPE_UNSPECIFIED DatabaseType = 0 DatabaseType_CLOUD_SQL DatabaseType = 1 - DatabaseType_ZALANDO_POSTGRES DatabaseType = 2 + DatabaseType_NAIS_POSTGRES DatabaseType = 2 ) // Enum value maps for DatabaseType. @@ -35,12 +35,12 @@ var ( DatabaseType_name = map[int32]string{ 0: "DATABASE_TYPE_UNSPECIFIED", 1: "CLOUD_SQL", - 2: "ZALANDO_POSTGRES", + 2: "NAIS_POSTGRES", } DatabaseType_value = map[string]int32{ "DATABASE_TYPE_UNSPECIFIED": 0, "CLOUD_SQL": 1, - "ZALANDO_POSTGRES": 2, + "NAIS_POSTGRES": 2, } ) @@ -378,21 +378,20 @@ var file_databases_proto_rawDesc = string([]byte{ 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6e, 0x61, 0x69, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, - 0x6f, 0x2a, 0x52, 0x0a, 0x0c, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x54, 0x79, 0x70, + 0x6f, 0x2a, 0x4f, 0x0a, 0x0c, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1d, 0x0a, 0x19, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x4c, 0x4f, 0x55, 0x44, 0x5f, 0x53, 0x51, 0x4c, 0x10, 0x01, 0x12, - 0x14, 0x0a, 0x10, 0x5a, 0x41, 0x4c, 0x41, 0x4e, 0x44, 0x4f, 0x5f, 0x50, 0x4f, 0x53, 0x54, 0x47, - 0x52, 0x45, 0x53, 0x10, 0x02, 0x32, 0x68, 0x0a, 0x09, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, - 0x65, 0x73, 0x12, 0x5b, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x27, 0x2e, 0x6e, 0x61, 0x69, - 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4c, - 0x69, 0x73, 0x74, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x6e, 0x61, 0x69, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x61, 0x74, 0x61, - 0x62, 0x61, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, - 0x1a, 0x5a, 0x18, 0x2e, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x63, 0x6c, 0x69, 0x65, - 0x6e, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, + 0x11, 0x0a, 0x0d, 0x4e, 0x41, 0x49, 0x53, 0x5f, 0x50, 0x4f, 0x53, 0x54, 0x47, 0x52, 0x45, 0x53, + 0x10, 0x02, 0x32, 0x68, 0x0a, 0x09, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x12, + 0x5b, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x27, 0x2e, 0x6e, 0x61, 0x69, 0x73, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x28, 0x2e, 0x6e, 0x61, 0x69, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, + 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x1a, 0x5a, 0x18, + 0x2e, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, }) var file_databases_proto_enumTypes = make([]protoimpl.EnumInfo, 1) diff --git a/pkg/apiclient/protoapi/databases_protoopaque.pb.go b/pkg/apiclient/protoapi/databases_protoopaque.pb.go index f0eb1aca8..c85fa69ae 100644 --- a/pkg/apiclient/protoapi/databases_protoopaque.pb.go +++ b/pkg/apiclient/protoapi/databases_protoopaque.pb.go @@ -27,7 +27,7 @@ type DatabaseType int32 const ( DatabaseType_DATABASE_TYPE_UNSPECIFIED DatabaseType = 0 DatabaseType_CLOUD_SQL DatabaseType = 1 - DatabaseType_ZALANDO_POSTGRES DatabaseType = 2 + DatabaseType_NAIS_POSTGRES DatabaseType = 2 ) // Enum value maps for DatabaseType. @@ -35,12 +35,12 @@ var ( DatabaseType_name = map[int32]string{ 0: "DATABASE_TYPE_UNSPECIFIED", 1: "CLOUD_SQL", - 2: "ZALANDO_POSTGRES", + 2: "NAIS_POSTGRES", } DatabaseType_value = map[string]int32{ "DATABASE_TYPE_UNSPECIFIED": 0, "CLOUD_SQL": 1, - "ZALANDO_POSTGRES": 2, + "NAIS_POSTGRES": 2, } ) @@ -380,21 +380,20 @@ var file_databases_proto_rawDesc = string([]byte{ 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6e, 0x61, 0x69, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, - 0x6f, 0x2a, 0x52, 0x0a, 0x0c, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x54, 0x79, 0x70, + 0x6f, 0x2a, 0x4f, 0x0a, 0x0c, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1d, 0x0a, 0x19, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x4c, 0x4f, 0x55, 0x44, 0x5f, 0x53, 0x51, 0x4c, 0x10, 0x01, 0x12, - 0x14, 0x0a, 0x10, 0x5a, 0x41, 0x4c, 0x41, 0x4e, 0x44, 0x4f, 0x5f, 0x50, 0x4f, 0x53, 0x54, 0x47, - 0x52, 0x45, 0x53, 0x10, 0x02, 0x32, 0x68, 0x0a, 0x09, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, - 0x65, 0x73, 0x12, 0x5b, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x27, 0x2e, 0x6e, 0x61, 0x69, - 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4c, - 0x69, 0x73, 0x74, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x6e, 0x61, 0x69, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x61, 0x74, 0x61, - 0x62, 0x61, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, - 0x1a, 0x5a, 0x18, 0x2e, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x63, 0x6c, 0x69, 0x65, - 0x6e, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, + 0x11, 0x0a, 0x0d, 0x4e, 0x41, 0x49, 0x53, 0x5f, 0x50, 0x4f, 0x53, 0x54, 0x47, 0x52, 0x45, 0x53, + 0x10, 0x02, 0x32, 0x68, 0x0a, 0x09, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x12, + 0x5b, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x27, 0x2e, 0x6e, 0x61, 0x69, 0x73, 0x2e, 0x61, + 0x70, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x28, 0x2e, 0x6e, 0x61, 0x69, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, + 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x1a, 0x5a, 0x18, + 0x2e, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2f, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, }) var file_databases_proto_enumTypes = make([]protoimpl.EnumInfo, 1) diff --git a/pkg/apiclient/protoapi/schema/databases.proto b/pkg/apiclient/protoapi/schema/databases.proto index 6876580c5..31485f34a 100644 --- a/pkg/apiclient/protoapi/schema/databases.proto +++ b/pkg/apiclient/protoapi/schema/databases.proto @@ -9,7 +9,7 @@ option go_package = "./pkg/apiclient/protoapi"; enum DatabaseType { DATABASE_TYPE_UNSPECIFIED = 0; CLOUD_SQL = 1; - ZALANDO_POSTGRES = 2; + NAIS_POSTGRES = 2; } message Database { From f889bfa1a997e39ec1ae8b5cde4ad6c02cd700c0 Mon Sep 17 00:00:00 2001 From: Johnny Fredheim Horvi Date: Tue, 29 Sep 2026 07:35:52 +0200 Subject: [PATCH 08/19] Align Postgres access GraphQL with API conventions and resolve main changes --- .configs/gqlgen.yaml | 1 + integration_tests/create_postgres_access.lua | 57 +- .../activitylogsql/activitylog.sql.go | 46 +- internal/activitylog/activitylogsql/models.go | 19 +- internal/activitylog/model.go | 22 +- internal/activitylog/queries.go | 68 +- internal/activitylog/queries/activitylog.sql | 6 +- internal/activitylog/resource.go | 24 +- internal/apply/apply.go | 5 - internal/auth/middleware/github_token.go | 54 +- .../graph/gengql/applications.generated.go | 175 +- internal/graph/gengql/apply.generated.go | 484 +++- internal/graph/gengql/cluster.generated.go | 35 + internal/graph/gengql/config.generated.go | 103 + internal/graph/gengql/deployment.generated.go | 69 + internal/graph/gengql/jobs.generated.go | 175 +- internal/graph/gengql/kafka.generated.go | 69 + internal/graph/gengql/opensearch.generated.go | 137 + internal/graph/gengql/postgres.generated.go | 256 +- .../graph/gengql/reconcilers.generated.go | 103 + internal/graph/gengql/repository.generated.go | 69 + internal/graph/gengql/root_.generated.go | 2292 ++++++++++++----- internal/graph/gengql/schema.generated.go | 178 -- internal/graph/gengql/secret.generated.go | 239 ++ ...viceaccount_workload_bindings.generated.go | 69 + .../graph/gengql/serviceaccounts.generated.go | 273 ++ .../gengql/servicemaintenance.generated.go | 35 + internal/graph/gengql/teams.generated.go | 368 +++ internal/graph/gengql/tunnel.generated.go | 69 + internal/graph/gengql/unleash.generated.go | 103 + internal/graph/gengql/valkey.generated.go | 137 + .../graph/gengql/vulnerability.generated.go | 35 + internal/graph/postgres.resolvers.go | 19 +- internal/graph/schema/activitylog.graphqls | 3 + internal/graph/schema/applications.graphqls | 16 + internal/graph/schema/apply.graphqls | 53 +- internal/graph/schema/cluster.graphqls | 3 + internal/graph/schema/config.graphqls | 9 + internal/graph/schema/deployment.graphqls | 6 + internal/graph/schema/jobs.graphqls | 16 + internal/graph/schema/kafka.graphqls | 6 + internal/graph/schema/opensearch.graphqls | 12 + internal/graph/schema/postgres.graphqls | 109 +- internal/graph/schema/reconcilers.graphqls | 9 + internal/graph/schema/repository.graphqls | 6 + internal/graph/schema/secret.graphqls | 21 + .../serviceaccount_workload_bindings.graphqls | 6 + .../graph/schema/serviceaccounts.graphqls | 24 + .../graph/schema/servicemaintenance.graphqls | 3 + internal/graph/schema/teams.graphqls | 24 + internal/graph/schema/tunnel.graphqls | 6 + internal/graph/schema/unleash.graphqls | 9 + internal/graph/schema/valkey.graphqls | 12 + internal/graph/schema/vulnerability.graphqls | 3 + .../kubernetes/fake/postgres_fixtures_test.go | 5 +- internal/workload/application/activitylog.go | 5 +- internal/workload/job/activitylog.go | 5 +- 57 files changed, 4987 insertions(+), 1178 deletions(-) diff --git a/.configs/gqlgen.yaml b/.configs/gqlgen.yaml index c88200ccf..73ca01d3f 100644 --- a/.configs/gqlgen.yaml +++ b/.configs/gqlgen.yaml @@ -39,6 +39,7 @@ autobind: - "github.com/nais/api/internal/alerts" - "github.com/nais/api/internal/apply" - "github.com/nais/api/internal/auth/authz" + - "github.com/nais/api/internal/auth/middleware/github" - "github.com/nais/api/internal/cost" - "github.com/nais/api/internal/deployment" - "github.com/nais/api/internal/deployment/deploymentactivity" diff --git a/integration_tests/create_postgres_access.lua b/integration_tests/create_postgres_access.lua index 54b3667a8..4f47bf038 100644 --- a/integration_tests/create_postgres_access.lua +++ b/integration_tests/create_postgres_access.lua @@ -219,11 +219,11 @@ Test.gql("Personal access targets a physical instance, even when its name differ t.check { data = { createPostgresAccess = { name = NotNull() } } } t.query [[ - query { postgresAccess(name: "recovered-access", teamSlug: "someteamname", environmentName: "dev") { - postgresInstance { name } - } } + query { team(slug: "someteamname") { environment(name: "dev") { + postgresAccess(name: "recovered-access") { postgresInstance { name } } + } } } ]] - t.check { data = { postgresAccess = { postgresInstance = { name = "foobar-recovered" } } } } + t.check { data = { team = { environment = { postgresAccess = { postgresInstance = { name = "foobar-recovered" } } } } } } end) Test.gql("PostgresAccess status is visible to authorized team members", function(t) @@ -235,16 +235,16 @@ Test.gql("PostgresAccess status is visible to authorized team members", function { name = "expired-access", state = "EXPIRED", message = "access has expired" }, }) do t.query(string.format( - [[query { postgresAccess(name: "%s", teamSlug: "someteamname", environmentName: "dev") { name state message } }]], + [[query { team(slug: "someteamname") { environment(name: "dev") { postgresAccess(name: "%s") { name state message } } } }]], test.name)) t.check { - data = { + data = { team = { environment = { postgresAccess = { name = test.name, state = test.state, message = test.message, }, - }, + } } }, } end end) @@ -252,14 +252,14 @@ end) Test.gql("PostgresAccess status rejects users outside the team", function(t) t.addHeader("x-user-email", nonMemberUser:email()) t.query [[ - query { postgresAccess(name: "ready-access", teamSlug: "someteamname", environmentName: "dev") { state } } + query { team(slug: "someteamname") { environment(name: "dev") { postgresAccess(name: "ready-access") { state } } } } ]] t.check { errors = { { locations = NotNull(), message = Contains('you need the "postgres:access:grant" authorization.'), - path = { "postgresAccess" }, + path = { "team", "environment", "postgresAccess" }, }, }, data = Null, @@ -270,21 +270,23 @@ Test.gql("PostgresAccess connection returns credentials only to its owner", func t.addHeader("x-user-email", user:email()) t.query [[ query GetPostgresAccessConnection { - postgresAccessConnection(input: {name: "ready-access", teamSlug: "someteamname", environmentName: "dev"}) { - password - caCertificate - serverName - username - relayEndpoint - relayAccess - relayToken - } + team(slug: "someteamname") { environment(name: "dev") { + postgresAccess(name: "ready-access") { connection { + password + caCertificate + serverName + username + relayEndpoint + relayAccess + relayToken + } } + } } } ]] t.check { - data = { - postgresAccessConnection = { + data = { team = { environment = { postgresAccess = { + connection = { password = "supersecret", caCertificate = "test-ca-certificate", serverName = "pg-foobar-rw.someteamname.svc.cluster.local", @@ -293,17 +295,17 @@ Test.gql("PostgresAccess connection returns credentials only to its owner", func relayAccess = "someteamname/ready-access", relayToken = "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8", }, - }, + } } } }, } end) Test.gql("PostgresAccess connection rejects a different team member", function(t) t.addHeader("x-user-email", otherMemberUser:email()) t.query [[ - query { postgresAccessConnection(input: {name: "ready-access", teamSlug: "someteamname", environmentName: "dev"}) { password } } + query { team(slug: "someteamname") { environment(name: "dev") { postgresAccess(name: "ready-access") { connection { password } } } } } ]] t.check { - errors = { { locations = NotNull(), path = { "postgresAccessConnection" }, message = Contains("not authorized") } }, + errors = { { locations = NotNull(), path = { "team", "environment", "postgresAccess", "connection" }, message = Contains("not authorized") } }, data = Null, } end) @@ -329,13 +331,14 @@ Test.gql("PostgresAccess connection rejects expired, unready, and missing-secret for _, test in ipairs({ { name = "expired-access", message = "has expired" }, { name = "pending-access", message = "is not ready" }, + { name = "failed-access", message = "is not ready" }, { name = "missing-secret-access", message = "secrets for PostgresAccess is not available" }, }) do t.query(string.format( - [[query { postgresAccessConnection(input: {name: "%s", teamSlug: "someteamname", environmentName: "dev"}) { password } }]], + [[query { team(slug: "someteamname") { environment(name: "dev") { postgresAccess(name: "%s") { connection { password } } } } }]], test.name)) t.check { - errors = { { locations = NotNull(), path = { "postgresAccessConnection" }, message = Contains(test.message) } }, + errors = { { locations = NotNull(), path = { "team", "environment", "postgresAccess", "connection" }, message = Contains(test.message) } }, data = Null, } end @@ -344,9 +347,9 @@ end) Test.gql("Personal postgres connection retrieval is audited", function(t) t.addHeader("x-user-email", user:email()) t.query [[ - query { postgresAccessConnection(input: {name: "ready-access", teamSlug: "someteamname", environmentName: "dev"}) { password } } + query { team(slug: "someteamname") { environment(name: "dev") { postgresAccess(name: "ready-access") { connection { password } } } } } ]] - t.check { data = { postgresAccessConnection = { password = "supersecret" } } } + t.check { data = { team = { environment = { postgresAccess = { connection = { password = "supersecret" } } } } } } t.query [[ { team(slug: "someteamname") { activityLog(first: 1) { nodes { message ... on PostgresPersonalAccessConnectionActivityLogEntry { resourceName } } } } } diff --git a/internal/activitylog/activitylogsql/activitylog.sql.go b/internal/activitylog/activitylogsql/activitylog.sql.go index bee9afaf5..4b99e5f99 100644 --- a/internal/activitylog/activitylogsql/activitylog.sql.go +++ b/internal/activitylog/activitylogsql/activitylog.sql.go @@ -20,7 +20,8 @@ INSERT INTO resource_name, team_slug, environment, - data + data, + github_actor_claims ) VALUES ( @@ -30,18 +31,20 @@ VALUES $4, $5, $6, - $7 + $7, + $8 ) ` type CreateParams struct { - Actor string - Action string - ResourceType string - ResourceName string - TeamSlug *slug.Slug - EnvironmentName *string - Data []byte + Actor string + Action string + ResourceType string + ResourceName string + TeamSlug *slug.Slug + EnvironmentName *string + Data []byte + GithubActorClaims []byte } func (q *Queries) Create(ctx context.Context, arg CreateParams) error { @@ -53,6 +56,7 @@ func (q *Queries) Create(ctx context.Context, arg CreateParams) error { arg.TeamSlug, arg.EnvironmentName, arg.Data, + arg.GithubActorClaims, ) return err } @@ -693,7 +697,7 @@ func (q *Queries) FacetsForTenantActivityTypes(ctx context.Context, arg FacetsFo const get = `-- name: Get :one SELECT - id, created_at, actor, action, resource_type, resource_name, team_slug, data, environment + id, created_at, actor, action, resource_type, resource_name, team_slug, data, environment, github_actor_claims FROM activity_log_combined_view WHERE @@ -713,13 +717,14 @@ func (q *Queries) Get(ctx context.Context, id uuid.UUID) (*ActivityLogCombinedVi &i.TeamSlug, &i.Data, &i.Environment, + &i.GithubActorClaims, ) return &i, err } const listByIDs = `-- name: ListByIDs :many SELECT - id, created_at, actor, action, resource_type, resource_name, team_slug, data, environment + id, created_at, actor, action, resource_type, resource_name, team_slug, data, environment, github_actor_claims FROM activity_log_combined_view WHERE @@ -747,6 +752,7 @@ func (q *Queries) ListByIDs(ctx context.Context, ids []uuid.UUID) ([]*ActivityLo &i.TeamSlug, &i.Data, &i.Environment, + &i.GithubActorClaims, ); err != nil { return nil, err } @@ -790,7 +796,7 @@ WITH ) ) SELECT - activity_log_combined_view.id, activity_log_combined_view.created_at, activity_log_combined_view.actor, activity_log_combined_view.action, activity_log_combined_view.resource_type, activity_log_combined_view.resource_name, activity_log_combined_view.team_slug, activity_log_combined_view.data, activity_log_combined_view.environment, + activity_log_combined_view.id, activity_log_combined_view.created_at, activity_log_combined_view.actor, activity_log_combined_view.action, activity_log_combined_view.resource_type, activity_log_combined_view.resource_name, activity_log_combined_view.team_slug, activity_log_combined_view.data, activity_log_combined_view.environment, activity_log_combined_view.github_actor_claims, matching_entries.total_count FROM activity_log_combined_view @@ -874,6 +880,7 @@ func (q *Queries) ListForResource(ctx context.Context, arg ListForResourceParams &i.ActivityLogCombinedView.TeamSlug, &i.ActivityLogCombinedView.Data, &i.ActivityLogCombinedView.Environment, + &i.ActivityLogCombinedView.GithubActorClaims, &i.TotalCount, ); err != nil { return nil, err @@ -888,7 +895,7 @@ func (q *Queries) ListForResource(ctx context.Context, arg ListForResourceParams const listForResourceAndTeam = `-- name: ListForResourceAndTeam :many SELECT - activity_log_combined_view.id, activity_log_combined_view.created_at, activity_log_combined_view.actor, activity_log_combined_view.action, activity_log_combined_view.resource_type, activity_log_combined_view.resource_name, activity_log_combined_view.team_slug, activity_log_combined_view.data, activity_log_combined_view.environment, + activity_log_combined_view.id, activity_log_combined_view.created_at, activity_log_combined_view.actor, activity_log_combined_view.action, activity_log_combined_view.resource_type, activity_log_combined_view.resource_name, activity_log_combined_view.team_slug, activity_log_combined_view.data, activity_log_combined_view.environment, activity_log_combined_view.github_actor_claims, COUNT(*) OVER () AS total_count FROM activity_log_combined_view @@ -972,6 +979,7 @@ func (q *Queries) ListForResourceAndTeam(ctx context.Context, arg ListForResourc &i.ActivityLogCombinedView.TeamSlug, &i.ActivityLogCombinedView.Data, &i.ActivityLogCombinedView.Environment, + &i.ActivityLogCombinedView.GithubActorClaims, &i.TotalCount, ); err != nil { return nil, err @@ -986,7 +994,7 @@ func (q *Queries) ListForResourceAndTeam(ctx context.Context, arg ListForResourc const listForResourceTeamAndEnvironment = `-- name: ListForResourceTeamAndEnvironment :many SELECT - activity_log_combined_view.id, activity_log_combined_view.created_at, activity_log_combined_view.actor, activity_log_combined_view.action, activity_log_combined_view.resource_type, activity_log_combined_view.resource_name, activity_log_combined_view.team_slug, activity_log_combined_view.data, activity_log_combined_view.environment, + activity_log_combined_view.id, activity_log_combined_view.created_at, activity_log_combined_view.actor, activity_log_combined_view.action, activity_log_combined_view.resource_type, activity_log_combined_view.resource_name, activity_log_combined_view.team_slug, activity_log_combined_view.data, activity_log_combined_view.environment, activity_log_combined_view.github_actor_claims, COUNT(*) OVER () AS total_count FROM activity_log_combined_view @@ -1073,6 +1081,7 @@ func (q *Queries) ListForResourceTeamAndEnvironment(ctx context.Context, arg Lis &i.ActivityLogCombinedView.TeamSlug, &i.ActivityLogCombinedView.Data, &i.ActivityLogCombinedView.Environment, + &i.ActivityLogCombinedView.GithubActorClaims, &i.TotalCount, ); err != nil { return nil, err @@ -1087,7 +1096,7 @@ func (q *Queries) ListForResourceTeamAndEnvironment(ctx context.Context, arg Lis const listForResourceWithoutTeam = `-- name: ListForResourceWithoutTeam :many SELECT - activity_log_combined_view.id, activity_log_combined_view.created_at, activity_log_combined_view.actor, activity_log_combined_view.action, activity_log_combined_view.resource_type, activity_log_combined_view.resource_name, activity_log_combined_view.team_slug, activity_log_combined_view.data, activity_log_combined_view.environment, + activity_log_combined_view.id, activity_log_combined_view.created_at, activity_log_combined_view.actor, activity_log_combined_view.action, activity_log_combined_view.resource_type, activity_log_combined_view.resource_name, activity_log_combined_view.team_slug, activity_log_combined_view.data, activity_log_combined_view.environment, activity_log_combined_view.github_actor_claims, COUNT(*) OVER () AS total_count FROM activity_log_combined_view @@ -1169,6 +1178,7 @@ func (q *Queries) ListForResourceWithoutTeam(ctx context.Context, arg ListForRes &i.ActivityLogCombinedView.TeamSlug, &i.ActivityLogCombinedView.Data, &i.ActivityLogCombinedView.Environment, + &i.ActivityLogCombinedView.GithubActorClaims, &i.TotalCount, ); err != nil { return nil, err @@ -1212,7 +1222,7 @@ WITH ) ) SELECT - activity_log_combined_view.id, activity_log_combined_view.created_at, activity_log_combined_view.actor, activity_log_combined_view.action, activity_log_combined_view.resource_type, activity_log_combined_view.resource_name, activity_log_combined_view.team_slug, activity_log_combined_view.data, activity_log_combined_view.environment, + activity_log_combined_view.id, activity_log_combined_view.created_at, activity_log_combined_view.actor, activity_log_combined_view.action, activity_log_combined_view.resource_type, activity_log_combined_view.resource_name, activity_log_combined_view.team_slug, activity_log_combined_view.data, activity_log_combined_view.environment, activity_log_combined_view.github_actor_claims, matching_entries.total_count FROM activity_log_combined_view @@ -1293,6 +1303,7 @@ func (q *Queries) ListForTeam(ctx context.Context, arg ListForTeamParams) ([]*Li &i.ActivityLogCombinedView.TeamSlug, &i.ActivityLogCombinedView.Data, &i.ActivityLogCombinedView.Environment, + &i.ActivityLogCombinedView.GithubActorClaims, &i.TotalCount, ); err != nil { return nil, err @@ -1335,7 +1346,7 @@ WITH ) ) SELECT - activity_log_combined_view.id, activity_log_combined_view.created_at, activity_log_combined_view.actor, activity_log_combined_view.action, activity_log_combined_view.resource_type, activity_log_combined_view.resource_name, activity_log_combined_view.team_slug, activity_log_combined_view.data, activity_log_combined_view.environment, + activity_log_combined_view.id, activity_log_combined_view.created_at, activity_log_combined_view.actor, activity_log_combined_view.action, activity_log_combined_view.resource_type, activity_log_combined_view.resource_name, activity_log_combined_view.team_slug, activity_log_combined_view.data, activity_log_combined_view.environment, activity_log_combined_view.github_actor_claims, matching_entries.total_count FROM activity_log_combined_view @@ -1411,6 +1422,7 @@ func (q *Queries) ListForTenant(ctx context.Context, arg ListForTenantParams) ([ &i.ActivityLogCombinedView.TeamSlug, &i.ActivityLogCombinedView.Data, &i.ActivityLogCombinedView.Environment, + &i.ActivityLogCombinedView.GithubActorClaims, &i.TotalCount, ); err != nil { return nil, err diff --git a/internal/activitylog/activitylogsql/models.go b/internal/activitylog/activitylogsql/models.go index 0124f3e81..e569ca13b 100644 --- a/internal/activitylog/activitylogsql/models.go +++ b/internal/activitylog/activitylogsql/models.go @@ -9,13 +9,14 @@ import ( ) type ActivityLogCombinedView struct { - ID uuid.UUID - CreatedAt pgtype.Timestamptz - Actor string - Action string - ResourceType string - ResourceName string - TeamSlug *slug.Slug - Data []byte - Environment *string + ID uuid.UUID + CreatedAt pgtype.Timestamptz + Actor string + Action string + ResourceType string + ResourceName string + TeamSlug *slug.Slug + Data []byte + Environment *string + GithubActorClaims []byte } diff --git a/internal/activitylog/model.go b/internal/activitylog/model.go index 516d905ec..854447df3 100644 --- a/internal/activitylog/model.go +++ b/internal/activitylog/model.go @@ -8,6 +8,7 @@ import ( "time" "github.com/google/uuid" + "github.com/nais/api/internal/auth/middleware/github" "github.com/nais/api/internal/graph/ident" "github.com/nais/api/internal/graph/model" "github.com/nais/api/internal/graph/pagination" @@ -76,16 +77,17 @@ type ActivityLogResourceTypeFacetItem struct { } type GenericActivityLogEntry struct { - Actor string `json:"actor"` - CreatedAt time.Time `json:"createdAt"` - EnvironmentName *string `json:"environmentName,omitempty"` - Message string `json:"message"` - ResourceType ActivityLogEntryResourceType `json:"resourceType"` - ResourceName string `json:"resourceName"` - TeamSlug *slug.Slug `json:"teamSlug,omitempty"` - Action ActivityLogEntryAction `json:"-"` - UUID uuid.UUID `json:"-"` - Data []byte `json:"-"` + Actor string `json:"actor"` + CreatedAt time.Time `json:"createdAt"` + EnvironmentName *string `json:"environmentName,omitempty"` + Message string `json:"message"` + ResourceType ActivityLogEntryResourceType `json:"resourceType"` + ResourceName string `json:"resourceName"` + TeamSlug *slug.Slug `json:"teamSlug,omitempty"` + GitHubActorClaims *github.GitHubActorClaims `json:"gitHubActorClaims,omitempty"` + Action ActivityLogEntryAction `json:"-"` + UUID uuid.UUID `json:"-"` + Data []byte `json:"-"` } func (GenericActivityLogEntry) IsNode() {} diff --git a/internal/activitylog/queries.go b/internal/activitylog/queries.go index f1b0312d1..ed06d10ea 100644 --- a/internal/activitylog/queries.go +++ b/internal/activitylog/queries.go @@ -1,13 +1,16 @@ package activitylog import ( + "bytes" "context" "encoding/json" "fmt" + "strings" "github.com/google/uuid" "github.com/nais/api/internal/activitylog/activitylogsql" "github.com/nais/api/internal/auth/authz" + "github.com/nais/api/internal/auth/middleware/github" "github.com/nais/api/internal/environmentmapper" "github.com/nais/api/internal/graph/ident" "github.com/nais/api/internal/graph/pagination" @@ -41,26 +44,37 @@ func MarshalData(input CreateInput) ([]byte, error) { } func Create(ctx context.Context, input CreateInput) error { - q := db(ctx) - data, err := MarshalData(input) if err != nil { return err } + var claimsData []byte + if actor, ok := input.Actor.(interface { + GitHubActorClaims() *github.GitHubActorClaims + }); ok { + if claims := actor.GitHubActorClaims(); claims != nil { + claimsData, err = json.Marshal(claims) + if err != nil { + return fmt.Errorf("marshaling GitHub actor claims: %w", err) + } + } + } + q := db(ctx) var environmentName *string if input.EnvironmentName != nil { environmentName = new(environmentmapper.EnvironmentName(*input.EnvironmentName)) } return q.Create(ctx, activitylogsql.CreateParams{ - Action: string(input.Action), - Actor: input.Actor.Identity(), - Data: data, - EnvironmentName: environmentName, - ResourceName: input.ResourceName, - ResourceType: string(input.ResourceType), - TeamSlug: input.TeamSlug, + Action: string(input.Action), + Actor: input.Actor.Identity(), + Data: data, + EnvironmentName: environmentName, + ResourceName: input.ResourceName, + ResourceType: string(input.ResourceType), + TeamSlug: input.TeamSlug, + GithubActorClaims: claimsData, }) } @@ -309,17 +323,33 @@ func ListForResourceTeamAndEnvironment(ctx context.Context, resourceType Activit func toGraphActivityLogEntry(row *activitylogsql.ActivityLogCombinedView) (ActivityLogEntry, error) { titler := cases.Title(language.English) + var claims *github.GitHubActorClaims + if len(row.GithubActorClaims) > 0 { + if err := json.Unmarshal(row.GithubActorClaims, &claims); err != nil { + return nil, fmt.Errorf("unmarshaling activity log actor claims: %w", err) + } + } else if strings.HasPrefix(row.Actor, "github-repo:") && bytes.Contains(row.Data, []byte(`"gitHubActorClaims"`)) { + // Older API instances may still write claims into data during a rolling deployment. + var legacy struct { + GitHubActorClaims *github.GitHubActorClaims `json:"gitHubActorClaims"` + } + if err := json.Unmarshal(row.Data, &legacy); err != nil { + return nil, fmt.Errorf("unmarshaling legacy activity log actor claims: %w", err) + } + claims = legacy.GitHubActorClaims + } entry := GenericActivityLogEntry{ - Action: ActivityLogEntryAction(row.Action), - Actor: row.Actor, - CreatedAt: row.CreatedAt.Time, - EnvironmentName: row.Environment, - Message: titler.String(row.Action) + " " + titler.String(row.ResourceType), - ResourceType: ActivityLogEntryResourceType(row.ResourceType), - ResourceName: row.ResourceName, - TeamSlug: row.TeamSlug, - UUID: row.ID, - Data: row.Data, + Action: ActivityLogEntryAction(row.Action), + Actor: row.Actor, + CreatedAt: row.CreatedAt.Time, + EnvironmentName: row.Environment, + Message: titler.String(row.Action) + " " + titler.String(row.ResourceType), + ResourceType: ActivityLogEntryResourceType(row.ResourceType), + ResourceName: row.ResourceName, + TeamSlug: row.TeamSlug, + UUID: row.ID, + Data: row.Data, + GitHubActorClaims: claims, } transformer, ok := knownTransformers[ActivityLogEntryResourceType(row.ResourceType)] diff --git a/internal/activitylog/queries/activitylog.sql b/internal/activitylog/queries/activitylog.sql index cb1f34463..fc4cd21a7 100644 --- a/internal/activitylog/queries/activitylog.sql +++ b/internal/activitylog/queries/activitylog.sql @@ -324,7 +324,8 @@ INSERT INTO resource_name, team_slug, environment, - data + data, + github_actor_claims ) VALUES ( @@ -334,7 +335,8 @@ VALUES @resource_name, @team_slug, @environment_name, - @data + @data, + @github_actor_claims ) ; diff --git a/internal/activitylog/resource.go b/internal/activitylog/resource.go index 0e6e5d35f..e7b5651d3 100644 --- a/internal/activitylog/resource.go +++ b/internal/activitylog/resource.go @@ -3,6 +3,8 @@ package activitylog import ( "fmt" "sync" + + "github.com/nais/api/internal/auth/middleware/github" ) var ( @@ -67,25 +69,8 @@ type GenericKubernetesResourceActivityLogEntryData struct { // Only populated for updates. ChangedFields []ResourceChangedField `json:"changedFields"` - // GitHubActorClaims holds the GitHub Actions OIDC token claims at the time of the - // apply. Only populated when the request was authenticated via a GitHub token. - GitHubActorClaims *GitHubActorClaims `json:"gitHubActorClaims,omitempty"` -} - -// GitHubActorClaims holds the GitHub Actions OIDC token claims captured at the -// time of an apply operation. Duplicated from the middleware package to avoid a -// circular import; JSON tags must stay in sync. -type GitHubActorClaims struct { - Ref string `json:"ref"` - Repository string `json:"repository"` - RepositoryID string `json:"repositoryId"` - RunID string `json:"runId"` - RunAttempt string `json:"runAttempt"` - Actor string `json:"actor"` - Workflow string `json:"workflow"` - EventName string `json:"eventName"` - Environment string `json:"environment"` - JobWorkflowRef string `json:"jobWorkflowRef"` + // GitHubActorClaims exposes the deprecated data field from the entry's claims column. + GitHubActorClaims *github.GitHubActorClaims `json:"-"` } // GenericKubernetesActivityLogEntry is used for resource types that do not have @@ -115,6 +100,7 @@ func init() { if err != nil { return nil, fmt.Errorf("transforming unsupported resource activity log entry data: %w", err) } + data.GitHubActorClaims = entry.GitHubActorClaims return GenericKubernetesResourceActivityLogEntry{ GenericActivityLogEntry: entry.WithMessage( fmt.Sprintf("%s %s %s", entry.ResourceName, entry.Action, entry.ResourceType), diff --git a/internal/apply/apply.go b/internal/apply/apply.go index fe1d2bb3c..404c8a743 100644 --- a/internal/apply/apply.go +++ b/internal/apply/apply.go @@ -10,7 +10,6 @@ import ( "github.com/nais/api/internal/activitylog" "github.com/nais/api/internal/auth/authz" - "github.com/nais/api/internal/auth/middleware" "github.com/nais/api/internal/environmentmapper" "github.com/nais/api/internal/slug" "github.com/sirupsen/logrus" @@ -176,10 +175,6 @@ func (h *Handler) applyOne( } actor := authz.ActorFromContext(ctx) - if ghActor, ok := actor.User.(*middleware.GitHubRepoActor); ok { - claims := activitylog.GitHubActorClaims(ghActor.Claims) - logData.GitHubActorClaims = &claims - } if err := activitylog.Create(ctx, activitylog.CreateInput{ Action: action, diff --git a/internal/auth/middleware/github_token.go b/internal/auth/middleware/github_token.go index 17c6b3e95..75d7ed0f1 100644 --- a/internal/auth/middleware/github_token.go +++ b/internal/auth/middleware/github_token.go @@ -10,42 +10,13 @@ import ( "github.com/coreos/go-oidc/v3/oidc" "github.com/google/uuid" "github.com/nais/api/internal/auth/authz" + "github.com/nais/api/internal/auth/middleware/github" "github.com/nais/api/internal/github/repository" "github.com/nais/api/internal/slug" "github.com/nais/api/internal/team" "github.com/sirupsen/logrus" ) -// ghClaims represents the claims present in a GitHub OIDC token. -// See https://docs.github.com/en/actions/reference/security/oidc#oidc-token-claims. -type ghClaims struct { - Ref string `json:"ref"` - Repository string `json:"repository"` - RepositoryID string `json:"repository_id"` - RunID string `json:"run_id"` - RunAttempt string `json:"run_attempt"` - Actor string `json:"actor"` - Workflow string `json:"workflow"` - EventName string `json:"event_name"` - Environment string `json:"environment"` - JobWorkflowRef string `json:"job_workflow_ref"` -} - -// GitHubActorClaims holds the subset of GitHub OIDC claims that are stored -// alongside activity log entries for audit purposes. -type GitHubActorClaims struct { - Ref string `json:"ref"` - Repository string `json:"repository"` - RepositoryID string `json:"repositoryID"` - RunID string `json:"runID"` - RunAttempt string `json:"runAttempt"` - Actor string `json:"actor"` - Workflow string `json:"workflow"` - EventName string `json:"eventName"` - Environment string `json:"environment"` - JobWorkflowRef string `json:"jobWorkflowRef"` -} - const ( // GitHubOIDCIssuer is the OIDC issuer URL for GitHub Actions tokens. GitHubOIDCIssuer = "https://token.actions.githubusercontent.com" @@ -83,8 +54,8 @@ func GitHubOIDC(ctx context.Context, issuer string, log logrus.FieldLogger) (fun return } - claims := &ghClaims{} - if err := idToken.Claims(claims); err != nil { + claims := github.GitHubActorClaims{} + if err := idToken.Claims(&claims); err != nil { log.WithError(err).Debug("failed to parse claims from token") next.ServeHTTP(w, r) return @@ -119,18 +90,7 @@ func GitHubOIDC(ctx context.Context, issuer string, log logrus.FieldLogger) (fun usr := &GitHubRepoActor{ RepositoryName: claims.Repository, TeamSlugs: slices.Collect(maps.Keys(slugs)), - Claims: GitHubActorClaims{ - Ref: claims.Ref, - Repository: claims.Repository, - RepositoryID: claims.RepositoryID, - RunID: claims.RunID, - RunAttempt: claims.RunAttempt, - Actor: claims.Actor, - Workflow: claims.Workflow, - EventName: claims.EventName, - Environment: claims.Environment, - JobWorkflowRef: claims.JobWorkflowRef, - }, + Claims: claims, } next.ServeHTTP(w, r.WithContext(authz.ContextWithActor(ctx, usr, roles))) @@ -142,7 +102,7 @@ func GitHubOIDC(ctx context.Context, issuer string, log logrus.FieldLogger) (fun type GitHubRepoActor struct { RepositoryName string TeamSlugs []slug.Slug - Claims GitHubActorClaims + Claims github.GitHubActorClaims } func (g *GitHubRepoActor) GetID() uuid.UUID { return uuid.Nil } @@ -151,6 +111,10 @@ func (g *GitHubRepoActor) Identity() string { return fmt.Sprintf("github-repo:%s", g.RepositoryName) } +func (g *GitHubRepoActor) GitHubActorClaims() *github.GitHubActorClaims { + return &g.Claims +} + func (g *GitHubRepoActor) IsServiceAccount() bool { return true } func (g *GitHubRepoActor) IsGitHubActions() {} diff --git a/internal/graph/gengql/applications.generated.go b/internal/graph/gengql/applications.generated.go index 738da5aa7..dcbe7a6e2 100644 --- a/internal/graph/gengql/applications.generated.go +++ b/internal/graph/gengql/applications.generated.go @@ -13,6 +13,7 @@ import ( "github.com/99designs/gqlgen/graphql" "github.com/nais/api/internal/activitylog" + "github.com/nais/api/internal/auth/middleware/github" "github.com/nais/api/internal/cost" "github.com/nais/api/internal/deployment" "github.com/nais/api/internal/graph/ident" @@ -1870,6 +1871,38 @@ func (ec *executionContext) fieldContext_ApplicationCreatedActivityLogEntry_acto return graphql.NewScalarFieldContext("ApplicationCreatedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _ApplicationCreatedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *application.ApplicationCreatedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_ApplicationCreatedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_ApplicationCreatedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ApplicationCreatedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _ApplicationCreatedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *application.ApplicationCreatedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -2086,6 +2119,38 @@ func (ec *executionContext) fieldContext_ApplicationDeletedActivityLogEntry_acto return graphql.NewScalarFieldContext("ApplicationDeletedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _ApplicationDeletedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *application.ApplicationDeletedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_ApplicationDeletedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_ApplicationDeletedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ApplicationDeletedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _ApplicationDeletedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *application.ApplicationDeletedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -3075,6 +3140,38 @@ func (ec *executionContext) fieldContext_ApplicationRestartedActivityLogEntry_ac return graphql.NewScalarFieldContext("ApplicationRestartedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _ApplicationRestartedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *application.ApplicationRestartedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_ApplicationRestartedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_ApplicationRestartedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ApplicationRestartedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _ApplicationRestartedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *application.ApplicationRestartedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -3259,6 +3356,38 @@ func (ec *executionContext) fieldContext_ApplicationScaledActivityLogEntry_actor return graphql.NewScalarFieldContext("ApplicationScaledActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _ApplicationScaledActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *application.ApplicationScaledActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_ApplicationScaledActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_ApplicationScaledActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ApplicationScaledActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _ApplicationScaledActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *application.ApplicationScaledActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -3636,6 +3765,38 @@ func (ec *executionContext) fieldContext_ApplicationUpdatedActivityLogEntry_acto return graphql.NewScalarFieldContext("ApplicationUpdatedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _ApplicationUpdatedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *application.ApplicationUpdatedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_ApplicationUpdatedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_ApplicationUpdatedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ApplicationUpdatedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _ApplicationUpdatedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *application.ApplicationUpdatedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -3850,8 +4011,8 @@ func (ec *executionContext) _ApplicationUpdatedActivityLogEntryData_gitHubActorC return obj.GitHubActorClaims, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v *activitylog.GitHubActorClaims) graphql.Marshaler { - return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋactivitylogᚐGitHubActorClaims(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) }, true, false, @@ -5712,6 +5873,8 @@ func (ec *executionContext) _ApplicationCreatedActivityLogEntry(ctx context.Cont if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._ApplicationCreatedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._ApplicationCreatedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -5788,6 +5951,8 @@ func (ec *executionContext) _ApplicationDeletedActivityLogEntry(ctx context.Cont if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._ApplicationDeletedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._ApplicationDeletedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -6425,6 +6590,8 @@ func (ec *executionContext) _ApplicationRestartedActivityLogEntry(ctx context.Co if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._ApplicationRestartedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._ApplicationRestartedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -6496,6 +6663,8 @@ func (ec *executionContext) _ApplicationScaledActivityLogEntry(ctx context.Conte if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._ApplicationScaledActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._ApplicationScaledActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -6709,6 +6878,8 @@ func (ec *executionContext) _ApplicationUpdatedActivityLogEntry(ctx context.Cont if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._ApplicationUpdatedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._ApplicationUpdatedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { diff --git a/internal/graph/gengql/apply.generated.go b/internal/graph/gengql/apply.generated.go index 7e760f200..b7ee88679 100644 --- a/internal/graph/gengql/apply.generated.go +++ b/internal/graph/gengql/apply.generated.go @@ -12,6 +12,7 @@ import ( "github.com/99designs/gqlgen/graphql" "github.com/nais/api/internal/activitylog" + "github.com/nais/api/internal/auth/middleware/github" "github.com/nais/api/internal/graph/ident" "github.com/nais/api/internal/slug" "github.com/vektah/gqlparser/v2/ast" @@ -77,6 +78,38 @@ func (ec *executionContext) fieldContext_GenericKubernetesResourceActivityLogEnt return graphql.NewScalarFieldContext("GenericKubernetesResourceActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _GenericKubernetesResourceActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *activitylog.GenericKubernetesResourceActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_GenericKubernetesResourceActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_GenericKubernetesResourceActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "GenericKubernetesResourceActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _GenericKubernetesResourceActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *activitylog.GenericKubernetesResourceActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -337,8 +370,8 @@ func (ec *executionContext) _GenericKubernetesResourceActivityLogEntryData_gitHu return obj.GitHubActorClaims, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v *activitylog.GitHubActorClaims) graphql.Marshaler { - return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋactivitylogᚐGitHubActorClaims(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) }, true, false, @@ -357,7 +390,214 @@ func (ec *executionContext) fieldContext_GenericKubernetesResourceActivityLogEnt return fc, nil } -func (ec *executionContext) _GitHubActorClaims_ref(ctx context.Context, field graphql.CollectedField, obj *activitylog.GitHubActorClaims) (ret graphql.Marshaler) { +func (ec *executionContext) _GitHubActorClaims_actor(ctx context.Context, field graphql.CollectedField, obj *github.GitHubActorClaims) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_GitHubActorClaims_actor(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Actor, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { + return ec.marshalNString2string(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_GitHubActorClaims_actor(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("GitHubActorClaims", field, false, false, errors.New("field of type String does not have child fields")) +} + +func (ec *executionContext) _GitHubActorClaims_actorID(ctx context.Context, field graphql.CollectedField, obj *github.GitHubActorClaims) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_GitHubActorClaims_actorID(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.ActorID, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *string) graphql.Marshaler { + return ec.marshalOString2ᚖstring(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_GitHubActorClaims_actorID(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("GitHubActorClaims", field, false, false, errors.New("field of type String does not have child fields")) +} + +func (ec *executionContext) _GitHubActorClaims_baseRef(ctx context.Context, field graphql.CollectedField, obj *github.GitHubActorClaims) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_GitHubActorClaims_baseRef(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.BaseRef, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *string) graphql.Marshaler { + return ec.marshalOString2ᚖstring(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_GitHubActorClaims_baseRef(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("GitHubActorClaims", field, false, false, errors.New("field of type String does not have child fields")) +} + +func (ec *executionContext) _GitHubActorClaims_checkRunID(ctx context.Context, field graphql.CollectedField, obj *github.GitHubActorClaims) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_GitHubActorClaims_checkRunID(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.CheckRunID, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *string) graphql.Marshaler { + return ec.marshalOString2ᚖstring(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_GitHubActorClaims_checkRunID(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("GitHubActorClaims", field, false, false, errors.New("field of type String does not have child fields")) +} + +func (ec *executionContext) _GitHubActorClaims_environment(ctx context.Context, field graphql.CollectedField, obj *github.GitHubActorClaims) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_GitHubActorClaims_environment(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Environment, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { + return ec.marshalNString2string(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_GitHubActorClaims_environment(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("GitHubActorClaims", field, false, false, errors.New("field of type String does not have child fields")) +} + +func (ec *executionContext) _GitHubActorClaims_eventName(ctx context.Context, field graphql.CollectedField, obj *github.GitHubActorClaims) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_GitHubActorClaims_eventName(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.EventName, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { + return ec.marshalNString2string(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_GitHubActorClaims_eventName(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("GitHubActorClaims", field, false, false, errors.New("field of type String does not have child fields")) +} + +func (ec *executionContext) _GitHubActorClaims_headRef(ctx context.Context, field graphql.CollectedField, obj *github.GitHubActorClaims) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_GitHubActorClaims_headRef(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.HeadRef, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *string) graphql.Marshaler { + return ec.marshalOString2ᚖstring(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_GitHubActorClaims_headRef(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("GitHubActorClaims", field, false, false, errors.New("field of type String does not have child fields")) +} + +func (ec *executionContext) _GitHubActorClaims_jobWorkflowRef(ctx context.Context, field graphql.CollectedField, obj *github.GitHubActorClaims) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_GitHubActorClaims_jobWorkflowRef(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.JobWorkflowRef, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { + return ec.marshalNString2string(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_GitHubActorClaims_jobWorkflowRef(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("GitHubActorClaims", field, false, false, errors.New("field of type String does not have child fields")) +} + +func (ec *executionContext) _GitHubActorClaims_jobWorkflowSha(ctx context.Context, field graphql.CollectedField, obj *github.GitHubActorClaims) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_GitHubActorClaims_jobWorkflowSha(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.JobWorkflowSha, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *string) graphql.Marshaler { + return ec.marshalOString2ᚖstring(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_GitHubActorClaims_jobWorkflowSha(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("GitHubActorClaims", field, false, false, errors.New("field of type String does not have child fields")) +} + +func (ec *executionContext) _GitHubActorClaims_ref(ctx context.Context, field graphql.CollectedField, obj *github.GitHubActorClaims) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, @@ -380,7 +620,30 @@ func (ec *executionContext) fieldContext_GitHubActorClaims_ref(_ context.Context return graphql.NewScalarFieldContext("GitHubActorClaims", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _GitHubActorClaims_repository(ctx context.Context, field graphql.CollectedField, obj *activitylog.GitHubActorClaims) (ret graphql.Marshaler) { +func (ec *executionContext) _GitHubActorClaims_refType(ctx context.Context, field graphql.CollectedField, obj *github.GitHubActorClaims) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_GitHubActorClaims_refType(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.RefType, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *string) graphql.Marshaler { + return ec.marshalOString2ᚖstring(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_GitHubActorClaims_refType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("GitHubActorClaims", field, false, false, errors.New("field of type String does not have child fields")) +} + +func (ec *executionContext) _GitHubActorClaims_repository(ctx context.Context, field graphql.CollectedField, obj *github.GitHubActorClaims) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, @@ -403,7 +666,7 @@ func (ec *executionContext) fieldContext_GitHubActorClaims_repository(_ context. return graphql.NewScalarFieldContext("GitHubActorClaims", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _GitHubActorClaims_repositoryID(ctx context.Context, field graphql.CollectedField, obj *activitylog.GitHubActorClaims) (ret graphql.Marshaler) { +func (ec *executionContext) _GitHubActorClaims_repositoryID(ctx context.Context, field graphql.CollectedField, obj *github.GitHubActorClaims) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, @@ -426,30 +689,76 @@ func (ec *executionContext) fieldContext_GitHubActorClaims_repositoryID(_ contex return graphql.NewScalarFieldContext("GitHubActorClaims", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _GitHubActorClaims_runID(ctx context.Context, field graphql.CollectedField, obj *activitylog.GitHubActorClaims) (ret graphql.Marshaler) { +func (ec *executionContext) _GitHubActorClaims_repositoryOwner(ctx context.Context, field graphql.CollectedField, obj *github.GitHubActorClaims) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_GitHubActorClaims_runID(ctx, field) + return ec.fieldContext_GitHubActorClaims_repositoryOwner(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.RunID, nil + return obj.RepositoryOwner, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { - return ec.marshalNString2string(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *string) graphql.Marshaler { + return ec.marshalOString2ᚖstring(ctx, selections, v) }, true, + false, + ) +} +func (ec *executionContext) fieldContext_GitHubActorClaims_repositoryOwner(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("GitHubActorClaims", field, false, false, errors.New("field of type String does not have child fields")) +} + +func (ec *executionContext) _GitHubActorClaims_repositoryOwnerID(ctx context.Context, field graphql.CollectedField, obj *github.GitHubActorClaims) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_GitHubActorClaims_repositoryOwnerID(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.RepositoryOwnerID, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *string) graphql.Marshaler { + return ec.marshalOString2ᚖstring(ctx, selections, v) + }, true, + false, ) } -func (ec *executionContext) fieldContext_GitHubActorClaims_runID(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_GitHubActorClaims_repositoryOwnerID(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("GitHubActorClaims", field, false, false, errors.New("field of type String does not have child fields")) +} + +func (ec *executionContext) _GitHubActorClaims_repositoryVisibility(ctx context.Context, field graphql.CollectedField, obj *github.GitHubActorClaims) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_GitHubActorClaims_repositoryVisibility(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.RepositoryVisibility, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *string) graphql.Marshaler { + return ec.marshalOString2ᚖstring(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_GitHubActorClaims_repositoryVisibility(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("GitHubActorClaims", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _GitHubActorClaims_runAttempt(ctx context.Context, field graphql.CollectedField, obj *activitylog.GitHubActorClaims) (ret graphql.Marshaler) { +func (ec *executionContext) _GitHubActorClaims_runAttempt(ctx context.Context, field graphql.CollectedField, obj *github.GitHubActorClaims) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, @@ -472,16 +781,16 @@ func (ec *executionContext) fieldContext_GitHubActorClaims_runAttempt(_ context. return graphql.NewScalarFieldContext("GitHubActorClaims", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _GitHubActorClaims_actor(ctx context.Context, field graphql.CollectedField, obj *activitylog.GitHubActorClaims) (ret graphql.Marshaler) { +func (ec *executionContext) _GitHubActorClaims_runID(ctx context.Context, field graphql.CollectedField, obj *github.GitHubActorClaims) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_GitHubActorClaims_actor(ctx, field) + return ec.fieldContext_GitHubActorClaims_runID(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Actor, nil + return obj.RunID, nil }, nil, func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { @@ -491,66 +800,66 @@ func (ec *executionContext) _GitHubActorClaims_actor(ctx context.Context, field true, ) } -func (ec *executionContext) fieldContext_GitHubActorClaims_actor(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_GitHubActorClaims_runID(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("GitHubActorClaims", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _GitHubActorClaims_workflow(ctx context.Context, field graphql.CollectedField, obj *activitylog.GitHubActorClaims) (ret graphql.Marshaler) { +func (ec *executionContext) _GitHubActorClaims_runnerEnvironment(ctx context.Context, field graphql.CollectedField, obj *github.GitHubActorClaims) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_GitHubActorClaims_workflow(ctx, field) + return ec.fieldContext_GitHubActorClaims_runnerEnvironment(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Workflow, nil + return obj.RunnerEnvironment, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { - return ec.marshalNString2string(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *string) graphql.Marshaler { + return ec.marshalOString2ᚖstring(ctx, selections, v) }, true, - true, + false, ) } -func (ec *executionContext) fieldContext_GitHubActorClaims_workflow(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_GitHubActorClaims_runnerEnvironment(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("GitHubActorClaims", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _GitHubActorClaims_eventName(ctx context.Context, field graphql.CollectedField, obj *activitylog.GitHubActorClaims) (ret graphql.Marshaler) { +func (ec *executionContext) _GitHubActorClaims_runNumber(ctx context.Context, field graphql.CollectedField, obj *github.GitHubActorClaims) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_GitHubActorClaims_eventName(ctx, field) + return ec.fieldContext_GitHubActorClaims_runNumber(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.EventName, nil + return obj.RunNumber, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { - return ec.marshalNString2string(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *string) graphql.Marshaler { + return ec.marshalOString2ᚖstring(ctx, selections, v) }, true, - true, + false, ) } -func (ec *executionContext) fieldContext_GitHubActorClaims_eventName(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_GitHubActorClaims_runNumber(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("GitHubActorClaims", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _GitHubActorClaims_environment(ctx context.Context, field graphql.CollectedField, obj *activitylog.GitHubActorClaims) (ret graphql.Marshaler) { +func (ec *executionContext) _GitHubActorClaims_workflow(ctx context.Context, field graphql.CollectedField, obj *github.GitHubActorClaims) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_GitHubActorClaims_environment(ctx, field) + return ec.fieldContext_GitHubActorClaims_workflow(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Environment, nil + return obj.Workflow, nil }, nil, func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { @@ -560,30 +869,53 @@ func (ec *executionContext) _GitHubActorClaims_environment(ctx context.Context, true, ) } -func (ec *executionContext) fieldContext_GitHubActorClaims_environment(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_GitHubActorClaims_workflow(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("GitHubActorClaims", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _GitHubActorClaims_jobWorkflowRef(ctx context.Context, field graphql.CollectedField, obj *activitylog.GitHubActorClaims) (ret graphql.Marshaler) { +func (ec *executionContext) _GitHubActorClaims_workflowRef(ctx context.Context, field graphql.CollectedField, obj *github.GitHubActorClaims) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_GitHubActorClaims_jobWorkflowRef(ctx, field) + return ec.fieldContext_GitHubActorClaims_workflowRef(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.JobWorkflowRef, nil + return obj.WorkflowRef, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { - return ec.marshalNString2string(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *string) graphql.Marshaler { + return ec.marshalOString2ᚖstring(ctx, selections, v) }, true, + false, + ) +} +func (ec *executionContext) fieldContext_GitHubActorClaims_workflowRef(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("GitHubActorClaims", field, false, false, errors.New("field of type String does not have child fields")) +} + +func (ec *executionContext) _GitHubActorClaims_workflowSha(ctx context.Context, field graphql.CollectedField, obj *github.GitHubActorClaims) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_GitHubActorClaims_workflowSha(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.WorkflowSha, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *string) graphql.Marshaler { + return ec.marshalOString2ᚖstring(ctx, selections, v) + }, true, + false, ) } -func (ec *executionContext) fieldContext_GitHubActorClaims_jobWorkflowRef(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_GitHubActorClaims_workflowSha(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("GitHubActorClaims", field, false, false, errors.New("field of type String does not have child fields")) } @@ -689,6 +1021,8 @@ func (ec *executionContext) _GenericKubernetesResourceActivityLogEntry(ctx conte if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._GenericKubernetesResourceActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._GenericKubernetesResourceActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -794,7 +1128,7 @@ func (ec *executionContext) _GenericKubernetesResourceActivityLogEntryData(ctx c var gitHubActorClaimsImplementors = []string{"GitHubActorClaims"} -func (ec *executionContext) _GitHubActorClaims(ctx context.Context, sel ast.SelectionSet, obj *activitylog.GitHubActorClaims) graphql.Marshaler { +func (ec *executionContext) _GitHubActorClaims(ctx context.Context, sel ast.SelectionSet, obj *github.GitHubActorClaims) graphql.Marshaler { fields := graphql.CollectFields(ec.OperationContext, sel, gitHubActorClaimsImplementors) out := graphql.NewFieldSet(fields) @@ -803,56 +1137,82 @@ func (ec *executionContext) _GitHubActorClaims(ctx context.Context, sel ast.Sele switch field.Name { case "__typename": out.Values[i] = graphql.MarshalString("GitHubActorClaims") - case "ref": - out.Values[i] = ec._GitHubActorClaims_ref(ctx, field, obj) + case "actor": + out.Values[i] = ec._GitHubActorClaims_actor(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } - case "repository": - out.Values[i] = ec._GitHubActorClaims_repository(ctx, field, obj) + case "actorID": + out.Values[i] = ec._GitHubActorClaims_actorID(ctx, field, obj) + case "baseRef": + out.Values[i] = ec._GitHubActorClaims_baseRef(ctx, field, obj) + case "checkRunID": + out.Values[i] = ec._GitHubActorClaims_checkRunID(ctx, field, obj) + case "environment": + out.Values[i] = ec._GitHubActorClaims_environment(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } - case "repositoryID": - out.Values[i] = ec._GitHubActorClaims_repositoryID(ctx, field, obj) + case "eventName": + out.Values[i] = ec._GitHubActorClaims_eventName(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } - case "runID": - out.Values[i] = ec._GitHubActorClaims_runID(ctx, field, obj) + case "headRef": + out.Values[i] = ec._GitHubActorClaims_headRef(ctx, field, obj) + case "jobWorkflowRef": + out.Values[i] = ec._GitHubActorClaims_jobWorkflowRef(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } - case "runAttempt": - out.Values[i] = ec._GitHubActorClaims_runAttempt(ctx, field, obj) + case "jobWorkflowSha": + out.Values[i] = ec._GitHubActorClaims_jobWorkflowSha(ctx, field, obj) + case "ref": + out.Values[i] = ec._GitHubActorClaims_ref(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } - case "actor": - out.Values[i] = ec._GitHubActorClaims_actor(ctx, field, obj) + case "refType": + out.Values[i] = ec._GitHubActorClaims_refType(ctx, field, obj) + case "repository": + out.Values[i] = ec._GitHubActorClaims_repository(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } - case "workflow": - out.Values[i] = ec._GitHubActorClaims_workflow(ctx, field, obj) + case "repositoryID": + out.Values[i] = ec._GitHubActorClaims_repositoryID(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } - case "eventName": - out.Values[i] = ec._GitHubActorClaims_eventName(ctx, field, obj) + case "repositoryOwner": + out.Values[i] = ec._GitHubActorClaims_repositoryOwner(ctx, field, obj) + case "repositoryOwnerID": + out.Values[i] = ec._GitHubActorClaims_repositoryOwnerID(ctx, field, obj) + case "repositoryVisibility": + out.Values[i] = ec._GitHubActorClaims_repositoryVisibility(ctx, field, obj) + case "runAttempt": + out.Values[i] = ec._GitHubActorClaims_runAttempt(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } - case "environment": - out.Values[i] = ec._GitHubActorClaims_environment(ctx, field, obj) + case "runID": + out.Values[i] = ec._GitHubActorClaims_runID(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } - case "jobWorkflowRef": - out.Values[i] = ec._GitHubActorClaims_jobWorkflowRef(ctx, field, obj) + case "runnerEnvironment": + out.Values[i] = ec._GitHubActorClaims_runnerEnvironment(ctx, field, obj) + case "runNumber": + out.Values[i] = ec._GitHubActorClaims_runNumber(ctx, field, obj) + case "workflow": + out.Values[i] = ec._GitHubActorClaims_workflow(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } + case "workflowRef": + out.Values[i] = ec._GitHubActorClaims_workflowRef(ctx, field, obj) + case "workflowSha": + out.Values[i] = ec._GitHubActorClaims_workflowSha(ctx, field, obj) default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -979,7 +1339,7 @@ func (ec *executionContext) marshalNResourceChangedField2ᚖgithubᚗcomᚋnais return ec._ResourceChangedField(ctx, sel, v) } -func (ec *executionContext) marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋactivitylogᚐGitHubActorClaims(ctx context.Context, sel ast.SelectionSet, v *activitylog.GitHubActorClaims) graphql.Marshaler { +func (ec *executionContext) marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx context.Context, sel ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { if v == nil { return graphql.Null } diff --git a/internal/graph/gengql/cluster.generated.go b/internal/graph/gengql/cluster.generated.go index a57c32751..99ee4b30a 100644 --- a/internal/graph/gengql/cluster.generated.go +++ b/internal/graph/gengql/cluster.generated.go @@ -12,6 +12,7 @@ import ( "github.com/99designs/gqlgen/graphql" "github.com/nais/api/internal/activitylog" + "github.com/nais/api/internal/auth/middleware/github" "github.com/nais/api/internal/graph/ident" "github.com/nais/api/internal/kubernetes/event/pubsublog" "github.com/nais/api/internal/slug" @@ -78,6 +79,38 @@ func (ec *executionContext) fieldContext_ClusterAuditActivityLogEntry_actor(_ co return graphql.NewScalarFieldContext("ClusterAuditActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _ClusterAuditActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *pubsublog.ClusterAuditActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_ClusterAuditActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_ClusterAuditActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ClusterAuditActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _ClusterAuditActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *pubsublog.ClusterAuditActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -327,6 +360,8 @@ func (ec *executionContext) _ClusterAuditActivityLogEntry(ctx context.Context, s if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._ClusterAuditActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._ClusterAuditActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { diff --git a/internal/graph/gengql/config.generated.go b/internal/graph/gengql/config.generated.go index 17eea1452..87a7b48e7 100644 --- a/internal/graph/gengql/config.generated.go +++ b/internal/graph/gengql/config.generated.go @@ -12,6 +12,7 @@ import ( "github.com/99designs/gqlgen/graphql" "github.com/nais/api/internal/activitylog" + "github.com/nais/api/internal/auth/middleware/github" "github.com/nais/api/internal/graph/ident" "github.com/nais/api/internal/graph/model" "github.com/nais/api/internal/graph/pagination" @@ -827,6 +828,38 @@ func (ec *executionContext) fieldContext_ConfigCreatedActivityLogEntry_actor(_ c return graphql.NewScalarFieldContext("ConfigCreatedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _ConfigCreatedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *config.ConfigCreatedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_ConfigCreatedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_ConfigCreatedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ConfigCreatedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _ConfigCreatedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *config.ConfigCreatedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -1011,6 +1044,38 @@ func (ec *executionContext) fieldContext_ConfigDeletedActivityLogEntry_actor(_ c return graphql.NewScalarFieldContext("ConfigDeletedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _ConfigDeletedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *config.ConfigDeletedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_ConfigDeletedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_ConfigDeletedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ConfigDeletedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _ConfigDeletedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *config.ConfigDeletedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -1346,6 +1411,38 @@ func (ec *executionContext) fieldContext_ConfigUpdatedActivityLogEntry_actor(_ c return graphql.NewScalarFieldContext("ConfigUpdatedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _ConfigUpdatedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *config.ConfigUpdatedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_ConfigUpdatedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_ConfigUpdatedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ConfigUpdatedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _ConfigUpdatedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *config.ConfigUpdatedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -2796,6 +2893,8 @@ func (ec *executionContext) _ConfigCreatedActivityLogEntry(ctx context.Context, if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._ConfigCreatedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._ConfigCreatedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -2867,6 +2966,8 @@ func (ec *executionContext) _ConfigDeletedActivityLogEntry(ctx context.Context, if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._ConfigDeletedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._ConfigDeletedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -3124,6 +3225,8 @@ func (ec *executionContext) _ConfigUpdatedActivityLogEntry(ctx context.Context, if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._ConfigUpdatedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._ConfigUpdatedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { diff --git a/internal/graph/gengql/deployment.generated.go b/internal/graph/gengql/deployment.generated.go index 2999285fb..3e515e0c5 100644 --- a/internal/graph/gengql/deployment.generated.go +++ b/internal/graph/gengql/deployment.generated.go @@ -12,6 +12,7 @@ import ( "github.com/99designs/gqlgen/graphql" "github.com/nais/api/internal/activitylog" + "github.com/nais/api/internal/auth/middleware/github" "github.com/nais/api/internal/deployment" "github.com/nais/api/internal/deployment/deploymentactivity" "github.com/nais/api/internal/graph/ident" @@ -465,6 +466,38 @@ func (ec *executionContext) fieldContext_DeploymentActivityLogEntry_actor(_ cont return graphql.NewScalarFieldContext("DeploymentActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _DeploymentActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *deploymentactivity.DeploymentActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_DeploymentActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_DeploymentActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "DeploymentActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _DeploymentActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *deploymentactivity.DeploymentActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -1410,6 +1443,38 @@ func (ec *executionContext) fieldContext_TeamDeployKeyUpdatedActivityLogEntry_ac return graphql.NewScalarFieldContext("TeamDeployKeyUpdatedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _TeamDeployKeyUpdatedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *deploymentactivity.TeamDeployKeyUpdatedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_TeamDeployKeyUpdatedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_TeamDeployKeyUpdatedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "TeamDeployKeyUpdatedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _TeamDeployKeyUpdatedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *deploymentactivity.TeamDeployKeyUpdatedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -1855,6 +1920,8 @@ func (ec *executionContext) _DeploymentActivityLogEntry(ctx context.Context, sel if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._DeploymentActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._DeploymentActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -2403,6 +2470,8 @@ func (ec *executionContext) _TeamDeployKeyUpdatedActivityLogEntry(ctx context.Co if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._TeamDeployKeyUpdatedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._TeamDeployKeyUpdatedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { diff --git a/internal/graph/gengql/jobs.generated.go b/internal/graph/gengql/jobs.generated.go index f7774d0c3..b78204420 100644 --- a/internal/graph/gengql/jobs.generated.go +++ b/internal/graph/gengql/jobs.generated.go @@ -13,6 +13,7 @@ import ( "github.com/99designs/gqlgen/graphql" "github.com/nais/api/internal/activitylog" + "github.com/nais/api/internal/auth/middleware/github" "github.com/nais/api/internal/cost" "github.com/nais/api/internal/deployment" "github.com/nais/api/internal/graph/ident" @@ -1904,6 +1905,38 @@ func (ec *executionContext) fieldContext_JobCreatedActivityLogEntry_actor(_ cont return graphql.NewScalarFieldContext("JobCreatedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _JobCreatedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *job.JobCreatedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_JobCreatedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_JobCreatedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "JobCreatedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _JobCreatedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *job.JobCreatedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -2120,6 +2153,38 @@ func (ec *executionContext) fieldContext_JobDeletedActivityLogEntry_actor(_ cont return graphql.NewScalarFieldContext("JobDeletedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _JobDeletedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *job.JobDeletedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_JobDeletedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_JobDeletedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "JobDeletedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _JobDeletedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *job.JobDeletedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -2893,6 +2958,38 @@ func (ec *executionContext) fieldContext_JobRunDeletedActivityLogEntry_actor(_ c return graphql.NewScalarFieldContext("JobRunDeletedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _JobRunDeletedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *job.JobRunDeletedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_JobRunDeletedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_JobRunDeletedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "JobRunDeletedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _JobRunDeletedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *job.JobRunDeletedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -3591,6 +3688,38 @@ func (ec *executionContext) fieldContext_JobTriggeredActivityLogEntry_actor(_ co return graphql.NewScalarFieldContext("JobTriggeredActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _JobTriggeredActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *job.JobTriggeredActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_JobTriggeredActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_JobTriggeredActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "JobTriggeredActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _JobTriggeredActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *job.JobTriggeredActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -3775,6 +3904,38 @@ func (ec *executionContext) fieldContext_JobUpdatedActivityLogEntry_actor(_ cont return graphql.NewScalarFieldContext("JobUpdatedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _JobUpdatedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *job.JobUpdatedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_JobUpdatedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_JobUpdatedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "JobUpdatedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _JobUpdatedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *job.JobUpdatedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -3989,8 +4150,8 @@ func (ec *executionContext) _JobUpdatedActivityLogEntryData_gitHubActorClaims(ct return obj.GitHubActorClaims, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v *activitylog.GitHubActorClaims) graphql.Marshaler { - return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋactivitylogᚐGitHubActorClaims(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) }, true, false, @@ -5702,6 +5863,8 @@ func (ec *executionContext) _JobCreatedActivityLogEntry(ctx context.Context, sel if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._JobCreatedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._JobCreatedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -5778,6 +5941,8 @@ func (ec *executionContext) _JobDeletedActivityLogEntry(ctx context.Context, sel if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._JobDeletedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._JobDeletedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -6302,6 +6467,8 @@ func (ec *executionContext) _JobRunDeletedActivityLogEntry(ctx context.Context, if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._JobRunDeletedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._JobRunDeletedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -6770,6 +6937,8 @@ func (ec *executionContext) _JobTriggeredActivityLogEntry(ctx context.Context, s if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._JobTriggeredActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._JobTriggeredActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -6841,6 +7010,8 @@ func (ec *executionContext) _JobUpdatedActivityLogEntry(ctx context.Context, sel if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._JobUpdatedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._JobUpdatedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { diff --git a/internal/graph/gengql/kafka.generated.go b/internal/graph/gengql/kafka.generated.go index 57beca6fc..fab660a81 100644 --- a/internal/graph/gengql/kafka.generated.go +++ b/internal/graph/gengql/kafka.generated.go @@ -12,6 +12,7 @@ import ( "github.com/99designs/gqlgen/graphql" "github.com/nais/api/internal/activitylog" + "github.com/nais/api/internal/auth/middleware/github" "github.com/nais/api/internal/graph/ident" "github.com/nais/api/internal/graph/model" "github.com/nais/api/internal/graph/pagination" @@ -320,6 +321,38 @@ func (ec *executionContext) fieldContext_KafkaCredentialsCreatedActivityLogEntry return graphql.NewScalarFieldContext("KafkaCredentialsCreatedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _KafkaCredentialsCreatedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *kafkatopic.KafkaCredentialsCreatedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_KafkaCredentialsCreatedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_KafkaCredentialsCreatedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "KafkaCredentialsCreatedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _KafkaCredentialsCreatedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *kafkatopic.KafkaCredentialsCreatedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -1579,6 +1612,38 @@ func (ec *executionContext) fieldContext_KafkaTopicUpdatedActivityLogEntry_actor return graphql.NewScalarFieldContext("KafkaTopicUpdatedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _KafkaTopicUpdatedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *kafkatopic.KafkaTopicUpdatedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_KafkaTopicUpdatedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_KafkaTopicUpdatedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "KafkaTopicUpdatedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _KafkaTopicUpdatedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *kafkatopic.KafkaTopicUpdatedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -2388,6 +2453,8 @@ func (ec *executionContext) _KafkaCredentialsCreatedActivityLogEntry(ctx context if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._KafkaCredentialsCreatedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._KafkaCredentialsCreatedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -3229,6 +3296,8 @@ func (ec *executionContext) _KafkaTopicUpdatedActivityLogEntry(ctx context.Conte if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._KafkaTopicUpdatedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._KafkaTopicUpdatedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { diff --git a/internal/graph/gengql/opensearch.generated.go b/internal/graph/gengql/opensearch.generated.go index 96af8dbda..8d6bffd29 100644 --- a/internal/graph/gengql/opensearch.generated.go +++ b/internal/graph/gengql/opensearch.generated.go @@ -12,6 +12,7 @@ import ( "github.com/99designs/gqlgen/graphql" "github.com/nais/api/internal/activitylog" + "github.com/nais/api/internal/auth/middleware/github" "github.com/nais/api/internal/cost" "github.com/nais/api/internal/graph/ident" "github.com/nais/api/internal/graph/model" @@ -1283,6 +1284,38 @@ func (ec *executionContext) fieldContext_OpenSearchCreatedActivityLogEntry_actor return graphql.NewScalarFieldContext("OpenSearchCreatedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _OpenSearchCreatedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *opensearch.OpenSearchCreatedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_OpenSearchCreatedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_OpenSearchCreatedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "OpenSearchCreatedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _OpenSearchCreatedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *opensearch.OpenSearchCreatedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -1582,6 +1615,38 @@ func (ec *executionContext) fieldContext_OpenSearchCredentialsCreatedActivityLog return graphql.NewScalarFieldContext("OpenSearchCredentialsCreatedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _OpenSearchCredentialsCreatedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *opensearch.OpenSearchCredentialsCreatedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_OpenSearchCredentialsCreatedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_OpenSearchCredentialsCreatedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "OpenSearchCredentialsCreatedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _OpenSearchCredentialsCreatedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *opensearch.OpenSearchCredentialsCreatedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -1844,6 +1909,38 @@ func (ec *executionContext) fieldContext_OpenSearchDeletedActivityLogEntry_actor return graphql.NewScalarFieldContext("OpenSearchDeletedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _OpenSearchDeletedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *opensearch.OpenSearchDeletedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_OpenSearchDeletedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_OpenSearchDeletedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "OpenSearchDeletedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _OpenSearchDeletedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *opensearch.OpenSearchDeletedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -2225,6 +2322,38 @@ func (ec *executionContext) fieldContext_OpenSearchUpdatedActivityLogEntry_actor return graphql.NewScalarFieldContext("OpenSearchUpdatedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _OpenSearchUpdatedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *opensearch.OpenSearchUpdatedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_OpenSearchUpdatedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_OpenSearchUpdatedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "OpenSearchUpdatedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _OpenSearchUpdatedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *opensearch.OpenSearchUpdatedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -3868,6 +3997,8 @@ func (ec *executionContext) _OpenSearchCreatedActivityLogEntry(ctx context.Conte if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._OpenSearchCreatedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._OpenSearchCreatedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -3998,6 +4129,8 @@ func (ec *executionContext) _OpenSearchCredentialsCreatedActivityLogEntry(ctx co if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._OpenSearchCredentialsCreatedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._OpenSearchCredentialsCreatedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -4115,6 +4248,8 @@ func (ec *executionContext) _OpenSearchDeletedActivityLogEntry(ctx context.Conte if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._OpenSearchDeletedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._OpenSearchDeletedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -4416,6 +4551,8 @@ func (ec *executionContext) _OpenSearchUpdatedActivityLogEntry(ctx context.Conte if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._OpenSearchUpdatedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._OpenSearchUpdatedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { diff --git a/internal/graph/gengql/postgres.generated.go b/internal/graph/gengql/postgres.generated.go index 6f55b49b1..3508589f4 100644 --- a/internal/graph/gengql/postgres.generated.go +++ b/internal/graph/gengql/postgres.generated.go @@ -12,6 +12,7 @@ import ( "github.com/99designs/gqlgen/graphql" "github.com/nais/api/internal/activitylog" + "github.com/nais/api/internal/auth/middleware/github" "github.com/nais/api/internal/graph/ident" "github.com/nais/api/internal/graph/model" "github.com/nais/api/internal/graph/pagination" @@ -28,6 +29,8 @@ type PostgresAccessResolver interface { Team(ctx context.Context, obj *postgres.PostgresAccess) (*team.Team, error) TeamEnvironment(ctx context.Context, obj *postgres.PostgresAccess) (*team.TeamEnvironment, error) PostgresInstance(ctx context.Context, obj *postgres.PostgresAccess) (*postgres.PostgresInstance, error) + + Connection(ctx context.Context, obj *postgres.PostgresAccess) (*postgres.PostgresAccessConnection, error) } type PostgresInstanceResolver interface { Team(ctx context.Context, obj *postgres.PostgresInstance) (*team.Team, error) @@ -594,6 +597,38 @@ func (ec *executionContext) fieldContext_PostgresAccess_relayAccess(_ context.Co return graphql.NewScalarFieldContext("PostgresAccess", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _PostgresAccess_connection(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccess) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_PostgresAccess_connection(ctx, field) + }, + func(ctx context.Context) (any, error) { + return ec.Resolvers.PostgresAccess().Connection(ctx, obj) + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *postgres.PostgresAccessConnection) graphql.Marshaler { + return ec.marshalNPostgresAccessConnection2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccessConnection(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_PostgresAccess_connection(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "PostgresAccess", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_PostgresAccessConnection(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _PostgresAccessConnection_username(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccessConnection) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -801,6 +836,38 @@ func (ec *executionContext) fieldContext_PostgresDeletedActivityLogEntry_actor(_ return graphql.NewScalarFieldContext("PostgresDeletedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _PostgresDeletedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresDeletedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_PostgresDeletedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_PostgresDeletedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "PostgresDeletedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _PostgresDeletedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresDeletedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -985,6 +1052,38 @@ func (ec *executionContext) fieldContext_PostgresGrantAccessActivityLogEntry_act return graphql.NewScalarFieldContext("PostgresGrantAccessActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _PostgresGrantAccessActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresGrantAccessActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_PostgresGrantAccessActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_PostgresGrantAccessActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "PostgresGrantAccessActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _PostgresGrantAccessActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresGrantAccessActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -1813,6 +1912,38 @@ func (ec *executionContext) fieldContext_PostgresPersonalAccessConnectionActivit return graphql.NewScalarFieldContext("PostgresPersonalAccessConnectionActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _PostgresPersonalAccessConnectionActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresPersonalAccessConnectionActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_PostgresPersonalAccessConnectionActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_PostgresPersonalAccessConnectionActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "PostgresPersonalAccessConnectionActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _PostgresPersonalAccessConnectionActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresPersonalAccessConnectionActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -1997,6 +2128,38 @@ func (ec *executionContext) fieldContext_PostgresPersonalAccessCreatedActivityLo return graphql.NewScalarFieldContext("PostgresPersonalAccessCreatedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _PostgresPersonalAccessCreatedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresPersonalAccessCreatedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_PostgresPersonalAccessCreatedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_PostgresPersonalAccessCreatedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "PostgresPersonalAccessCreatedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _PostgresPersonalAccessCreatedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresPersonalAccessCreatedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -2441,50 +2604,6 @@ func (ec *executionContext) unmarshalInputDeletePostgresInput(ctx context.Contex return it, nil } -func (ec *executionContext) unmarshalInputPostgresAccessConnectionInput(ctx context.Context, obj any) (postgres.PostgresAccessConnectionInput, error) { - var it postgres.PostgresAccessConnectionInput - if obj == nil { - return it, nil - } - - asMap := map[string]any{} - for k, v := range obj.(map[string]any) { - asMap[k] = v - } - - fieldsInOrder := [...]string{"name", "teamSlug", "environmentName"} - for _, k := range fieldsInOrder { - v, ok := asMap[k] - if !ok { - continue - } - switch k { - case "name": - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("name")) - data, err := ec.unmarshalNString2string(ctx, v) - if err != nil { - return it, err - } - it.Name = data - case "teamSlug": - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("teamSlug")) - data, err := ec.unmarshalNSlug2githubᚗcomᚋnaisᚋapiᚋinternalᚋslugᚐSlug(ctx, v) - if err != nil { - return it, err - } - it.TeamSlug = data - case "environmentName": - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("environmentName")) - data, err := ec.unmarshalNString2string(ctx, v) - if err != nil { - return it, err - } - it.EnvironmentName = data - } - } - return it, nil -} - func (ec *executionContext) unmarshalInputPostgresInstanceFilter(ctx context.Context, obj any) (postgres.PostgresInstanceFilter, error) { var it postgres.PostgresInstanceFilter if obj == nil { @@ -2875,6 +2994,42 @@ func (ec *executionContext) _PostgresAccess(ctx context.Context, sel ast.Selecti out.Values[i] = ec._PostgresAccess_message(ctx, field, obj) case "relayAccess": out.Values[i] = ec._PostgresAccess_relayAccess(ctx, field, obj) + case "connection": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._PostgresAccess_connection(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + if field.Deferrable != nil { + dfs, ok := deferred[field.Deferrable.Label] + di := 0 + if ok { + dfs.AddField(field) + di = len(dfs.Values) - 1 + } else { + dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) + deferred[field.Deferrable.Label] = dfs + } + dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { + return innerFunc(ctx, dfs) + }) + + // don't run the out.Concurrently() call below + out.Values[i] = graphql.Null + continue + } + + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2988,6 +3143,8 @@ func (ec *executionContext) _PostgresDeletedActivityLogEntry(ctx context.Context if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._PostgresDeletedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._PostgresDeletedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -3059,6 +3216,8 @@ func (ec *executionContext) _PostgresGrantAccessActivityLogEntry(ctx context.Con if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._PostgresGrantAccessActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._PostgresGrantAccessActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -3689,6 +3848,8 @@ func (ec *executionContext) _PostgresPersonalAccessConnectionActivityLogEntry(ct if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._PostgresPersonalAccessConnectionActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._PostgresPersonalAccessConnectionActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -3760,6 +3921,8 @@ func (ec *executionContext) _PostgresPersonalAccessCreatedActivityLogEntry(ctx c if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._PostgresPersonalAccessCreatedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._PostgresPersonalAccessCreatedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -4027,11 +4190,6 @@ func (ec *executionContext) marshalNPostgresAccessConnection2ᚖgithubᚗcomᚋn return ec._PostgresAccessConnection(ctx, sel, v) } -func (ec *executionContext) unmarshalNPostgresAccessConnectionInput2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccessConnectionInput(ctx context.Context, v any) (postgres.PostgresAccessConnectionInput, error) { - res, err := ec.unmarshalInputPostgresAccessConnectionInput(ctx, v) - return res, graphql.ErrorOnPath(ctx, err) -} - func (ec *executionContext) unmarshalNPostgresAccessLevel2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccessLevel(ctx context.Context, v any) (postgres.PostgresAccessLevel, error) { var res postgres.PostgresAccessLevel err := res.UnmarshalGQL(v) diff --git a/internal/graph/gengql/reconcilers.generated.go b/internal/graph/gengql/reconcilers.generated.go index 74a83a63b..a85bfbe18 100644 --- a/internal/graph/gengql/reconcilers.generated.go +++ b/internal/graph/gengql/reconcilers.generated.go @@ -12,6 +12,7 @@ import ( "github.com/99designs/gqlgen/graphql" "github.com/nais/api/internal/activitylog" + "github.com/nais/api/internal/auth/middleware/github" "github.com/nais/api/internal/graph/ident" "github.com/nais/api/internal/graph/pagination" "github.com/nais/api/internal/reconciler" @@ -570,6 +571,38 @@ func (ec *executionContext) fieldContext_ReconcilerConfiguredActivityLogEntry_ac return graphql.NewScalarFieldContext("ReconcilerConfiguredActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _ReconcilerConfiguredActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *reconciler.ReconcilerConfiguredActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_ReconcilerConfiguredActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_ReconcilerConfiguredActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ReconcilerConfiguredActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _ReconcilerConfiguredActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *reconciler.ReconcilerConfiguredActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -905,6 +938,38 @@ func (ec *executionContext) fieldContext_ReconcilerDisabledActivityLogEntry_acto return graphql.NewScalarFieldContext("ReconcilerDisabledActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _ReconcilerDisabledActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *reconciler.ReconcilerDisabledActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_ReconcilerDisabledActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_ReconcilerDisabledActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ReconcilerDisabledActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _ReconcilerDisabledActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *reconciler.ReconcilerDisabledActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -1144,6 +1209,38 @@ func (ec *executionContext) fieldContext_ReconcilerEnabledActivityLogEntry_actor return graphql.NewScalarFieldContext("ReconcilerEnabledActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _ReconcilerEnabledActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *reconciler.ReconcilerEnabledActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_ReconcilerEnabledActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_ReconcilerEnabledActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ReconcilerEnabledActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _ReconcilerEnabledActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *reconciler.ReconcilerEnabledActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -1988,6 +2085,8 @@ func (ec *executionContext) _ReconcilerConfiguredActivityLogEntry(ctx context.Co if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._ReconcilerConfiguredActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._ReconcilerConfiguredActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -2152,6 +2251,8 @@ func (ec *executionContext) _ReconcilerDisabledActivityLogEntry(ctx context.Cont if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._ReconcilerDisabledActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._ReconcilerDisabledActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -2267,6 +2368,8 @@ func (ec *executionContext) _ReconcilerEnabledActivityLogEntry(ctx context.Conte if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._ReconcilerEnabledActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._ReconcilerEnabledActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { diff --git a/internal/graph/gengql/repository.generated.go b/internal/graph/gengql/repository.generated.go index fc391c216..9ab2ac22d 100644 --- a/internal/graph/gengql/repository.generated.go +++ b/internal/graph/gengql/repository.generated.go @@ -12,6 +12,7 @@ import ( "github.com/99designs/gqlgen/graphql" "github.com/nais/api/internal/activitylog" + "github.com/nais/api/internal/auth/middleware/github" "github.com/nais/api/internal/github/repository" "github.com/nais/api/internal/graph/ident" "github.com/nais/api/internal/graph/pagination" @@ -217,6 +218,38 @@ func (ec *executionContext) fieldContext_RepositoryAddedActivityLogEntry_actor(_ return graphql.NewScalarFieldContext("RepositoryAddedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _RepositoryAddedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *repository.RepositoryAddedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_RepositoryAddedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_RepositoryAddedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "RepositoryAddedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _RepositoryAddedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *repository.RepositoryAddedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -552,6 +585,38 @@ func (ec *executionContext) fieldContext_RepositoryRemovedActivityLogEntry_actor return graphql.NewScalarFieldContext("RepositoryRemovedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _RepositoryRemovedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *repository.RepositoryRemovedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_RepositoryRemovedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_RepositoryRemovedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "RepositoryRemovedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _RepositoryRemovedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *repository.RepositoryRemovedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -1016,6 +1081,8 @@ func (ec *executionContext) _RepositoryAddedActivityLogEntry(ctx context.Context if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._RepositoryAddedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._RepositoryAddedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -1180,6 +1247,8 @@ func (ec *executionContext) _RepositoryRemovedActivityLogEntry(ctx context.Conte if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._RepositoryRemovedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._RepositoryRemovedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { diff --git a/internal/graph/gengql/root_.generated.go b/internal/graph/gengql/root_.generated.go index f101f8594..2715b03cc 100644 --- a/internal/graph/gengql/root_.generated.go +++ b/internal/graph/gengql/root_.generated.go @@ -282,26 +282,28 @@ type ComplexityRoot struct { } ApplicationCreatedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - Data func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + Data func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } ApplicationDeletedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } ApplicationEdge struct { @@ -376,26 +378,28 @@ type ComplexityRoot struct { } ApplicationRestartedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } ApplicationScaledActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - Data func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + Data func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } ApplicationScaledActivityLogEntryData struct { @@ -415,15 +419,16 @@ type ComplexityRoot struct { } ApplicationUpdatedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - Data func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + Data func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } ApplicationUpdatedActivityLogEntryData struct { @@ -565,15 +570,16 @@ type ComplexityRoot struct { } ClusterAuditActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - Data func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + Data func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } ClusterAuditActivityLogEntryData struct { @@ -604,25 +610,27 @@ type ComplexityRoot struct { } ConfigCreatedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } ConfigDeletedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } ConfigEdge struct { @@ -637,15 +645,16 @@ type ComplexityRoot struct { } ConfigUpdatedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - Data func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + Data func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } ConfigUpdatedActivityLogEntryData struct { @@ -832,15 +841,16 @@ type ComplexityRoot struct { } DeploymentActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - Data func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + Data func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } DeploymentActivityLogEntryData struct { @@ -1007,15 +1017,16 @@ type ComplexityRoot struct { } GenericKubernetesResourceActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - Data func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + Data func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } GenericKubernetesResourceActivityLogEntryData struct { @@ -1026,16 +1037,29 @@ type ComplexityRoot struct { } GitHubActorClaims struct { - Actor func(childComplexity int) int - Environment func(childComplexity int) int - EventName func(childComplexity int) int - JobWorkflowRef func(childComplexity int) int - Ref func(childComplexity int) int - Repository func(childComplexity int) int - RepositoryID func(childComplexity int) int - RunAttempt func(childComplexity int) int - RunID func(childComplexity int) int - Workflow func(childComplexity int) int + Actor func(childComplexity int) int + ActorID func(childComplexity int) int + BaseRef func(childComplexity int) int + CheckRunID func(childComplexity int) int + Environment func(childComplexity int) int + EventName func(childComplexity int) int + HeadRef func(childComplexity int) int + JobWorkflowRef func(childComplexity int) int + JobWorkflowSha func(childComplexity int) int + Ref func(childComplexity int) int + RefType func(childComplexity int) int + Repository func(childComplexity int) int + RepositoryID func(childComplexity int) int + RepositoryOwner func(childComplexity int) int + RepositoryOwnerID func(childComplexity int) int + RepositoryVisibility func(childComplexity int) int + RunAttempt func(childComplexity int) int + RunID func(childComplexity int) int + RunNumber func(childComplexity int) int + RunnerEnvironment func(childComplexity int) int + Workflow func(childComplexity int) int + WorkflowRef func(childComplexity int) int + WorkflowSha func(childComplexity int) int } IDPortenAuthIntegration struct { @@ -1239,26 +1263,28 @@ type ComplexityRoot struct { } JobCreatedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - Data func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + Data func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } JobDeletedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } JobEdge struct { @@ -1300,15 +1326,16 @@ type ComplexityRoot struct { } JobRunDeletedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - Data func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + Data func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } JobRunDeletedActivityLogEntryData struct { @@ -1358,26 +1385,28 @@ type ComplexityRoot struct { } JobTriggeredActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } JobUpdatedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - Data func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + Data func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } JobUpdatedActivityLogEntryData struct { @@ -1395,15 +1424,16 @@ type ComplexityRoot struct { } KafkaCredentialsCreatedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - Data func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + Data func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } KafkaCredentialsCreatedActivityLogEntryData struct { @@ -1477,15 +1507,16 @@ type ComplexityRoot struct { } KafkaTopicUpdatedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - Data func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + Data func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } KafkaTopicUpdatedActivityLogEntryData struct { @@ -1717,14 +1748,15 @@ type ComplexityRoot struct { } OpenSearchCreatedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } OpenSearchCredentials struct { @@ -1736,15 +1768,16 @@ type ComplexityRoot struct { } OpenSearchCredentialsCreatedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - Data func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + Data func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } OpenSearchCredentialsCreatedActivityLogEntryData struct { @@ -1753,14 +1786,15 @@ type ComplexityRoot struct { } OpenSearchDeletedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } OpenSearchEdge struct { @@ -1812,15 +1846,16 @@ type ComplexityRoot struct { } OpenSearchUpdatedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - Data func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + Data func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } OpenSearchUpdatedActivityLogEntryData struct { @@ -1865,6 +1900,7 @@ type ComplexityRoot struct { PostgresAccess struct { AccessLevel func(childComplexity int) int + Connection func(childComplexity int) int ExpiresAt func(childComplexity int) int ID func(childComplexity int) int Message func(childComplexity int) int @@ -1887,26 +1923,28 @@ type ComplexityRoot struct { } PostgresDeletedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } PostgresGrantAccessActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - Data func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + Data func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } PostgresGrantAccessActivityLogEntryData struct { @@ -1949,26 +1987,28 @@ type ComplexityRoot struct { } PostgresPersonalAccessConnectionActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } PostgresPersonalAccessCreatedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - Data func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + Data func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } PostgresPersonalAccessCreatedActivityLogEntryData struct { @@ -2021,8 +2061,6 @@ type ComplexityRoot struct { ImageVulnerabilityHistory func(childComplexity int, from scalar.Date) int Me func(childComplexity int) int Node func(childComplexity int, id ident.Ident) int - PostgresAccess func(childComplexity int, name string, teamSlug slug.Slug, environmentName string) int - PostgresAccessConnection func(childComplexity int, input postgres.PostgresAccessConnectionInput) int Reconcilers func(childComplexity int, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor) int Roles func(childComplexity int, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, filter *authz.RoleFilter) int Search func(childComplexity int, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, filter search.SearchFilter) int @@ -2061,15 +2099,16 @@ type ComplexityRoot struct { } ReconcilerConfiguredActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - Data func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + Data func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } ReconcilerConfiguredActivityLogEntryData struct { @@ -2083,14 +2122,15 @@ type ComplexityRoot struct { } ReconcilerDisabledActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } ReconcilerEdge struct { @@ -2099,14 +2139,15 @@ type ComplexityRoot struct { } ReconcilerEnabledActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } ReconcilerError struct { @@ -2157,14 +2198,15 @@ type ComplexityRoot struct { } RepositoryAddedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } RepositoryConnection struct { @@ -2179,14 +2221,15 @@ type ComplexityRoot struct { } RepositoryRemovedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } RequestTeamDeletionPayload struct { @@ -2223,15 +2266,16 @@ type ComplexityRoot struct { } RoleAssignedToServiceAccountActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - Data func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + Data func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } RoleAssignedToServiceAccountActivityLogEntryData struct { @@ -2260,15 +2304,16 @@ type ComplexityRoot struct { } RoleRevokedFromServiceAccountActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - Data func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + Data func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } RoleRevokedFromServiceAccountActivityLogEntryData struct { @@ -2319,25 +2364,27 @@ type ComplexityRoot struct { } SecretCreatedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } SecretDeletedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } SecretEdge struct { @@ -2352,15 +2399,16 @@ type ComplexityRoot struct { } SecretUpdatedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - Data func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + Data func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } SecretUpdatedActivityLogEntryData struct { @@ -2380,15 +2428,16 @@ type ComplexityRoot struct { } SecretValueAddedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - Data func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + Data func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } SecretValueAddedActivityLogEntryData struct { @@ -2396,15 +2445,16 @@ type ComplexityRoot struct { } SecretValueRemovedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - Data func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + Data func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } SecretValueRemovedActivityLogEntryData struct { @@ -2412,15 +2462,16 @@ type ComplexityRoot struct { } SecretValueUpdatedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - Data func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + Data func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } SecretValueUpdatedActivityLogEntryData struct { @@ -2428,15 +2479,16 @@ type ComplexityRoot struct { } SecretValuesViewedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - Data func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + Data func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } SecretValuesViewedActivityLogEntryData struct { @@ -2464,25 +2516,27 @@ type ComplexityRoot struct { } ServiceAccountCreatedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } ServiceAccountDeletedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } ServiceAccountEdge struct { @@ -2507,15 +2561,16 @@ type ComplexityRoot struct { } ServiceAccountTokenCreatedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - Data func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + Data func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } ServiceAccountTokenCreatedActivityLogEntryData struct { @@ -2523,15 +2578,16 @@ type ComplexityRoot struct { } ServiceAccountTokenDeletedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - Data func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + Data func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } ServiceAccountTokenDeletedActivityLogEntryData struct { @@ -2544,15 +2600,16 @@ type ComplexityRoot struct { } ServiceAccountTokenUpdatedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - Data func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + Data func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } ServiceAccountTokenUpdatedActivityLogEntryData struct { @@ -2567,15 +2624,16 @@ type ComplexityRoot struct { } ServiceAccountUpdatedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - Data func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + Data func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } ServiceAccountUpdatedActivityLogEntryData struct { @@ -2601,15 +2659,16 @@ type ComplexityRoot struct { } ServiceAccountWorkloadBindingAddedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - Data func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + Data func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } ServiceAccountWorkloadBindingAddedActivityLogEntryData struct { @@ -2630,15 +2689,16 @@ type ComplexityRoot struct { } ServiceAccountWorkloadBindingRemovedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - Data func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + Data func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } ServiceAccountWorkloadBindingRemovedActivityLogEntryData struct { @@ -2659,14 +2719,15 @@ type ComplexityRoot struct { } ServiceMaintenanceActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } SetTeamMemberRolePayload struct { @@ -2886,14 +2947,15 @@ type ComplexityRoot struct { } TeamConfirmDeleteKeyActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } TeamConnection struct { @@ -2923,25 +2985,27 @@ type ComplexityRoot struct { } TeamCreateDeleteKeyActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } TeamCreatedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } TeamDeleteKey struct { @@ -2953,14 +3017,15 @@ type ComplexityRoot struct { } TeamDeployKeyUpdatedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } TeamEdge struct { @@ -2987,6 +3052,7 @@ type ComplexityRoot struct { Name func(childComplexity int) int OpenSearch func(childComplexity int, name string) int Postgres func(childComplexity int, name string) int + PostgresAccess func(childComplexity int, name string) int PostgresInstance func(childComplexity int, name string) int SQLInstance func(childComplexity int, name string) int Secret func(childComplexity int, name string) int @@ -3007,15 +3073,16 @@ type ComplexityRoot struct { } TeamEnvironmentUpdatedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - Data func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + Data func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } TeamEnvironmentUpdatedActivityLogEntryData struct { @@ -3120,15 +3187,16 @@ type ComplexityRoot struct { } TeamMemberAddedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - Data func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + Data func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } TeamMemberAddedActivityLogEntryData struct { @@ -3149,15 +3217,16 @@ type ComplexityRoot struct { } TeamMemberRemovedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - Data func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + Data func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } TeamMemberRemovedActivityLogEntryData struct { @@ -3166,15 +3235,16 @@ type ComplexityRoot struct { } TeamMemberSetRoleActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - Data func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + Data func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } TeamMemberSetRoleActivityLogEntryData struct { @@ -3212,15 +3282,16 @@ type ComplexityRoot struct { } TeamUpdatedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - Data func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + Data func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } TeamUpdatedActivityLogEntryData struct { @@ -3290,15 +3361,16 @@ type ComplexityRoot struct { } TunnelCreatedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - Data func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + Data func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } TunnelCreatedActivityLogEntryData struct { @@ -3307,15 +3379,16 @@ type ComplexityRoot struct { } TunnelDeletedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - Data func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + Data func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } TunnelDeletedActivityLogEntryData struct { @@ -3341,25 +3414,27 @@ type ComplexityRoot struct { } UnleashInstanceCreatedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } UnleashInstanceDeletedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } UnleashInstanceMetrics struct { @@ -3372,15 +3447,16 @@ type ComplexityRoot struct { } UnleashInstanceUpdatedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - Data func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + Data func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } UnleashInstanceUpdatedActivityLogEntryData struct { @@ -3586,14 +3662,15 @@ type ComplexityRoot struct { } ValkeyCreatedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } ValkeyCredentials struct { @@ -3605,15 +3682,16 @@ type ComplexityRoot struct { } ValkeyCredentialsCreatedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - Data func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + Data func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } ValkeyCredentialsCreatedActivityLogEntryData struct { @@ -3622,14 +3700,15 @@ type ComplexityRoot struct { } ValkeyDeletedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } ValkeyEdge struct { @@ -3681,15 +3760,16 @@ type ComplexityRoot struct { } ValkeyUpdatedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - Data func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + Data func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } ValkeyUpdatedActivityLogEntryData struct { @@ -3734,15 +3814,16 @@ type ComplexityRoot struct { } VulnerabilityUpdatedActivityLogEntry struct { - Actor func(childComplexity int) int - CreatedAt func(childComplexity int) int - Data func(childComplexity int) int - EnvironmentName func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - ResourceName func(childComplexity int) int - ResourceType func(childComplexity int) int - TeamSlug func(childComplexity int) int + Actor func(childComplexity int) int + CreatedAt func(childComplexity int) int + Data func(childComplexity int) int + EnvironmentName func(childComplexity int) int + GitHubActorClaims func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + ResourceName func(childComplexity int) int + ResourceType func(childComplexity int) int + TeamSlug func(childComplexity int) int } VulnerableImageIssue struct { @@ -4456,6 +4537,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.ApplicationCreatedActivityLogEntry.EnvironmentName(childComplexity), true + case "ApplicationCreatedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.ApplicationCreatedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.ApplicationCreatedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "ApplicationCreatedActivityLogEntry.id": if e.ComplexityRoot.ApplicationCreatedActivityLogEntry.ID == nil { break @@ -4512,6 +4600,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.ApplicationDeletedActivityLogEntry.EnvironmentName(childComplexity), true + case "ApplicationDeletedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.ApplicationDeletedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.ApplicationDeletedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "ApplicationDeletedActivityLogEntry.id": if e.ComplexityRoot.ApplicationDeletedActivityLogEntry.ID == nil { break @@ -4839,6 +4934,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.ApplicationRestartedActivityLogEntry.EnvironmentName(childComplexity), true + case "ApplicationRestartedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.ApplicationRestartedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.ApplicationRestartedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "ApplicationRestartedActivityLogEntry.id": if e.ComplexityRoot.ApplicationRestartedActivityLogEntry.ID == nil { break @@ -4902,6 +5004,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.ApplicationScaledActivityLogEntry.EnvironmentName(childComplexity), true + case "ApplicationScaledActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.ApplicationScaledActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.ApplicationScaledActivityLogEntry.GitHubActorClaims(childComplexity), true + case "ApplicationScaledActivityLogEntry.id": if e.ComplexityRoot.ApplicationScaledActivityLogEntry.ID == nil { break @@ -5014,6 +5123,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.ApplicationUpdatedActivityLogEntry.EnvironmentName(childComplexity), true + case "ApplicationUpdatedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.ApplicationUpdatedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.ApplicationUpdatedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "ApplicationUpdatedActivityLogEntry.id": if e.ComplexityRoot.ApplicationUpdatedActivityLogEntry.ID == nil { break @@ -5591,6 +5707,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.ClusterAuditActivityLogEntry.EnvironmentName(childComplexity), true + case "ClusterAuditActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.ClusterAuditActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.ClusterAuditActivityLogEntry.GitHubActorClaims(childComplexity), true + case "ClusterAuditActivityLogEntry.id": if e.ComplexityRoot.ClusterAuditActivityLogEntry.ID == nil { break @@ -5793,6 +5916,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.ConfigCreatedActivityLogEntry.EnvironmentName(childComplexity), true + case "ConfigCreatedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.ConfigCreatedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.ConfigCreatedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "ConfigCreatedActivityLogEntry.id": if e.ComplexityRoot.ConfigCreatedActivityLogEntry.ID == nil { break @@ -5849,6 +5979,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.ConfigDeletedActivityLogEntry.EnvironmentName(childComplexity), true + case "ConfigDeletedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.ConfigDeletedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.ConfigDeletedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "ConfigDeletedActivityLogEntry.id": if e.ComplexityRoot.ConfigDeletedActivityLogEntry.ID == nil { break @@ -5947,6 +6084,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.ConfigUpdatedActivityLogEntry.EnvironmentName(childComplexity), true + case "ConfigUpdatedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.ConfigUpdatedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.ConfigUpdatedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "ConfigUpdatedActivityLogEntry.id": if e.ComplexityRoot.ConfigUpdatedActivityLogEntry.ID == nil { break @@ -6539,6 +6683,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.DeploymentActivityLogEntry.EnvironmentName(childComplexity), true + case "DeploymentActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.DeploymentActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.DeploymentActivityLogEntry.GitHubActorClaims(childComplexity), true + case "DeploymentActivityLogEntry.id": if e.ComplexityRoot.DeploymentActivityLogEntry.ID == nil { break @@ -7207,6 +7358,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.GenericKubernetesResourceActivityLogEntry.EnvironmentName(childComplexity), true + case "GenericKubernetesResourceActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.GenericKubernetesResourceActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.GenericKubernetesResourceActivityLogEntry.GitHubActorClaims(childComplexity), true + case "GenericKubernetesResourceActivityLogEntry.id": if e.ComplexityRoot.GenericKubernetesResourceActivityLogEntry.ID == nil { break @@ -7277,6 +7435,27 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.GitHubActorClaims.Actor(childComplexity), true + case "GitHubActorClaims.actorID": + if e.ComplexityRoot.GitHubActorClaims.ActorID == nil { + break + } + + return e.ComplexityRoot.GitHubActorClaims.ActorID(childComplexity), true + + case "GitHubActorClaims.baseRef": + if e.ComplexityRoot.GitHubActorClaims.BaseRef == nil { + break + } + + return e.ComplexityRoot.GitHubActorClaims.BaseRef(childComplexity), true + + case "GitHubActorClaims.checkRunID": + if e.ComplexityRoot.GitHubActorClaims.CheckRunID == nil { + break + } + + return e.ComplexityRoot.GitHubActorClaims.CheckRunID(childComplexity), true + case "GitHubActorClaims.environment": if e.ComplexityRoot.GitHubActorClaims.Environment == nil { break @@ -7291,6 +7470,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.GitHubActorClaims.EventName(childComplexity), true + case "GitHubActorClaims.headRef": + if e.ComplexityRoot.GitHubActorClaims.HeadRef == nil { + break + } + + return e.ComplexityRoot.GitHubActorClaims.HeadRef(childComplexity), true + case "GitHubActorClaims.jobWorkflowRef": if e.ComplexityRoot.GitHubActorClaims.JobWorkflowRef == nil { break @@ -7298,6 +7484,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.GitHubActorClaims.JobWorkflowRef(childComplexity), true + case "GitHubActorClaims.jobWorkflowSha": + if e.ComplexityRoot.GitHubActorClaims.JobWorkflowSha == nil { + break + } + + return e.ComplexityRoot.GitHubActorClaims.JobWorkflowSha(childComplexity), true + case "GitHubActorClaims.ref": if e.ComplexityRoot.GitHubActorClaims.Ref == nil { break @@ -7305,6 +7498,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.GitHubActorClaims.Ref(childComplexity), true + case "GitHubActorClaims.refType": + if e.ComplexityRoot.GitHubActorClaims.RefType == nil { + break + } + + return e.ComplexityRoot.GitHubActorClaims.RefType(childComplexity), true + case "GitHubActorClaims.repository": if e.ComplexityRoot.GitHubActorClaims.Repository == nil { break @@ -7319,6 +7519,27 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.GitHubActorClaims.RepositoryID(childComplexity), true + case "GitHubActorClaims.repositoryOwner": + if e.ComplexityRoot.GitHubActorClaims.RepositoryOwner == nil { + break + } + + return e.ComplexityRoot.GitHubActorClaims.RepositoryOwner(childComplexity), true + + case "GitHubActorClaims.repositoryOwnerID": + if e.ComplexityRoot.GitHubActorClaims.RepositoryOwnerID == nil { + break + } + + return e.ComplexityRoot.GitHubActorClaims.RepositoryOwnerID(childComplexity), true + + case "GitHubActorClaims.repositoryVisibility": + if e.ComplexityRoot.GitHubActorClaims.RepositoryVisibility == nil { + break + } + + return e.ComplexityRoot.GitHubActorClaims.RepositoryVisibility(childComplexity), true + case "GitHubActorClaims.runAttempt": if e.ComplexityRoot.GitHubActorClaims.RunAttempt == nil { break @@ -7333,6 +7554,20 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.GitHubActorClaims.RunID(childComplexity), true + case "GitHubActorClaims.runNumber": + if e.ComplexityRoot.GitHubActorClaims.RunNumber == nil { + break + } + + return e.ComplexityRoot.GitHubActorClaims.RunNumber(childComplexity), true + + case "GitHubActorClaims.runnerEnvironment": + if e.ComplexityRoot.GitHubActorClaims.RunnerEnvironment == nil { + break + } + + return e.ComplexityRoot.GitHubActorClaims.RunnerEnvironment(childComplexity), true + case "GitHubActorClaims.workflow": if e.ComplexityRoot.GitHubActorClaims.Workflow == nil { break @@ -7340,6 +7575,20 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.GitHubActorClaims.Workflow(childComplexity), true + case "GitHubActorClaims.workflowRef": + if e.ComplexityRoot.GitHubActorClaims.WorkflowRef == nil { + break + } + + return e.ComplexityRoot.GitHubActorClaims.WorkflowRef(childComplexity), true + + case "GitHubActorClaims.workflowSha": + if e.ComplexityRoot.GitHubActorClaims.WorkflowSha == nil { + break + } + + return e.ComplexityRoot.GitHubActorClaims.WorkflowSha(childComplexity), true + case "IDPortenAuthIntegration.name": if e.ComplexityRoot.IDPortenAuthIntegration.Name == nil { break @@ -8313,6 +8562,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.JobCreatedActivityLogEntry.EnvironmentName(childComplexity), true + case "JobCreatedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.JobCreatedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.JobCreatedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "JobCreatedActivityLogEntry.id": if e.ComplexityRoot.JobCreatedActivityLogEntry.ID == nil { break @@ -8369,6 +8625,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.JobDeletedActivityLogEntry.EnvironmentName(childComplexity), true + case "JobDeletedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.JobDeletedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.JobDeletedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "JobDeletedActivityLogEntry.id": if e.ComplexityRoot.JobDeletedActivityLogEntry.ID == nil { break @@ -8577,6 +8840,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.JobRunDeletedActivityLogEntry.EnvironmentName(childComplexity), true + case "JobRunDeletedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.JobRunDeletedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.JobRunDeletedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "JobRunDeletedActivityLogEntry.id": if e.ComplexityRoot.JobRunDeletedActivityLogEntry.ID == nil { break @@ -8766,6 +9036,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.JobTriggeredActivityLogEntry.EnvironmentName(childComplexity), true + case "JobTriggeredActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.JobTriggeredActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.JobTriggeredActivityLogEntry.GitHubActorClaims(childComplexity), true + case "JobTriggeredActivityLogEntry.id": if e.ComplexityRoot.JobTriggeredActivityLogEntry.ID == nil { break @@ -8829,6 +9106,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.JobUpdatedActivityLogEntry.EnvironmentName(childComplexity), true + case "JobUpdatedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.JobUpdatedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.JobUpdatedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "JobUpdatedActivityLogEntry.id": if e.ComplexityRoot.JobUpdatedActivityLogEntry.ID == nil { break @@ -8948,6 +9232,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.KafkaCredentialsCreatedActivityLogEntry.EnvironmentName(childComplexity), true + case "KafkaCredentialsCreatedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.KafkaCredentialsCreatedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.KafkaCredentialsCreatedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "KafkaCredentialsCreatedActivityLogEntry.id": if e.ComplexityRoot.KafkaCredentialsCreatedActivityLogEntry.ID == nil { break @@ -9296,6 +9587,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.KafkaTopicUpdatedActivityLogEntry.EnvironmentName(childComplexity), true + case "KafkaTopicUpdatedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.KafkaTopicUpdatedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.KafkaTopicUpdatedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "KafkaTopicUpdatedActivityLogEntry.id": if e.ComplexityRoot.KafkaTopicUpdatedActivityLogEntry.ID == nil { break @@ -10747,6 +11045,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.OpenSearchCreatedActivityLogEntry.EnvironmentName(childComplexity), true + case "OpenSearchCreatedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.OpenSearchCreatedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.OpenSearchCreatedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "OpenSearchCreatedActivityLogEntry.id": if e.ComplexityRoot.OpenSearchCreatedActivityLogEntry.ID == nil { break @@ -10845,6 +11150,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.OpenSearchCredentialsCreatedActivityLogEntry.EnvironmentName(childComplexity), true + case "OpenSearchCredentialsCreatedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.OpenSearchCredentialsCreatedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.OpenSearchCredentialsCreatedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "OpenSearchCredentialsCreatedActivityLogEntry.id": if e.ComplexityRoot.OpenSearchCredentialsCreatedActivityLogEntry.ID == nil { break @@ -10915,6 +11227,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.OpenSearchDeletedActivityLogEntry.EnvironmentName(childComplexity), true + case "OpenSearchDeletedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.OpenSearchDeletedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.OpenSearchDeletedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "OpenSearchDeletedActivityLogEntry.id": if e.ComplexityRoot.OpenSearchDeletedActivityLogEntry.ID == nil { break @@ -11151,6 +11470,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.OpenSearchUpdatedActivityLogEntry.EnvironmentName(childComplexity), true + case "OpenSearchUpdatedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.OpenSearchUpdatedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.OpenSearchUpdatedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "OpenSearchUpdatedActivityLogEntry.id": if e.ComplexityRoot.OpenSearchUpdatedActivityLogEntry.ID == nil { break @@ -11347,6 +11673,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.PostgresAccess.AccessLevel(childComplexity), true + case "PostgresAccess.connection": + if e.ComplexityRoot.PostgresAccess.Connection == nil { + break + } + + return e.ComplexityRoot.PostgresAccess.Connection(childComplexity), true + case "PostgresAccess.expiresAt": if e.ComplexityRoot.PostgresAccess.ExpiresAt == nil { break @@ -11480,6 +11813,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.PostgresDeletedActivityLogEntry.EnvironmentName(childComplexity), true + case "PostgresDeletedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.PostgresDeletedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.PostgresDeletedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "PostgresDeletedActivityLogEntry.id": if e.ComplexityRoot.PostgresDeletedActivityLogEntry.ID == nil { break @@ -11543,6 +11883,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.PostgresGrantAccessActivityLogEntry.EnvironmentName(childComplexity), true + case "PostgresGrantAccessActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.PostgresGrantAccessActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.PostgresGrantAccessActivityLogEntry.GitHubActorClaims(childComplexity), true + case "PostgresGrantAccessActivityLogEntry.id": if e.ComplexityRoot.PostgresGrantAccessActivityLogEntry.ID == nil { break @@ -11751,6 +12098,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.PostgresPersonalAccessConnectionActivityLogEntry.EnvironmentName(childComplexity), true + case "PostgresPersonalAccessConnectionActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.PostgresPersonalAccessConnectionActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.PostgresPersonalAccessConnectionActivityLogEntry.GitHubActorClaims(childComplexity), true + case "PostgresPersonalAccessConnectionActivityLogEntry.id": if e.ComplexityRoot.PostgresPersonalAccessConnectionActivityLogEntry.ID == nil { break @@ -11814,6 +12168,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.PostgresPersonalAccessCreatedActivityLogEntry.EnvironmentName(childComplexity), true + case "PostgresPersonalAccessCreatedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.PostgresPersonalAccessCreatedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.PostgresPersonalAccessCreatedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "PostgresPersonalAccessCreatedActivityLogEntry.id": if e.ComplexityRoot.PostgresPersonalAccessCreatedActivityLogEntry.ID == nil { break @@ -12132,30 +12493,6 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.Query.Node(childComplexity, args["id"].(ident.Ident)), true - case "Query.postgresAccess": - if e.ComplexityRoot.Query.PostgresAccess == nil { - break - } - - args, err := ec.field_Query_postgresAccess_args(ctx, rawArgs) - if err != nil { - return 0, false - } - - return e.ComplexityRoot.Query.PostgresAccess(childComplexity, args["name"].(string), args["teamSlug"].(slug.Slug), args["environmentName"].(string)), true - - case "Query.postgresAccessConnection": - if e.ComplexityRoot.Query.PostgresAccessConnection == nil { - break - } - - args, err := ec.field_Query_postgresAccessConnection_args(ctx, rawArgs) - if err != nil { - return 0, false - } - - return e.ComplexityRoot.Query.PostgresAccessConnection(childComplexity, args["input"].(postgres.PostgresAccessConnectionInput)), true - case "Query.reconcilers": if e.ComplexityRoot.Query.Reconcilers == nil { break @@ -12457,6 +12794,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.ReconcilerConfiguredActivityLogEntry.EnvironmentName(childComplexity), true + case "ReconcilerConfiguredActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.ReconcilerConfiguredActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.ReconcilerConfiguredActivityLogEntry.GitHubActorClaims(childComplexity), true + case "ReconcilerConfiguredActivityLogEntry.id": if e.ComplexityRoot.ReconcilerConfiguredActivityLogEntry.ID == nil { break @@ -12541,6 +12885,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.ReconcilerDisabledActivityLogEntry.EnvironmentName(childComplexity), true + case "ReconcilerDisabledActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.ReconcilerDisabledActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.ReconcilerDisabledActivityLogEntry.GitHubActorClaims(childComplexity), true + case "ReconcilerDisabledActivityLogEntry.id": if e.ComplexityRoot.ReconcilerDisabledActivityLogEntry.ID == nil { break @@ -12611,6 +12962,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.ReconcilerEnabledActivityLogEntry.EnvironmentName(childComplexity), true + case "ReconcilerEnabledActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.ReconcilerEnabledActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.ReconcilerEnabledActivityLogEntry.GitHubActorClaims(childComplexity), true + case "ReconcilerEnabledActivityLogEntry.id": if e.ComplexityRoot.ReconcilerEnabledActivityLogEntry.ID == nil { break @@ -12807,6 +13165,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.RepositoryAddedActivityLogEntry.EnvironmentName(childComplexity), true + case "RepositoryAddedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.RepositoryAddedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.RepositoryAddedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "RepositoryAddedActivityLogEntry.id": if e.ComplexityRoot.RepositoryAddedActivityLogEntry.ID == nil { break @@ -12898,6 +13263,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.RepositoryRemovedActivityLogEntry.EnvironmentName(childComplexity), true + case "RepositoryRemovedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.RepositoryRemovedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.RepositoryRemovedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "RepositoryRemovedActivityLogEntry.id": if e.ComplexityRoot.RepositoryRemovedActivityLogEntry.ID == nil { break @@ -13045,6 +13417,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.RoleAssignedToServiceAccountActivityLogEntry.EnvironmentName(childComplexity), true + case "RoleAssignedToServiceAccountActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.RoleAssignedToServiceAccountActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.RoleAssignedToServiceAccountActivityLogEntry.GitHubActorClaims(childComplexity), true + case "RoleAssignedToServiceAccountActivityLogEntry.id": if e.ComplexityRoot.RoleAssignedToServiceAccountActivityLogEntry.ID == nil { break @@ -13199,6 +13578,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.RoleRevokedFromServiceAccountActivityLogEntry.EnvironmentName(childComplexity), true + case "RoleRevokedFromServiceAccountActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.RoleRevokedFromServiceAccountActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.RoleRevokedFromServiceAccountActivityLogEntry.GitHubActorClaims(childComplexity), true + case "RoleRevokedFromServiceAccountActivityLogEntry.id": if e.ComplexityRoot.RoleRevokedFromServiceAccountActivityLogEntry.ID == nil { break @@ -13478,6 +13864,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.SecretCreatedActivityLogEntry.EnvironmentName(childComplexity), true + case "SecretCreatedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.SecretCreatedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.SecretCreatedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "SecretCreatedActivityLogEntry.id": if e.ComplexityRoot.SecretCreatedActivityLogEntry.ID == nil { break @@ -13534,6 +13927,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.SecretDeletedActivityLogEntry.EnvironmentName(childComplexity), true + case "SecretDeletedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.SecretDeletedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.SecretDeletedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "SecretDeletedActivityLogEntry.id": if e.ComplexityRoot.SecretDeletedActivityLogEntry.ID == nil { break @@ -13632,6 +14032,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.SecretUpdatedActivityLogEntry.EnvironmentName(childComplexity), true + case "SecretUpdatedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.SecretUpdatedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.SecretUpdatedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "SecretUpdatedActivityLogEntry.id": if e.ComplexityRoot.SecretUpdatedActivityLogEntry.ID == nil { break @@ -13744,6 +14151,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.SecretValueAddedActivityLogEntry.EnvironmentName(childComplexity), true + case "SecretValueAddedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.SecretValueAddedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.SecretValueAddedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "SecretValueAddedActivityLogEntry.id": if e.ComplexityRoot.SecretValueAddedActivityLogEntry.ID == nil { break @@ -13814,6 +14228,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.SecretValueRemovedActivityLogEntry.EnvironmentName(childComplexity), true + case "SecretValueRemovedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.SecretValueRemovedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.SecretValueRemovedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "SecretValueRemovedActivityLogEntry.id": if e.ComplexityRoot.SecretValueRemovedActivityLogEntry.ID == nil { break @@ -13884,6 +14305,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.SecretValueUpdatedActivityLogEntry.EnvironmentName(childComplexity), true + case "SecretValueUpdatedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.SecretValueUpdatedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.SecretValueUpdatedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "SecretValueUpdatedActivityLogEntry.id": if e.ComplexityRoot.SecretValueUpdatedActivityLogEntry.ID == nil { break @@ -13954,6 +14382,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.SecretValuesViewedActivityLogEntry.EnvironmentName(childComplexity), true + case "SecretValuesViewedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.SecretValuesViewedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.SecretValuesViewedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "SecretValuesViewedActivityLogEntry.id": if e.ComplexityRoot.SecretValuesViewedActivityLogEntry.ID == nil { break @@ -14135,6 +14570,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.ServiceAccountCreatedActivityLogEntry.EnvironmentName(childComplexity), true + case "ServiceAccountCreatedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.ServiceAccountCreatedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.ServiceAccountCreatedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "ServiceAccountCreatedActivityLogEntry.id": if e.ComplexityRoot.ServiceAccountCreatedActivityLogEntry.ID == nil { break @@ -14191,6 +14633,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.ServiceAccountDeletedActivityLogEntry.EnvironmentName(childComplexity), true + case "ServiceAccountDeletedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.ServiceAccountDeletedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.ServiceAccountDeletedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "ServiceAccountDeletedActivityLogEntry.id": if e.ComplexityRoot.ServiceAccountDeletedActivityLogEntry.ID == nil { break @@ -14338,6 +14787,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.ServiceAccountTokenCreatedActivityLogEntry.EnvironmentName(childComplexity), true + case "ServiceAccountTokenCreatedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.ServiceAccountTokenCreatedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.ServiceAccountTokenCreatedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "ServiceAccountTokenCreatedActivityLogEntry.id": if e.ComplexityRoot.ServiceAccountTokenCreatedActivityLogEntry.ID == nil { break @@ -14408,6 +14864,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.ServiceAccountTokenDeletedActivityLogEntry.EnvironmentName(childComplexity), true + case "ServiceAccountTokenDeletedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.ServiceAccountTokenDeletedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.ServiceAccountTokenDeletedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "ServiceAccountTokenDeletedActivityLogEntry.id": if e.ComplexityRoot.ServiceAccountTokenDeletedActivityLogEntry.ID == nil { break @@ -14492,6 +14955,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.ServiceAccountTokenUpdatedActivityLogEntry.EnvironmentName(childComplexity), true + case "ServiceAccountTokenUpdatedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.ServiceAccountTokenUpdatedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.ServiceAccountTokenUpdatedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "ServiceAccountTokenUpdatedActivityLogEntry.id": if e.ComplexityRoot.ServiceAccountTokenUpdatedActivityLogEntry.ID == nil { break @@ -14590,6 +15060,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.ServiceAccountUpdatedActivityLogEntry.EnvironmentName(childComplexity), true + case "ServiceAccountUpdatedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.ServiceAccountUpdatedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.ServiceAccountUpdatedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "ServiceAccountUpdatedActivityLogEntry.id": if e.ComplexityRoot.ServiceAccountUpdatedActivityLogEntry.ID == nil { break @@ -14744,6 +15221,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.ServiceAccountWorkloadBindingAddedActivityLogEntry.EnvironmentName(childComplexity), true + case "ServiceAccountWorkloadBindingAddedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.ServiceAccountWorkloadBindingAddedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.ServiceAccountWorkloadBindingAddedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "ServiceAccountWorkloadBindingAddedActivityLogEntry.id": if e.ComplexityRoot.ServiceAccountWorkloadBindingAddedActivityLogEntry.ID == nil { break @@ -14863,6 +15347,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.ServiceAccountWorkloadBindingRemovedActivityLogEntry.EnvironmentName(childComplexity), true + case "ServiceAccountWorkloadBindingRemovedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.ServiceAccountWorkloadBindingRemovedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.ServiceAccountWorkloadBindingRemovedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "ServiceAccountWorkloadBindingRemovedActivityLogEntry.id": if e.ComplexityRoot.ServiceAccountWorkloadBindingRemovedActivityLogEntry.ID == nil { break @@ -14975,6 +15466,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.ServiceMaintenanceActivityLogEntry.EnvironmentName(childComplexity), true + case "ServiceMaintenanceActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.ServiceMaintenanceActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.ServiceMaintenanceActivityLogEntry.GitHubActorClaims(childComplexity), true + case "ServiceMaintenanceActivityLogEntry.id": if e.ComplexityRoot.ServiceMaintenanceActivityLogEntry.ID == nil { break @@ -16136,6 +16634,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.TeamConfirmDeleteKeyActivityLogEntry.EnvironmentName(childComplexity), true + case "TeamConfirmDeleteKeyActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.TeamConfirmDeleteKeyActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.TeamConfirmDeleteKeyActivityLogEntry.GitHubActorClaims(childComplexity), true + case "TeamConfirmDeleteKeyActivityLogEntry.id": if e.ComplexityRoot.TeamConfirmDeleteKeyActivityLogEntry.ID == nil { break @@ -16274,6 +16779,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.TeamCreateDeleteKeyActivityLogEntry.EnvironmentName(childComplexity), true + case "TeamCreateDeleteKeyActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.TeamCreateDeleteKeyActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.TeamCreateDeleteKeyActivityLogEntry.GitHubActorClaims(childComplexity), true + case "TeamCreateDeleteKeyActivityLogEntry.id": if e.ComplexityRoot.TeamCreateDeleteKeyActivityLogEntry.ID == nil { break @@ -16330,6 +16842,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.TeamCreatedActivityLogEntry.EnvironmentName(childComplexity), true + case "TeamCreatedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.TeamCreatedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.TeamCreatedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "TeamCreatedActivityLogEntry.id": if e.ComplexityRoot.TeamCreatedActivityLogEntry.ID == nil { break @@ -16421,6 +16940,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.TeamDeployKeyUpdatedActivityLogEntry.EnvironmentName(childComplexity), true + case "TeamDeployKeyUpdatedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.TeamDeployKeyUpdatedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.TeamDeployKeyUpdatedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "TeamDeployKeyUpdatedActivityLogEntry.id": if e.ComplexityRoot.TeamDeployKeyUpdatedActivityLogEntry.ID == nil { break @@ -16620,6 +17146,18 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.TeamEnvironment.Postgres(childComplexity, args["name"].(string)), true + case "TeamEnvironment.postgresAccess": + if e.ComplexityRoot.TeamEnvironment.PostgresAccess == nil { + break + } + + args, err := ec.field_TeamEnvironment_postgresAccess_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.ComplexityRoot.TeamEnvironment.PostgresAccess(childComplexity, args["name"].(string)), true + case "TeamEnvironment.postgresInstance": if e.ComplexityRoot.TeamEnvironment.PostgresInstance == nil { break @@ -16760,6 +17298,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.TeamEnvironmentUpdatedActivityLogEntry.EnvironmentName(childComplexity), true + case "TeamEnvironmentUpdatedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.TeamEnvironmentUpdatedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.TeamEnvironmentUpdatedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "TeamEnvironmentUpdatedActivityLogEntry.id": if e.ComplexityRoot.TeamEnvironmentUpdatedActivityLogEntry.ID == nil { break @@ -17131,6 +17676,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.TeamMemberAddedActivityLogEntry.EnvironmentName(childComplexity), true + case "TeamMemberAddedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.TeamMemberAddedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.TeamMemberAddedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "TeamMemberAddedActivityLogEntry.id": if e.ComplexityRoot.TeamMemberAddedActivityLogEntry.ID == nil { break @@ -17250,6 +17802,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.TeamMemberRemovedActivityLogEntry.EnvironmentName(childComplexity), true + case "TeamMemberRemovedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.TeamMemberRemovedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.TeamMemberRemovedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "TeamMemberRemovedActivityLogEntry.id": if e.ComplexityRoot.TeamMemberRemovedActivityLogEntry.ID == nil { break @@ -17327,6 +17886,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.TeamMemberSetRoleActivityLogEntry.EnvironmentName(childComplexity), true + case "TeamMemberSetRoleActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.TeamMemberSetRoleActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.TeamMemberSetRoleActivityLogEntry.GitHubActorClaims(childComplexity), true + case "TeamMemberSetRoleActivityLogEntry.id": if e.ComplexityRoot.TeamMemberSetRoleActivityLogEntry.ID == nil { break @@ -17502,6 +18068,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.TeamUpdatedActivityLogEntry.EnvironmentName(childComplexity), true + case "TeamUpdatedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.TeamUpdatedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.TeamUpdatedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "TeamUpdatedActivityLogEntry.id": if e.ComplexityRoot.TeamUpdatedActivityLogEntry.ID == nil { break @@ -17859,6 +18432,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.TunnelCreatedActivityLogEntry.EnvironmentName(childComplexity), true + case "TunnelCreatedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.TunnelCreatedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.TunnelCreatedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "TunnelCreatedActivityLogEntry.id": if e.ComplexityRoot.TunnelCreatedActivityLogEntry.ID == nil { break @@ -17936,6 +18516,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.TunnelDeletedActivityLogEntry.EnvironmentName(childComplexity), true + case "TunnelDeletedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.TunnelDeletedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.TunnelDeletedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "TunnelDeletedActivityLogEntry.id": if e.ComplexityRoot.TunnelDeletedActivityLogEntry.ID == nil { break @@ -18088,6 +18675,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.UnleashInstanceCreatedActivityLogEntry.EnvironmentName(childComplexity), true + case "UnleashInstanceCreatedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.UnleashInstanceCreatedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.UnleashInstanceCreatedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "UnleashInstanceCreatedActivityLogEntry.id": if e.ComplexityRoot.UnleashInstanceCreatedActivityLogEntry.ID == nil { break @@ -18144,6 +18738,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.UnleashInstanceDeletedActivityLogEntry.EnvironmentName(childComplexity), true + case "UnleashInstanceDeletedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.UnleashInstanceDeletedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.UnleashInstanceDeletedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "UnleashInstanceDeletedActivityLogEntry.id": if e.ComplexityRoot.UnleashInstanceDeletedActivityLogEntry.ID == nil { break @@ -18249,6 +18850,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.UnleashInstanceUpdatedActivityLogEntry.EnvironmentName(childComplexity), true + case "UnleashInstanceUpdatedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.UnleashInstanceUpdatedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.UnleashInstanceUpdatedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "UnleashInstanceUpdatedActivityLogEntry.id": if e.ComplexityRoot.UnleashInstanceUpdatedActivityLogEntry.ID == nil { break @@ -19046,6 +19654,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.ValkeyCreatedActivityLogEntry.EnvironmentName(childComplexity), true + case "ValkeyCreatedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.ValkeyCreatedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.ValkeyCreatedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "ValkeyCreatedActivityLogEntry.id": if e.ComplexityRoot.ValkeyCreatedActivityLogEntry.ID == nil { break @@ -19144,6 +19759,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.ValkeyCredentialsCreatedActivityLogEntry.EnvironmentName(childComplexity), true + case "ValkeyCredentialsCreatedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.ValkeyCredentialsCreatedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.ValkeyCredentialsCreatedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "ValkeyCredentialsCreatedActivityLogEntry.id": if e.ComplexityRoot.ValkeyCredentialsCreatedActivityLogEntry.ID == nil { break @@ -19214,6 +19836,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.ValkeyDeletedActivityLogEntry.EnvironmentName(childComplexity), true + case "ValkeyDeletedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.ValkeyDeletedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.ValkeyDeletedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "ValkeyDeletedActivityLogEntry.id": if e.ComplexityRoot.ValkeyDeletedActivityLogEntry.ID == nil { break @@ -19450,6 +20079,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.ValkeyUpdatedActivityLogEntry.EnvironmentName(childComplexity), true + case "ValkeyUpdatedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.ValkeyUpdatedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.ValkeyUpdatedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "ValkeyUpdatedActivityLogEntry.id": if e.ComplexityRoot.ValkeyUpdatedActivityLogEntry.ID == nil { break @@ -19653,6 +20289,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.VulnerabilityUpdatedActivityLogEntry.EnvironmentName(childComplexity), true + case "VulnerabilityUpdatedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.VulnerabilityUpdatedActivityLogEntry.GitHubActorClaims == nil { + break + } + + return e.ComplexityRoot.VulnerabilityUpdatedActivityLogEntry.GitHubActorClaims(childComplexity), true + case "VulnerabilityUpdatedActivityLogEntry.id": if e.ComplexityRoot.VulnerabilityUpdatedActivityLogEntry.ID == nil { break @@ -20258,7 +20901,6 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { ec.unmarshalInputOpenSearchAccessOrder, ec.unmarshalInputOpenSearchFilter, ec.unmarshalInputOpenSearchOrder, - ec.unmarshalInputPostgresAccessConnectionInput, ec.unmarshalInputPostgresInstanceFilter, ec.unmarshalInputPostgresInstanceOrder, ec.unmarshalInputReconcilerConfigInput, @@ -20685,6 +21327,9 @@ interface ActivityLogEntry implements Node { """ actor: String! + "GitHub Actions OIDC claims captured when the action was authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + """ Creation time of the entry. """ @@ -21873,6 +22518,9 @@ type ApplicationDeletedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -21899,6 +22547,9 @@ type ApplicationRestartedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -21927,6 +22578,9 @@ type ApplicationScaledActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -21973,6 +22627,9 @@ type ApplicationCreatedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -22003,6 +22660,7 @@ type ApplicationUpdatedActivityLogEntryData { changedFields: [ResourceChangedField!]! "GitHub Actions OIDC token claims at the time of the apply. Only present when the request was authenticated via a GitHub token." gitHubActorClaims: GitHubActorClaims + @deprecated(reason: "Use gitHubActorClaims on the activity log entry instead.") } """ @@ -22015,6 +22673,9 @@ type ApplicationUpdatedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -22076,32 +22737,60 @@ type GenericKubernetesResourceActivityLogEntryData { changedFields: [ResourceChangedField!]! "GitHub Actions OIDC token claims at the time of the apply. Only present when the request was authenticated via a GitHub token." gitHubActorClaims: GitHubActorClaims + @deprecated(reason: "Use gitHubActorClaims on the activity log entry instead.") } """ -GitHub Actions OIDC token claims captured at the time of an apply operation. +GitHub Actions OIDC token claims captured when an activity log entry is created. +See https://docs.github.com/en/actions/reference/security/oidc#custom-claims-provided-by-github """ type GitHubActorClaims { + "The GitHub username that triggered the workflow." + actor: String! + "The ID of the personal account that initiated the workflow run." + actorID: String + "The target branch of the pull request in a workflow run." + baseRef: String + "The check run ID of the current job." + checkRunID: String + "The GitHub deployment environment name, if the job targets one." + environment: String! + "The event that triggered the workflow, e.g. 'push' or 'workflow_dispatch'." + eventName: String! + "The source branch of the pull request in a workflow run." + headRef: String + "The ref of the reusable workflow called by this job, if any. E.g. 'org/repo/.github/workflows/deploy.yaml@refs/heads/main'." + jobWorkflowRef: String! + "The commit SHA for the reusable workflow file, if the job uses one." + jobWorkflowSha: String "The git ref that triggered the workflow, e.g. 'refs/heads/main'." ref: String! + "The type of ref, e.g. 'branch'." + refType: String "The repository name that triggered the workflow, e.g. 'org/repo'." repository: String! "The immutable numeric GitHub repository ID." repositoryID: String! - "The unique identifier of the Actions workflow run. Links to https://github.com//actions/runs/." - runID: String! + "The name of the organization in which the repository is stored." + repositoryOwner: String + "The ID of the organization in which the repository is stored." + repositoryOwnerID: String + "The visibility of the repository, e.g. 'internal', 'private', or 'public'." + repositoryVisibility: String "The attempt number of the workflow run (1-indexed)." runAttempt: String! - "The GitHub username that triggered the workflow." - actor: String! + "The unique identifier of the Actions workflow run. Links to https://github.com//actions/runs/." + runID: String! + "The type of runner used by the job, e.g. 'github-hosted' or 'self-hosted'." + runnerEnvironment: String + "The number of times this workflow has been run." + runNumber: String "The path to the workflow file, e.g. '.github/workflows/deploy.yaml'." workflow: String! - "The event that triggered the workflow, e.g. 'push' or 'workflow_dispatch'." - eventName: String! - "The GitHub deployment environment name, if the job targets one." - environment: String! - "The ref of the reusable workflow called by this job, if any. E.g. 'org/repo/.github/workflows/deploy.yaml@refs/heads/main'." - jobWorkflowRef: String! + "The ref path to the workflow, e.g. 'org/repo/.github/workflows/deploy.yaml@refs/heads/main'." + workflowRef: String + "The commit SHA for the workflow file." + workflowSha: String } """ @@ -22127,6 +22816,9 @@ type GenericKubernetesResourceActivityLogEntry implements ActivityLogEntry & Nod "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -22542,6 +23234,9 @@ type ClusterAuditActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -23011,6 +23706,9 @@ type ConfigCreatedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -23037,6 +23735,9 @@ type ConfigUpdatedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -23082,6 +23783,9 @@ type ConfigDeletedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -23694,6 +24398,9 @@ type TeamDeployKeyUpdatedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -23722,6 +24429,9 @@ type DeploymentActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -25124,6 +25834,9 @@ type JobDeletedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -25150,6 +25863,9 @@ type JobTriggeredActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -25195,6 +25911,9 @@ type JobRunDeletedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -25229,6 +25948,9 @@ type JobCreatedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -25261,6 +25983,9 @@ type JobUpdatedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -25291,6 +26016,7 @@ type JobUpdatedActivityLogEntryData { changedFields: [ResourceChangedField!]! "GitHub Actions OIDC token claims at the time of the apply. Only present when the request was authenticated via a GitHub token." gitHubActorClaims: GitHubActorClaims + @deprecated(reason: "Use gitHubActorClaims on the activity log entry instead.") } extend enum ActivityLogActivityType { @@ -25619,6 +26345,9 @@ type KafkaCredentialsCreatedActivityLogEntry implements ActivityLogEntry & Node "The identity of the actor who performed the action." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -25653,6 +26382,9 @@ type KafkaTopicUpdatedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -26409,6 +27141,9 @@ type OpenSearchCreatedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -26435,6 +27170,9 @@ type OpenSearchUpdatedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -26487,6 +27225,9 @@ type OpenSearchDeletedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -26544,6 +27285,9 @@ type OpenSearchCredentialsCreatedActivityLogEntry implements ActivityLogEntry & "The identity of the actor who performed the action." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -26651,9 +27395,20 @@ type WorkloadLogLine { extend type TeamEnvironment { "Postgres in the team environment." - postgres(name: String!): Postgres! + postgres( + "Name of the Postgres in this team environment." + name: String! + ): Postgres! "Named PostgresInstance in the team environment." - postgresInstance(name: String!): PostgresInstance! + postgresInstance( + "Name of the PostgresInstance in this team environment." + name: String! + ): PostgresInstance! + "Get a PostgresAccess and its state. Available to authorized team members." + postgresAccess( + "Name of the PostgresAccess in this team environment." + name: String! + ): PostgresAccess! } extend interface Workload { @@ -26680,8 +27435,11 @@ extend type Job { ): PostgresInstanceConnection! } +"Ordering options for Postgres instances." input PostgresInstanceOrder { + "Field to order instances by." field: PostgresInstanceOrderField! + "Direction of the ordering." direction: OrderDirection! } @@ -26702,53 +27460,88 @@ input PostgresInstanceFilter { labels: [LabelFilter!] } +"Fields available when ordering Postgres instances." enum PostgresInstanceOrderField { + "Instance name." NAME + "Environment name." ENVIRONMENT } "A named PostgresInstance belonging to a Postgres." type PostgresInstance implements Persistence & Node { + "Opaque identifier for this instance." id: ID! + "Name of the instance." name: String! + "Team owning this instance." team: Team! + "Team environment containing this instance." teamEnvironment: TeamEnvironment! "Postgres owning this PostgresInstance." postgres: Postgres! "Workloads using this instance while it is active." - workloads(first: Int, after: Cursor, last: Int, before: Cursor): WorkloadConnection! + workloads( + "Return the first n workloads." + first: Int + "Return workloads after this cursor." + after: Cursor + "Return the last n workloads." + last: Int + "Return workloads before this cursor." + before: Cursor + ): WorkloadConnection! + "Current observed state of the instance." state: PostgresInstanceState! + "User-defined labels on this instance." labels: [ResourceLabel!]! } "A Postgres whose active instance can change." type Postgres implements Node { + "Opaque identifier for this Postgres." id: ID! + "Name of this Postgres." name: String! + "Configured PostgreSQL major version." majorVersion: String! + "Whether high availability is configured." highAvailability: Boolean! "Requested CPU, memory and disk size, when present on this Postgres." resources: PostgresResources! + "Name of the currently active PostgresInstance, if selected." activeInstance: String + "User-defined labels on this Postgres." labels: [ResourceLabel!]! } "Resource requests configured on Postgres. Omitted requests are null." type PostgresResources { + "Requested CPU." cpu: String + "Requested memory." memory: String + "Requested disk size." diskSize: String } +"Reconciliation and observed health of a PostgresInstance." enum PostgresInstanceState { + "The instance is healthy and ready." AVAILABLE + "The instance is provisioning or its state has not been observed yet." PROGRESSING + "The instance has reported a failure." DEGRADED } +"Paginated PostgresInstance results." type PostgresInstanceConnection { + "Pagination metadata." pageInfo: PageInfo! + "Instances in this page." nodes: [PostgresInstance!]! + "Instances and their pagination cursors." edges: [PostgresInstanceEdge!]! """ @@ -26758,8 +27551,11 @@ type PostgresInstanceConnection { facets: PostgresInstanceFacets } +"A PostgresInstance and its pagination cursor." type PostgresInstanceEdge { + "Cursor identifying this result." cursor: Cursor! + "The matching instance." node: PostgresInstance! } @@ -26799,8 +27595,7 @@ extend enum ActivityLogEntryResourceType { POSTGRES } -# This is managed directly by the activitylog package since it -# combines data within the database. +"An earlier Postgres access grant recorded in the activity log." type PostgresGrantAccessActivityLogEntry implements ActivityLogEntry & Node { "ID of the entry." id: ID! @@ -26808,6 +27603,9 @@ type PostgresGrantAccessActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -26830,8 +27628,11 @@ type PostgresGrantAccessActivityLogEntry implements ActivityLogEntry & Node { data: PostgresGrantAccessActivityLogEntryData! } +"Details of an earlier Postgres access grant." type PostgresGrantAccessActivityLogEntryData { + "Identity that received access." grantee: String! + "End of the granted access period." until: Time! } @@ -26841,6 +27642,8 @@ type PostgresPersonalAccessCreatedActivityLogEntry implements ActivityLogEntry & id: ID! "The identity of the actor who created the personal access." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims "Creation time of the entry." createdAt: Time! "Message that summarizes the entry." @@ -26873,6 +27676,8 @@ type PostgresPersonalAccessConnectionActivityLogEntry implements ActivityLogEntr id: ID! "Identity that retrieved the connection materials." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims "Creation time of the entry." createdAt: Time! "Message that summarizes the entry." @@ -26894,6 +27699,9 @@ type PostgresDeletedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -26935,7 +27743,7 @@ extend enum ActivityLogActivityType { extend type Mutation { """ Create time-limited personal access to a NAIS Postgres instance through the brokered PostgresAccess and relay flow. - Use this for new NAIS Postgres personal access. When the access is ready, retrieve its connection materials with postgresAccessConnection. + When the access is ready, retrieve its connection materials through PostgresAccess.connection. """ createPostgresAccess(input: CreatePostgresAccessInput!): CreatePostgresAccessPayload! "Delete a PostgresInstance that is not active on its Postgres." @@ -26976,6 +27784,7 @@ enum PostgresAccessLevel { READWRITECREATE } +"Input identifying the PostgresInstance to delete." input DeletePostgresInput { "Name of the Postgres instance." name: String! @@ -26985,37 +27794,23 @@ input DeletePostgresInput { teamSlug: Slug! } +"Result of requesting deletion of a PostgresInstance." type DeletePostgresPayload { "Whether or not the Postgres instance was deleted." postgresDeleted: Boolean } extend type TeamInventoryCounts { + "Counts of Postgres instances owned by the team." postgresInstances: TeamInventoryCountPostgresInstances! } +"Inventory totals for Postgres instances." type TeamInventoryCountPostgresInstances { "Total number of Postgres instances." total: Int! } -extend type Query { - "Get connection materials for a ready personal Postgres access owned by the caller." - postgresAccessConnection(input: PostgresAccessConnectionInput!): PostgresAccessConnection! - - "Get a personal PostgresAccess resource and its state. Available to authorized team members." - postgresAccess( - "Name of the PostgresAccess resource." - name: String! - - "Team slug that owns the Postgres instance." - teamSlug: Slug! - - "Environment name that the Postgres instance belongs to." - environmentName: String! - ): PostgresAccess! -} - "A time-limited personal access request for a Postgres instance." type PostgresAccess implements Node { "Opaque ID for this PostgresAccess resource." @@ -27038,6 +27833,8 @@ type PostgresAccess implements Node { message: String "Name of the controller-owned relay mapping, once created. Contains no credential." relayAccess: String + "Get connection materials for this ready access. Only its owner can read them." + connection: PostgresAccessConnection! } "High-level reconciliation state of a personal Postgres access." @@ -27052,16 +27849,6 @@ enum PostgresAccessState { EXPIRED } -"Input for retrieving connection materials for a ready personal access." -input PostgresAccessConnectionInput { - "Name of the PostgresAccess resource." - name: String! - "Team that owns the PostgresAccess resource." - teamSlug: Slug! - "Environment containing the PostgresAccess resource." - environmentName: String! -} - "Sensitive connection materials for a ready personal Postgres access." type PostgresAccessConnection { "Database username for the caller's personal role." @@ -27280,6 +28067,9 @@ type ReconcilerEnabledActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -27306,6 +28096,9 @@ type ReconcilerDisabledActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -27332,6 +28125,9 @@ type ReconcilerConfiguredActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -27504,6 +28300,9 @@ type RepositoryAddedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -27530,6 +28329,9 @@ type RepositoryRemovedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -28292,6 +29094,9 @@ type SecretCreatedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -28318,6 +29123,9 @@ type SecretUpdatedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -28363,6 +29171,9 @@ type SecretValueAddedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -28397,6 +29208,9 @@ type SecretValueUpdatedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -28431,6 +29245,9 @@ type SecretValueRemovedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -28465,6 +29282,9 @@ type SecretDeletedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -28511,6 +29331,9 @@ type SecretValuesViewedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -28722,6 +29545,9 @@ type ServiceAccountWorkloadBindingAddedActivityLogEntry implements ActivityLogEn """ actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + """ Creation time of the entry. """ @@ -28786,6 +29612,9 @@ type ServiceAccountWorkloadBindingRemovedActivityLogEntry implements ActivityLog """ actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + """ Creation time of the entry. """ @@ -29395,6 +30224,9 @@ type ServiceAccountCreatedActivityLogEntry implements ActivityLogEntry & Node { """ actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + """ Creation time of the entry. """ @@ -29437,6 +30269,9 @@ type ServiceAccountUpdatedActivityLogEntry implements ActivityLogEntry & Node { """ actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + """ Creation time of the entry. """ @@ -29508,6 +30343,9 @@ type ServiceAccountDeletedActivityLogEntry implements ActivityLogEntry & Node { """ actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + """ Creation time of the entry. """ @@ -29550,6 +30388,9 @@ type RoleAssignedToServiceAccountActivityLogEntry implements ActivityLogEntry & """ actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + """ Creation time of the entry. """ @@ -29604,6 +30445,9 @@ type RoleRevokedFromServiceAccountActivityLogEntry implements ActivityLogEntry & """ actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + """ Creation time of the entry. """ @@ -29658,6 +30502,9 @@ type ServiceAccountTokenCreatedActivityLogEntry implements ActivityLogEntry & No """ actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + """ Creation time of the entry. """ @@ -29712,6 +30559,9 @@ type ServiceAccountTokenUpdatedActivityLogEntry implements ActivityLogEntry & No """ actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + """ Creation time of the entry. """ @@ -29788,6 +30638,9 @@ type ServiceAccountTokenDeletedActivityLogEntry implements ActivityLogEntry & No """ actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + """ Creation time of the entry. """ @@ -30016,6 +30869,9 @@ type ServiceMaintenanceActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -30784,6 +31640,9 @@ type TeamCreatedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -30810,6 +31669,9 @@ type TeamUpdatedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -30855,6 +31717,9 @@ type TeamCreateDeleteKeyActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -30881,6 +31746,9 @@ type TeamConfirmDeleteKeyActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -30907,6 +31775,9 @@ type TeamMemberAddedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -30947,6 +31818,9 @@ type TeamMemberRemovedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -30984,6 +31858,9 @@ type TeamMemberSetRoleActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -31024,6 +31901,9 @@ type TeamEnvironmentUpdatedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -31303,6 +32183,9 @@ type TunnelCreatedActivityLogEntry implements ActivityLogEntry & Node { """ actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + """ Creation time of the entry. """ @@ -31362,6 +32245,9 @@ type TunnelDeletedActivityLogEntry implements ActivityLogEntry & Node { """ actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + """ Creation time of the entry. """ @@ -31592,6 +32478,9 @@ type UnleashInstanceCreatedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -31618,6 +32507,9 @@ type UnleashInstanceUpdatedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -31658,6 +32550,9 @@ type UnleashInstanceDeletedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -32684,6 +33579,9 @@ type ValkeyCreatedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -32710,6 +33608,9 @@ type ValkeyUpdatedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -32762,6 +33663,9 @@ type ValkeyDeletedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -32819,6 +33723,9 @@ type ValkeyCredentialsCreatedActivityLogEntry implements ActivityLogEntry & Node "The identity of the actor who performed the action." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -33706,6 +34613,9 @@ type VulnerabilityUpdatedActivityLogEntry implements ActivityLogEntry & Node { """ actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + """ Creation time of the entry. """ @@ -35616,26 +36526,52 @@ func (ec *executionContext) childFields_GenericKubernetesResourceActivityLogEntr func (ec *executionContext) childFields_GitHubActorClaims(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { switch field.Name { + case "actor": + return ec.fieldContext_GitHubActorClaims_actor(ctx, field) + case "actorID": + return ec.fieldContext_GitHubActorClaims_actorID(ctx, field) + case "baseRef": + return ec.fieldContext_GitHubActorClaims_baseRef(ctx, field) + case "checkRunID": + return ec.fieldContext_GitHubActorClaims_checkRunID(ctx, field) + case "environment": + return ec.fieldContext_GitHubActorClaims_environment(ctx, field) + case "eventName": + return ec.fieldContext_GitHubActorClaims_eventName(ctx, field) + case "headRef": + return ec.fieldContext_GitHubActorClaims_headRef(ctx, field) + case "jobWorkflowRef": + return ec.fieldContext_GitHubActorClaims_jobWorkflowRef(ctx, field) + case "jobWorkflowSha": + return ec.fieldContext_GitHubActorClaims_jobWorkflowSha(ctx, field) case "ref": return ec.fieldContext_GitHubActorClaims_ref(ctx, field) + case "refType": + return ec.fieldContext_GitHubActorClaims_refType(ctx, field) case "repository": return ec.fieldContext_GitHubActorClaims_repository(ctx, field) case "repositoryID": return ec.fieldContext_GitHubActorClaims_repositoryID(ctx, field) - case "runID": - return ec.fieldContext_GitHubActorClaims_runID(ctx, field) + case "repositoryOwner": + return ec.fieldContext_GitHubActorClaims_repositoryOwner(ctx, field) + case "repositoryOwnerID": + return ec.fieldContext_GitHubActorClaims_repositoryOwnerID(ctx, field) + case "repositoryVisibility": + return ec.fieldContext_GitHubActorClaims_repositoryVisibility(ctx, field) case "runAttempt": return ec.fieldContext_GitHubActorClaims_runAttempt(ctx, field) - case "actor": - return ec.fieldContext_GitHubActorClaims_actor(ctx, field) + case "runID": + return ec.fieldContext_GitHubActorClaims_runID(ctx, field) + case "runnerEnvironment": + return ec.fieldContext_GitHubActorClaims_runnerEnvironment(ctx, field) + case "runNumber": + return ec.fieldContext_GitHubActorClaims_runNumber(ctx, field) case "workflow": return ec.fieldContext_GitHubActorClaims_workflow(ctx, field) - case "eventName": - return ec.fieldContext_GitHubActorClaims_eventName(ctx, field) - case "environment": - return ec.fieldContext_GitHubActorClaims_environment(ctx, field) - case "jobWorkflowRef": - return ec.fieldContext_GitHubActorClaims_jobWorkflowRef(ctx, field) + case "workflowRef": + return ec.fieldContext_GitHubActorClaims_workflowRef(ctx, field) + case "workflowSha": + return ec.fieldContext_GitHubActorClaims_workflowSha(ctx, field) } return nil, fmt.Errorf("no field named %q was found under type GitHubActorClaims", field.Name) } @@ -36780,6 +37716,8 @@ func (ec *executionContext) childFields_PostgresAccess(ctx context.Context, fiel return ec.fieldContext_PostgresAccess_message(ctx, field) case "relayAccess": return ec.fieldContext_PostgresAccess_relayAccess(ctx, field) + case "connection": + return ec.fieldContext_PostgresAccess_connection(ctx, field) } return nil, fmt.Errorf("no field named %q was found under type PostgresAccess", field.Name) } @@ -38128,6 +39066,8 @@ func (ec *executionContext) childFields_TeamEnvironment(ctx context.Context, fie return ec.fieldContext_TeamEnvironment_postgres(ctx, field) case "postgresInstance": return ec.fieldContext_TeamEnvironment_postgresInstance(ctx, field) + case "postgresAccess": + return ec.fieldContext_TeamEnvironment_postgresAccess(ctx, field) case "secret": return ec.fieldContext_TeamEnvironment_secret(ctx, field) case "sqlInstance": diff --git a/internal/graph/gengql/schema.generated.go b/internal/graph/gengql/schema.generated.go index 0a1428564..6241db4c8 100644 --- a/internal/graph/gengql/schema.generated.go +++ b/internal/graph/gengql/schema.generated.go @@ -140,8 +140,6 @@ type QueryResolver interface { Environments(ctx context.Context, orderBy *environment.EnvironmentOrder) (*pagination.Connection[*environment.Environment], error) Environment(ctx context.Context, name string) (*environment.Environment, error) Features(ctx context.Context) (*feature.Features, error) - PostgresAccessConnection(ctx context.Context, input postgres.PostgresAccessConnectionInput) (*postgres.PostgresAccessConnection, error) - PostgresAccess(ctx context.Context, name string, teamSlug slug.Slug, environmentName string) (*postgres.PostgresAccess, error) CurrentUnitPrices(ctx context.Context) (*price.CurrentUnitPrices, error) Reconcilers(ctx context.Context, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor) (*pagination.Connection[*reconciler.Reconciler], error) Search(ctx context.Context, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, filter search.SearchFilter) (*pagination.Connection[search.SearchNode], error) @@ -1346,50 +1344,6 @@ func (ec *executionContext) field_Query_node_args(ctx context.Context, rawArgs m return args, nil } -func (ec *executionContext) field_Query_postgresAccessConnection_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { - var err error - args := map[string]any{} - arg0, err := graphql.ProcessArgField(ctx, rawArgs, "input", - func(ctx context.Context, v any) (postgres.PostgresAccessConnectionInput, error) { - return ec.unmarshalNPostgresAccessConnectionInput2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccessConnectionInput(ctx, v) - }) - if err != nil { - return nil, err - } - args["input"] = arg0 - return args, nil -} - -func (ec *executionContext) field_Query_postgresAccess_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { - var err error - args := map[string]any{} - arg0, err := graphql.ProcessArgField(ctx, rawArgs, "name", - func(ctx context.Context, v any) (string, error) { - return ec.unmarshalNString2string(ctx, v) - }) - if err != nil { - return nil, err - } - args["name"] = arg0 - arg1, err := graphql.ProcessArgField(ctx, rawArgs, "teamSlug", - func(ctx context.Context, v any) (slug.Slug, error) { - return ec.unmarshalNSlug2githubᚗcomᚋnaisᚋapiᚋinternalᚋslugᚐSlug(ctx, v) - }) - if err != nil { - return nil, err - } - args["teamSlug"] = arg1 - arg2, err := graphql.ProcessArgField(ctx, rawArgs, "environmentName", - func(ctx context.Context, v any) (string, error) { - return ec.unmarshalNString2string(ctx, v) - }) - if err != nil { - return nil, err - } - args["environmentName"] = arg2 - return args, nil -} - func (ec *executionContext) field_Query_reconcilers_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} @@ -5207,94 +5161,6 @@ func (ec *executionContext) fieldContext_Query_features(_ context.Context, field return fc, nil } -func (ec *executionContext) _Query_postgresAccessConnection(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { - return graphql.ResolveField( - ctx, - ec.OperationContext, - field, - func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_Query_postgresAccessConnection(ctx, field) - }, - func(ctx context.Context) (any, error) { - fc := graphql.GetFieldContext(ctx) - return ec.Resolvers.Query().PostgresAccessConnection(ctx, fc.Args["input"].(postgres.PostgresAccessConnectionInput)) - }, - nil, - func(ctx context.Context, selections ast.SelectionSet, v *postgres.PostgresAccessConnection) graphql.Marshaler { - return ec.marshalNPostgresAccessConnection2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccessConnection(ctx, selections, v) - }, - true, - true, - ) -} -func (ec *executionContext) fieldContext_Query_postgresAccessConnection(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Query", - Field: field, - IsMethod: true, - IsResolver: true, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_PostgresAccessConnection(ctx, field) - }, - } - defer func() { - if r := recover(); r != nil { - err = ec.Recover(ctx, r) - ec.Error(ctx, err) - } - }() - ctx = graphql.WithFieldContext(ctx, fc) - if fc.Args, err = ec.field_Query_postgresAccessConnection_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { - ec.Error(ctx, err) - return fc, err - } - return fc, nil -} - -func (ec *executionContext) _Query_postgresAccess(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { - return graphql.ResolveField( - ctx, - ec.OperationContext, - field, - func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_Query_postgresAccess(ctx, field) - }, - func(ctx context.Context) (any, error) { - fc := graphql.GetFieldContext(ctx) - return ec.Resolvers.Query().PostgresAccess(ctx, fc.Args["name"].(string), fc.Args["teamSlug"].(slug.Slug), fc.Args["environmentName"].(string)) - }, - nil, - func(ctx context.Context, selections ast.SelectionSet, v *postgres.PostgresAccess) graphql.Marshaler { - return ec.marshalNPostgresAccess2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccess(ctx, selections, v) - }, - true, - true, - ) -} -func (ec *executionContext) fieldContext_Query_postgresAccess(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "Query", - Field: field, - IsMethod: true, - IsResolver: true, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_PostgresAccess(ctx, field) - }, - } - defer func() { - if r := recover(); r != nil { - err = ec.Recover(ctx, r) - ec.Error(ctx, err) - } - }() - ctx = graphql.WithFieldContext(ctx, fc) - if fc.Args, err = ec.field_Query_postgresAccess_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { - ec.Error(ctx, err) - return fc, err - } - return fc, nil -} - func (ec *executionContext) _Query_currentUnitPrices(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -7989,50 +7855,6 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) } - out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) - case "postgresAccessConnection": - field := field - - innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - } - }() - res = ec._Query_postgresAccessConnection(ctx, field) - if res == graphql.Null { - atomic.AddUint32(&fs.Invalids, 1) - } - return res - } - - rrm := func(ctx context.Context) graphql.Marshaler { - return ec.OperationContext.RootResolverMiddleware(ctx, - func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) - } - - out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) - case "postgresAccess": - field := field - - innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { - defer func() { - if r := recover(); r != nil { - ec.Error(ctx, ec.Recover(ctx, r)) - } - }() - res = ec._Query_postgresAccess(ctx, field) - if res == graphql.Null { - atomic.AddUint32(&fs.Invalids, 1) - } - return res - } - - rrm := func(ctx context.Context) graphql.Marshaler { - return ec.OperationContext.RootResolverMiddleware(ctx, - func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) - } - out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return rrm(innerCtx) }) case "currentUnitPrices": field := field diff --git a/internal/graph/gengql/secret.generated.go b/internal/graph/gengql/secret.generated.go index 9caf66762..5fc522d9c 100644 --- a/internal/graph/gengql/secret.generated.go +++ b/internal/graph/gengql/secret.generated.go @@ -12,6 +12,7 @@ import ( "github.com/99designs/gqlgen/graphql" "github.com/nais/api/internal/activitylog" + "github.com/nais/api/internal/auth/middleware/github" "github.com/nais/api/internal/graph/ident" "github.com/nais/api/internal/graph/model" "github.com/nais/api/internal/graph/pagination" @@ -903,6 +904,38 @@ func (ec *executionContext) fieldContext_SecretCreatedActivityLogEntry_actor(_ c return graphql.NewScalarFieldContext("SecretCreatedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _SecretCreatedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *secret.SecretCreatedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_SecretCreatedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_SecretCreatedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "SecretCreatedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _SecretCreatedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *secret.SecretCreatedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -1087,6 +1120,38 @@ func (ec *executionContext) fieldContext_SecretDeletedActivityLogEntry_actor(_ c return graphql.NewScalarFieldContext("SecretDeletedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _SecretDeletedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *secret.SecretDeletedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_SecretDeletedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_SecretDeletedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "SecretDeletedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _SecretDeletedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *secret.SecretDeletedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -1422,6 +1487,38 @@ func (ec *executionContext) fieldContext_SecretUpdatedActivityLogEntry_actor(_ c return graphql.NewScalarFieldContext("SecretUpdatedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _SecretUpdatedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *secret.SecretUpdatedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_SecretUpdatedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_SecretUpdatedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "SecretUpdatedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _SecretUpdatedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *secret.SecretUpdatedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -1808,6 +1905,38 @@ func (ec *executionContext) fieldContext_SecretValueAddedActivityLogEntry_actor( return graphql.NewScalarFieldContext("SecretValueAddedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _SecretValueAddedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *secret.SecretValueAddedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_SecretValueAddedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_SecretValueAddedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "SecretValueAddedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _SecretValueAddedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *secret.SecretValueAddedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -2047,6 +2176,38 @@ func (ec *executionContext) fieldContext_SecretValueRemovedActivityLogEntry_acto return graphql.NewScalarFieldContext("SecretValueRemovedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _SecretValueRemovedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *secret.SecretValueRemovedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_SecretValueRemovedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_SecretValueRemovedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "SecretValueRemovedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _SecretValueRemovedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *secret.SecretValueRemovedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -2286,6 +2447,38 @@ func (ec *executionContext) fieldContext_SecretValueUpdatedActivityLogEntry_acto return graphql.NewScalarFieldContext("SecretValueUpdatedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _SecretValueUpdatedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *secret.SecretValueUpdatedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_SecretValueUpdatedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_SecretValueUpdatedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "SecretValueUpdatedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _SecretValueUpdatedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *secret.SecretValueUpdatedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -2525,6 +2718,38 @@ func (ec *executionContext) fieldContext_SecretValuesViewedActivityLogEntry_acto return graphql.NewScalarFieldContext("SecretValuesViewedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _SecretValuesViewedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *secret.SecretValuesViewedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_SecretValuesViewedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_SecretValuesViewedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "SecretValuesViewedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _SecretValuesViewedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *secret.SecretValuesViewedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -3880,6 +4105,8 @@ func (ec *executionContext) _SecretCreatedActivityLogEntry(ctx context.Context, if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._SecretCreatedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._SecretCreatedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -3951,6 +4178,8 @@ func (ec *executionContext) _SecretDeletedActivityLogEntry(ctx context.Context, if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._SecretDeletedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._SecretDeletedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -4208,6 +4437,8 @@ func (ec *executionContext) _SecretUpdatedActivityLogEntry(ctx context.Context, if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._SecretUpdatedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._SecretUpdatedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -4415,6 +4646,8 @@ func (ec *executionContext) _SecretValueAddedActivityLogEntry(ctx context.Contex if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._SecretValueAddedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._SecretValueAddedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -4530,6 +4763,8 @@ func (ec *executionContext) _SecretValueRemovedActivityLogEntry(ctx context.Cont if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._SecretValueRemovedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._SecretValueRemovedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -4645,6 +4880,8 @@ func (ec *executionContext) _SecretValueUpdatedActivityLogEntry(ctx context.Cont if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._SecretValueUpdatedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._SecretValueUpdatedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -4760,6 +4997,8 @@ func (ec *executionContext) _SecretValuesViewedActivityLogEntry(ctx context.Cont if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._SecretValuesViewedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._SecretValuesViewedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { diff --git a/internal/graph/gengql/serviceaccount_workload_bindings.generated.go b/internal/graph/gengql/serviceaccount_workload_bindings.generated.go index 021dde1d4..62467a6c9 100644 --- a/internal/graph/gengql/serviceaccount_workload_bindings.generated.go +++ b/internal/graph/gengql/serviceaccount_workload_bindings.generated.go @@ -12,6 +12,7 @@ import ( "github.com/99designs/gqlgen/graphql" "github.com/nais/api/internal/activitylog" + "github.com/nais/api/internal/auth/middleware/github" "github.com/nais/api/internal/graph/ident" "github.com/nais/api/internal/graph/pagination" "github.com/nais/api/internal/serviceaccount" @@ -431,6 +432,38 @@ func (ec *executionContext) fieldContext_ServiceAccountWorkloadBindingAddedActiv return graphql.NewScalarFieldContext("ServiceAccountWorkloadBindingAddedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _ServiceAccountWorkloadBindingAddedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *serviceaccount.ServiceAccountWorkloadBindingAddedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_ServiceAccountWorkloadBindingAddedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_ServiceAccountWorkloadBindingAddedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ServiceAccountWorkloadBindingAddedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _ServiceAccountWorkloadBindingAddedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *serviceaccount.ServiceAccountWorkloadBindingAddedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -867,6 +900,38 @@ func (ec *executionContext) fieldContext_ServiceAccountWorkloadBindingRemovedAct return graphql.NewScalarFieldContext("ServiceAccountWorkloadBindingRemovedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _ServiceAccountWorkloadBindingRemovedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *serviceaccount.ServiceAccountWorkloadBindingRemovedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_ServiceAccountWorkloadBindingRemovedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_ServiceAccountWorkloadBindingRemovedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ServiceAccountWorkloadBindingRemovedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _ServiceAccountWorkloadBindingRemovedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *serviceaccount.ServiceAccountWorkloadBindingRemovedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -1462,6 +1527,8 @@ func (ec *executionContext) _ServiceAccountWorkloadBindingAddedActivityLogEntry( if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._ServiceAccountWorkloadBindingAddedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._ServiceAccountWorkloadBindingAddedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -1674,6 +1741,8 @@ func (ec *executionContext) _ServiceAccountWorkloadBindingRemovedActivityLogEntr if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._ServiceAccountWorkloadBindingRemovedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._ServiceAccountWorkloadBindingRemovedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { diff --git a/internal/graph/gengql/serviceaccounts.generated.go b/internal/graph/gengql/serviceaccounts.generated.go index 12f8bc26b..77ca34291 100644 --- a/internal/graph/gengql/serviceaccounts.generated.go +++ b/internal/graph/gengql/serviceaccounts.generated.go @@ -13,6 +13,7 @@ import ( "github.com/99designs/gqlgen/graphql" "github.com/nais/api/internal/activitylog" "github.com/nais/api/internal/auth/authz" + "github.com/nais/api/internal/auth/middleware/github" "github.com/nais/api/internal/graph/ident" "github.com/nais/api/internal/graph/pagination" "github.com/nais/api/internal/graph/scalar" @@ -512,6 +513,38 @@ func (ec *executionContext) fieldContext_RoleAssignedToServiceAccountActivityLog return graphql.NewScalarFieldContext("RoleAssignedToServiceAccountActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _RoleAssignedToServiceAccountActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *serviceaccount.RoleAssignedToServiceAccountActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_RoleAssignedToServiceAccountActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_RoleAssignedToServiceAccountActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "RoleAssignedToServiceAccountActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _RoleAssignedToServiceAccountActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *serviceaccount.RoleAssignedToServiceAccountActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -751,6 +784,38 @@ func (ec *executionContext) fieldContext_RoleRevokedFromServiceAccountActivityLo return graphql.NewScalarFieldContext("RoleRevokedFromServiceAccountActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _RoleRevokedFromServiceAccountActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *serviceaccount.RoleRevokedFromServiceAccountActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_RoleRevokedFromServiceAccountActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_RoleRevokedFromServiceAccountActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "RoleRevokedFromServiceAccountActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _RoleRevokedFromServiceAccountActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *serviceaccount.RoleRevokedFromServiceAccountActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -1432,6 +1497,38 @@ func (ec *executionContext) fieldContext_ServiceAccountCreatedActivityLogEntry_a return graphql.NewScalarFieldContext("ServiceAccountCreatedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _ServiceAccountCreatedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *serviceaccount.ServiceAccountCreatedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_ServiceAccountCreatedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_ServiceAccountCreatedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ServiceAccountCreatedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _ServiceAccountCreatedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *serviceaccount.ServiceAccountCreatedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -1616,6 +1713,38 @@ func (ec *executionContext) fieldContext_ServiceAccountDeletedActivityLogEntry_a return graphql.NewScalarFieldContext("ServiceAccountDeletedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _ServiceAccountDeletedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *serviceaccount.ServiceAccountDeletedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_ServiceAccountDeletedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_ServiceAccountDeletedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ServiceAccountDeletedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _ServiceAccountDeletedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *serviceaccount.ServiceAccountDeletedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -2112,6 +2241,38 @@ func (ec *executionContext) fieldContext_ServiceAccountTokenCreatedActivityLogEn return graphql.NewScalarFieldContext("ServiceAccountTokenCreatedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _ServiceAccountTokenCreatedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *serviceaccount.ServiceAccountTokenCreatedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_ServiceAccountTokenCreatedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_ServiceAccountTokenCreatedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ServiceAccountTokenCreatedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _ServiceAccountTokenCreatedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *serviceaccount.ServiceAccountTokenCreatedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -2351,6 +2512,38 @@ func (ec *executionContext) fieldContext_ServiceAccountTokenDeletedActivityLogEn return graphql.NewScalarFieldContext("ServiceAccountTokenDeletedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _ServiceAccountTokenDeletedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *serviceaccount.ServiceAccountTokenDeletedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_ServiceAccountTokenDeletedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_ServiceAccountTokenDeletedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ServiceAccountTokenDeletedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _ServiceAccountTokenDeletedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *serviceaccount.ServiceAccountTokenDeletedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -2645,6 +2838,38 @@ func (ec *executionContext) fieldContext_ServiceAccountTokenUpdatedActivityLogEn return graphql.NewScalarFieldContext("ServiceAccountTokenUpdatedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _ServiceAccountTokenUpdatedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *serviceaccount.ServiceAccountTokenUpdatedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_ServiceAccountTokenUpdatedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_ServiceAccountTokenUpdatedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ServiceAccountTokenUpdatedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _ServiceAccountTokenUpdatedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *serviceaccount.ServiceAccountTokenUpdatedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -2985,6 +3210,38 @@ func (ec *executionContext) fieldContext_ServiceAccountUpdatedActivityLogEntry_a return graphql.NewScalarFieldContext("ServiceAccountUpdatedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _ServiceAccountUpdatedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *serviceaccount.ServiceAccountUpdatedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_ServiceAccountUpdatedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_ServiceAccountUpdatedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ServiceAccountUpdatedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _ServiceAccountUpdatedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *serviceaccount.ServiceAccountUpdatedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -3917,6 +4174,8 @@ func (ec *executionContext) _RoleAssignedToServiceAccountActivityLogEntry(ctx co if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._RoleAssignedToServiceAccountActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._RoleAssignedToServiceAccountActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -4029,6 +4288,8 @@ func (ec *executionContext) _RoleRevokedFromServiceAccountActivityLogEntry(ctx c if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._RoleRevokedFromServiceAccountActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._RoleRevokedFromServiceAccountActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -4459,6 +4720,8 @@ func (ec *executionContext) _ServiceAccountCreatedActivityLogEntry(ctx context.C if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._ServiceAccountCreatedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._ServiceAccountCreatedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -4527,6 +4790,8 @@ func (ec *executionContext) _ServiceAccountDeletedActivityLogEntry(ctx context.C if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._ServiceAccountDeletedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._ServiceAccountDeletedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -4751,6 +5016,8 @@ func (ec *executionContext) _ServiceAccountTokenCreatedActivityLogEntry(ctx cont if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._ServiceAccountTokenCreatedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._ServiceAccountTokenCreatedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -4863,6 +5130,8 @@ func (ec *executionContext) _ServiceAccountTokenDeletedActivityLogEntry(ctx cont if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._ServiceAccountTokenDeletedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._ServiceAccountTokenDeletedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -5019,6 +5288,8 @@ func (ec *executionContext) _ServiceAccountTokenUpdatedActivityLogEntry(ctx cont if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._ServiceAccountTokenUpdatedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._ServiceAccountTokenUpdatedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -5176,6 +5447,8 @@ func (ec *executionContext) _ServiceAccountUpdatedActivityLogEntry(ctx context.C if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._ServiceAccountUpdatedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._ServiceAccountUpdatedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { diff --git a/internal/graph/gengql/servicemaintenance.generated.go b/internal/graph/gengql/servicemaintenance.generated.go index e70268bf8..6e008f316 100644 --- a/internal/graph/gengql/servicemaintenance.generated.go +++ b/internal/graph/gengql/servicemaintenance.generated.go @@ -13,6 +13,7 @@ import ( "github.com/99designs/gqlgen/graphql" activitylog1 "github.com/nais/api/internal/activitylog" + "github.com/nais/api/internal/auth/middleware/github" "github.com/nais/api/internal/graph/ident" "github.com/nais/api/internal/graph/model" "github.com/nais/api/internal/graph/pagination" @@ -532,6 +533,38 @@ func (ec *executionContext) fieldContext_ServiceMaintenanceActivityLogEntry_acto return graphql.NewScalarFieldContext("ServiceMaintenanceActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _ServiceMaintenanceActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *activitylog.ServiceMaintenanceActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_ServiceMaintenanceActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_ServiceMaintenanceActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ServiceMaintenanceActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _ServiceMaintenanceActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *activitylog.ServiceMaintenanceActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -1471,6 +1504,8 @@ func (ec *executionContext) _ServiceMaintenanceActivityLogEntry(ctx context.Cont if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._ServiceMaintenanceActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._ServiceMaintenanceActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { diff --git a/internal/graph/gengql/teams.generated.go b/internal/graph/gengql/teams.generated.go index 01ebdfff6..a27b260b6 100644 --- a/internal/graph/gengql/teams.generated.go +++ b/internal/graph/gengql/teams.generated.go @@ -13,6 +13,7 @@ import ( "github.com/99designs/gqlgen/graphql" "github.com/nais/api/internal/activitylog" "github.com/nais/api/internal/alerts" + "github.com/nais/api/internal/auth/middleware/github" "github.com/nais/api/internal/cost" "github.com/nais/api/internal/deployment" "github.com/nais/api/internal/environment" @@ -106,6 +107,7 @@ type TeamEnvironmentResolver interface { OpenSearch(ctx context.Context, obj *team.TeamEnvironment, name string) (*opensearch.OpenSearch, error) Postgres(ctx context.Context, obj *team.TeamEnvironment, name string) (*postgres.Postgres, error) PostgresInstance(ctx context.Context, obj *team.TeamEnvironment, name string) (*postgres.PostgresInstance, error) + PostgresAccess(ctx context.Context, obj *team.TeamEnvironment, name string) (*postgres.PostgresAccess, error) Secret(ctx context.Context, obj *team.TeamEnvironment, name string) (*secret.Secret, error) SQLInstance(ctx context.Context, obj *team.TeamEnvironment, name string) (*sqlinstance.SQLInstance, error) Tunnel(ctx context.Context, obj *team.TeamEnvironment, name string) (*tunnel.Tunnel, error) @@ -289,6 +291,20 @@ func (ec *executionContext) field_TeamEnvironment_openSearch_args(ctx context.Co return args, nil } +func (ec *executionContext) field_TeamEnvironment_postgresAccess_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := graphql.ProcessArgField(ctx, rawArgs, "name", + func(ctx context.Context, v any) (string, error) { + return ec.unmarshalNString2string(ctx, v) + }) + if err != nil { + return nil, err + } + args["name"] = arg0 + return args, nil +} + func (ec *executionContext) field_TeamEnvironment_postgresInstance_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} @@ -3405,6 +3421,38 @@ func (ec *executionContext) fieldContext_TeamConfirmDeleteKeyActivityLogEntry_ac return graphql.NewScalarFieldContext("TeamConfirmDeleteKeyActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _TeamConfirmDeleteKeyActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *team.TeamConfirmDeleteKeyActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_TeamConfirmDeleteKeyActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_TeamConfirmDeleteKeyActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "TeamConfirmDeleteKeyActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _TeamConfirmDeleteKeyActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *team.TeamConfirmDeleteKeyActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -3685,6 +3733,38 @@ func (ec *executionContext) fieldContext_TeamCreateDeleteKeyActivityLogEntry_act return graphql.NewScalarFieldContext("TeamCreateDeleteKeyActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _TeamCreateDeleteKeyActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *team.TeamCreateDeleteKeyActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_TeamCreateDeleteKeyActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_TeamCreateDeleteKeyActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "TeamCreateDeleteKeyActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _TeamCreateDeleteKeyActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *team.TeamCreateDeleteKeyActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -3869,6 +3949,38 @@ func (ec *executionContext) fieldContext_TeamCreatedActivityLogEntry_actor(_ con return graphql.NewScalarFieldContext("TeamCreatedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _TeamCreatedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *team.TeamCreatedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_TeamCreatedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_TeamCreatedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "TeamCreatedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _TeamCreatedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *team.TeamCreatedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -4846,6 +4958,50 @@ func (ec *executionContext) fieldContext_TeamEnvironment_postgresInstance(ctx co return fc, nil } +func (ec *executionContext) _TeamEnvironment_postgresAccess(ctx context.Context, field graphql.CollectedField, obj *team.TeamEnvironment) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_TeamEnvironment_postgresAccess(ctx, field) + }, + func(ctx context.Context) (any, error) { + fc := graphql.GetFieldContext(ctx) + return ec.Resolvers.TeamEnvironment().PostgresAccess(ctx, obj, fc.Args["name"].(string)) + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *postgres.PostgresAccess) graphql.Marshaler { + return ec.marshalNPostgresAccess2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccess(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_TeamEnvironment_postgresAccess(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "TeamEnvironment", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_PostgresAccess(ctx, field) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_TeamEnvironment_postgresAccess_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + func (ec *executionContext) _TeamEnvironment_secret(ctx context.Context, field graphql.CollectedField, obj *team.TeamEnvironment) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -5112,6 +5268,38 @@ func (ec *executionContext) fieldContext_TeamEnvironmentUpdatedActivityLogEntry_ return graphql.NewScalarFieldContext("TeamEnvironmentUpdatedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _TeamEnvironmentUpdatedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *team.TeamEnvironmentUpdatedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_TeamEnvironmentUpdatedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_TeamEnvironmentUpdatedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "TeamEnvironmentUpdatedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _TeamEnvironmentUpdatedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *team.TeamEnvironmentUpdatedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -6097,6 +6285,38 @@ func (ec *executionContext) fieldContext_TeamMemberAddedActivityLogEntry_actor(_ return graphql.NewScalarFieldContext("TeamMemberAddedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _TeamMemberAddedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *team.TeamMemberAddedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_TeamMemberAddedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_TeamMemberAddedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "TeamMemberAddedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _TeamMemberAddedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *team.TeamMemberAddedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -6533,6 +6753,38 @@ func (ec *executionContext) fieldContext_TeamMemberRemovedActivityLogEntry_actor return graphql.NewScalarFieldContext("TeamMemberRemovedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _TeamMemberRemovedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *team.TeamMemberRemovedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_TeamMemberRemovedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_TeamMemberRemovedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "TeamMemberRemovedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _TeamMemberRemovedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *team.TeamMemberRemovedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -6795,6 +7047,38 @@ func (ec *executionContext) fieldContext_TeamMemberSetRoleActivityLogEntry_actor return graphql.NewScalarFieldContext("TeamMemberSetRoleActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _TeamMemberSetRoleActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *team.TeamMemberSetRoleActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_TeamMemberSetRoleActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_TeamMemberSetRoleActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "TeamMemberSetRoleActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _TeamMemberSetRoleActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *team.TeamMemberSetRoleActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -7080,6 +7364,38 @@ func (ec *executionContext) fieldContext_TeamUpdatedActivityLogEntry_actor(_ con return graphql.NewScalarFieldContext("TeamUpdatedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _TeamUpdatedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *team.TeamUpdatedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_TeamUpdatedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_TeamUpdatedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "TeamUpdatedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _TeamUpdatedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *team.TeamUpdatedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -9547,6 +9863,8 @@ func (ec *executionContext) _TeamConfirmDeleteKeyActivityLogEntry(ctx context.Co if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._TeamConfirmDeleteKeyActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._TeamConfirmDeleteKeyActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -9667,6 +9985,8 @@ func (ec *executionContext) _TeamCreateDeleteKeyActivityLogEntry(ctx context.Con if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._TeamCreateDeleteKeyActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._TeamCreateDeleteKeyActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -9738,6 +10058,8 @@ func (ec *executionContext) _TeamCreatedActivityLogEntry(ctx context.Context, se if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._TeamCreatedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._TeamCreatedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -10487,6 +10809,42 @@ func (ec *executionContext) _TeamEnvironment(ctx context.Context, sel ast.Select continue } + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) + case "postgresAccess": + field := field + + innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + } + }() + res = ec._TeamEnvironment_postgresAccess(ctx, field, obj) + if res == graphql.Null { + atomic.AddUint32(&fs.Invalids, 1) + } + return res + } + + if field.Deferrable != nil { + dfs, ok := deferred[field.Deferrable.Label] + di := 0 + if ok { + dfs.AddField(field) + di = len(dfs.Values) - 1 + } else { + dfs = graphql.NewFieldSet([]graphql.CollectedField{field}) + deferred[field.Deferrable.Label] = dfs + } + dfs.Concurrently(di, func(ctx context.Context) graphql.Marshaler { + return innerFunc(ctx, dfs) + }) + + // don't run the out.Concurrently() call below + out.Values[i] = graphql.Null + continue + } + out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) case "secret": field := field @@ -10709,6 +11067,8 @@ func (ec *executionContext) _TeamEnvironmentUpdatedActivityLogEntry(ctx context. if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._TeamEnvironmentUpdatedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._TeamEnvironmentUpdatedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -11569,6 +11929,8 @@ func (ec *executionContext) _TeamMemberAddedActivityLogEntry(ctx context.Context if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._TeamMemberAddedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._TeamMemberAddedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -11787,6 +12149,8 @@ func (ec *executionContext) _TeamMemberRemovedActivityLogEntry(ctx context.Conte if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._TeamMemberRemovedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._TeamMemberRemovedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -11907,6 +12271,8 @@ func (ec *executionContext) _TeamMemberSetRoleActivityLogEntry(ctx context.Conte if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._TeamMemberSetRoleActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._TeamMemberSetRoleActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -12032,6 +12398,8 @@ func (ec *executionContext) _TeamUpdatedActivityLogEntry(ctx context.Context, se if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._TeamUpdatedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._TeamUpdatedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { diff --git a/internal/graph/gengql/tunnel.generated.go b/internal/graph/gengql/tunnel.generated.go index dc1795c78..9c0ce7d8b 100644 --- a/internal/graph/gengql/tunnel.generated.go +++ b/internal/graph/gengql/tunnel.generated.go @@ -12,6 +12,7 @@ import ( "github.com/99designs/gqlgen/graphql" "github.com/nais/api/internal/activitylog" + "github.com/nais/api/internal/auth/middleware/github" "github.com/nais/api/internal/graph/ident" "github.com/nais/api/internal/slug" "github.com/nais/api/internal/tunnel" @@ -326,6 +327,38 @@ func (ec *executionContext) fieldContext_TunnelCreatedActivityLogEntry_actor(_ c return graphql.NewScalarFieldContext("TunnelCreatedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _TunnelCreatedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *tunnel.TunnelCreatedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_TunnelCreatedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_TunnelCreatedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "TunnelCreatedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _TunnelCreatedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *tunnel.TunnelCreatedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -588,6 +621,38 @@ func (ec *executionContext) fieldContext_TunnelDeletedActivityLogEntry_actor(_ c return graphql.NewScalarFieldContext("TunnelDeletedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _TunnelDeletedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *tunnel.TunnelDeletedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_TunnelDeletedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_TunnelDeletedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "TunnelDeletedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _TunnelDeletedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *tunnel.TunnelDeletedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -1114,6 +1179,8 @@ func (ec *executionContext) _TunnelCreatedActivityLogEntry(ctx context.Context, if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._TunnelCreatedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._TunnelCreatedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -1231,6 +1298,8 @@ func (ec *executionContext) _TunnelDeletedActivityLogEntry(ctx context.Context, if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._TunnelDeletedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._TunnelDeletedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { diff --git a/internal/graph/gengql/unleash.generated.go b/internal/graph/gengql/unleash.generated.go index ef71b90ea..a1a93f2a5 100644 --- a/internal/graph/gengql/unleash.generated.go +++ b/internal/graph/gengql/unleash.generated.go @@ -12,6 +12,7 @@ import ( "github.com/99designs/gqlgen/graphql" "github.com/nais/api/internal/activitylog" + "github.com/nais/api/internal/auth/middleware/github" "github.com/nais/api/internal/graph/ident" "github.com/nais/api/internal/graph/pagination" "github.com/nais/api/internal/slug" @@ -517,6 +518,38 @@ func (ec *executionContext) fieldContext_UnleashInstanceCreatedActivityLogEntry_ return graphql.NewScalarFieldContext("UnleashInstanceCreatedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _UnleashInstanceCreatedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *unleash.UnleashInstanceCreatedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_UnleashInstanceCreatedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_UnleashInstanceCreatedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "UnleashInstanceCreatedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _UnleashInstanceCreatedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *unleash.UnleashInstanceCreatedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -701,6 +734,38 @@ func (ec *executionContext) fieldContext_UnleashInstanceDeletedActivityLogEntry_ return graphql.NewScalarFieldContext("UnleashInstanceDeletedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _UnleashInstanceDeletedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *unleash.UnleashInstanceDeletedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_UnleashInstanceDeletedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_UnleashInstanceDeletedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "UnleashInstanceDeletedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _UnleashInstanceDeletedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *unleash.UnleashInstanceDeletedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -1023,6 +1088,38 @@ func (ec *executionContext) fieldContext_UnleashInstanceUpdatedActivityLogEntry_ return graphql.NewScalarFieldContext("UnleashInstanceUpdatedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _UnleashInstanceUpdatedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *unleash.UnleashInstanceUpdatedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_UnleashInstanceUpdatedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_UnleashInstanceUpdatedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "UnleashInstanceUpdatedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _UnleashInstanceUpdatedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *unleash.UnleashInstanceUpdatedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -1884,6 +1981,8 @@ func (ec *executionContext) _UnleashInstanceCreatedActivityLogEntry(ctx context. if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._UnleashInstanceCreatedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._UnleashInstanceCreatedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -1955,6 +2054,8 @@ func (ec *executionContext) _UnleashInstanceDeletedActivityLogEntry(ctx context. if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._UnleashInstanceDeletedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._UnleashInstanceDeletedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -2214,6 +2315,8 @@ func (ec *executionContext) _UnleashInstanceUpdatedActivityLogEntry(ctx context. if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._UnleashInstanceUpdatedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._UnleashInstanceUpdatedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { diff --git a/internal/graph/gengql/valkey.generated.go b/internal/graph/gengql/valkey.generated.go index 1e3eab3b2..76f44e743 100644 --- a/internal/graph/gengql/valkey.generated.go +++ b/internal/graph/gengql/valkey.generated.go @@ -12,6 +12,7 @@ import ( "github.com/99designs/gqlgen/graphql" "github.com/nais/api/internal/activitylog" + "github.com/nais/api/internal/auth/middleware/github" "github.com/nais/api/internal/cost" "github.com/nais/api/internal/graph/ident" "github.com/nais/api/internal/graph/model" @@ -1315,6 +1316,38 @@ func (ec *executionContext) fieldContext_ValkeyCreatedActivityLogEntry_actor(_ c return graphql.NewScalarFieldContext("ValkeyCreatedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _ValkeyCreatedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *valkey.ValkeyCreatedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_ValkeyCreatedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_ValkeyCreatedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ValkeyCreatedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _ValkeyCreatedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *valkey.ValkeyCreatedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -1614,6 +1647,38 @@ func (ec *executionContext) fieldContext_ValkeyCredentialsCreatedActivityLogEntr return graphql.NewScalarFieldContext("ValkeyCredentialsCreatedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _ValkeyCredentialsCreatedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *valkey.ValkeyCredentialsCreatedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_ValkeyCredentialsCreatedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_ValkeyCredentialsCreatedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ValkeyCredentialsCreatedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _ValkeyCredentialsCreatedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *valkey.ValkeyCredentialsCreatedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -1876,6 +1941,38 @@ func (ec *executionContext) fieldContext_ValkeyDeletedActivityLogEntry_actor(_ c return graphql.NewScalarFieldContext("ValkeyDeletedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _ValkeyDeletedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *valkey.ValkeyDeletedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_ValkeyDeletedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_ValkeyDeletedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ValkeyDeletedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _ValkeyDeletedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *valkey.ValkeyDeletedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -2257,6 +2354,38 @@ func (ec *executionContext) fieldContext_ValkeyUpdatedActivityLogEntry_actor(_ c return graphql.NewScalarFieldContext("ValkeyUpdatedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _ValkeyUpdatedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *valkey.ValkeyUpdatedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_ValkeyUpdatedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_ValkeyUpdatedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "ValkeyUpdatedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _ValkeyUpdatedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *valkey.ValkeyUpdatedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -3908,6 +4037,8 @@ func (ec *executionContext) _ValkeyCreatedActivityLogEntry(ctx context.Context, if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._ValkeyCreatedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._ValkeyCreatedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -4038,6 +4169,8 @@ func (ec *executionContext) _ValkeyCredentialsCreatedActivityLogEntry(ctx contex if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._ValkeyCredentialsCreatedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._ValkeyCredentialsCreatedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -4155,6 +4288,8 @@ func (ec *executionContext) _ValkeyDeletedActivityLogEntry(ctx context.Context, if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._ValkeyDeletedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._ValkeyDeletedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -4456,6 +4591,8 @@ func (ec *executionContext) _ValkeyUpdatedActivityLogEntry(ctx context.Context, if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._ValkeyUpdatedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._ValkeyUpdatedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { diff --git a/internal/graph/gengql/vulnerability.generated.go b/internal/graph/gengql/vulnerability.generated.go index 184b1cb9a..606f6b577 100644 --- a/internal/graph/gengql/vulnerability.generated.go +++ b/internal/graph/gengql/vulnerability.generated.go @@ -12,6 +12,7 @@ import ( "github.com/99designs/gqlgen/graphql" "github.com/nais/api/internal/activitylog" + "github.com/nais/api/internal/auth/middleware/github" "github.com/nais/api/internal/graph/ident" "github.com/nais/api/internal/graph/pagination" "github.com/nais/api/internal/slug" @@ -2905,6 +2906,38 @@ func (ec *executionContext) fieldContext_VulnerabilityUpdatedActivityLogEntry_ac return graphql.NewScalarFieldContext("VulnerabilityUpdatedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _VulnerabilityUpdatedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *vulnerability.VulnerabilityUpdatedActivityLogEntry) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_VulnerabilityUpdatedActivityLogEntry_gitHubActorClaims(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.GitHubActorClaims, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_VulnerabilityUpdatedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "VulnerabilityUpdatedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil +} + func (ec *executionContext) _VulnerabilityUpdatedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *vulnerability.VulnerabilityUpdatedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -5264,6 +5297,8 @@ func (ec *executionContext) _VulnerabilityUpdatedActivityLogEntry(ctx context.Co if out.Values[i] == graphql.Null { out.Invalids++ } + case "gitHubActorClaims": + out.Values[i] = ec._VulnerabilityUpdatedActivityLogEntry_gitHubActorClaims(ctx, field, obj) case "createdAt": out.Values[i] = ec._VulnerabilityUpdatedActivityLogEntry_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { diff --git a/internal/graph/postgres.resolvers.go b/internal/graph/postgres.resolvers.go index 7d17184ff..f45565e2a 100644 --- a/internal/graph/postgres.resolvers.go +++ b/internal/graph/postgres.resolvers.go @@ -7,7 +7,6 @@ import ( "github.com/nais/api/internal/graph/gengql" "github.com/nais/api/internal/graph/pagination" "github.com/nais/api/internal/persistence/postgres" - "github.com/nais/api/internal/slug" "github.com/nais/api/internal/team" "github.com/nais/api/internal/workload" "github.com/nais/api/internal/workload/application" @@ -63,6 +62,12 @@ func (r *postgresAccessResolver) PostgresInstance(ctx context.Context, obj *post return postgres.GetPostgresInstance(ctx, obj.TeamSlug, obj.EnvironmentName, obj.PostgresInstanceName) } +func (r *postgresAccessResolver) Connection(ctx context.Context, obj *postgres.PostgresAccess) (*postgres.PostgresAccessConnection, error) { + return postgres.GetPostgresAccessConnection(ctx, postgres.PostgresAccessConnectionInput{ + Name: obj.Name, TeamSlug: obj.TeamSlug, EnvironmentName: obj.EnvironmentName, + }) +} + func (r *postgresInstanceResolver) Team(ctx context.Context, obj *postgres.PostgresInstance) (*team.Team, error) { return team.Get(ctx, obj.TeamSlug) } @@ -93,14 +98,6 @@ func (r *postgresInstanceConnectionResolver) Facets(ctx context.Context, obj *pa }, nil } -func (r *queryResolver) PostgresAccessConnection(ctx context.Context, input postgres.PostgresAccessConnectionInput) (*postgres.PostgresAccessConnection, error) { - return postgres.GetPostgresAccessConnection(ctx, input) -} - -func (r *queryResolver) PostgresAccess(ctx context.Context, name string, teamSlug slug.Slug, environmentName string) (*postgres.PostgresAccess, error) { - return postgres.GetPostgresAccess(ctx, name, teamSlug, environmentName) -} - func (r *teamResolver) PostgresInstances(ctx context.Context, obj *team.Team, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *postgres.PostgresInstanceOrder, filter *postgres.PostgresInstanceFilter) (*pagination.FacetableConnection[*postgres.PostgresInstance, *postgres.PostgresInstanceFilter], error) { page, err := pagination.ParsePage(first, after, last, before) if err != nil { @@ -118,6 +115,10 @@ func (r *teamEnvironmentResolver) PostgresInstance(ctx context.Context, obj *tea return postgres.GetPostgresInstance(ctx, obj.TeamSlug, obj.EnvironmentName, name) } +func (r *teamEnvironmentResolver) PostgresAccess(ctx context.Context, obj *team.TeamEnvironment, name string) (*postgres.PostgresAccess, error) { + return postgres.GetPostgresAccess(ctx, name, obj.TeamSlug, obj.EnvironmentName) +} + func (r *teamInventoryCountsResolver) PostgresInstances(ctx context.Context, obj *team.TeamInventoryCounts) (*postgres.TeamInventoryCountPostgresInstances, error) { return &postgres.TeamInventoryCountPostgresInstances{ Total: postgres.CountForTeam(ctx, obj.TeamSlug), diff --git a/internal/graph/schema/activitylog.graphqls b/internal/graph/schema/activitylog.graphqls index 55c7f5c79..a5e147736 100644 --- a/internal/graph/schema/activitylog.graphqls +++ b/internal/graph/schema/activitylog.graphqls @@ -268,6 +268,9 @@ interface ActivityLogEntry implements Node { """ actor: String! + "GitHub Actions OIDC claims captured when the action was authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + """ Creation time of the entry. """ diff --git a/internal/graph/schema/applications.graphqls b/internal/graph/schema/applications.graphqls index 25d1a010f..777e23807 100644 --- a/internal/graph/schema/applications.graphqls +++ b/internal/graph/schema/applications.graphqls @@ -742,6 +742,9 @@ type ApplicationDeletedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -768,6 +771,9 @@ type ApplicationRestartedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -796,6 +802,9 @@ type ApplicationScaledActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -842,6 +851,9 @@ type ApplicationCreatedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -872,6 +884,7 @@ type ApplicationUpdatedActivityLogEntryData { changedFields: [ResourceChangedField!]! "GitHub Actions OIDC token claims at the time of the apply. Only present when the request was authenticated via a GitHub token." gitHubActorClaims: GitHubActorClaims + @deprecated(reason: "Use gitHubActorClaims on the activity log entry instead.") } """ @@ -884,6 +897,9 @@ type ApplicationUpdatedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! diff --git a/internal/graph/schema/apply.graphqls b/internal/graph/schema/apply.graphqls index cd0e8b00b..62ec3d627 100644 --- a/internal/graph/schema/apply.graphqls +++ b/internal/graph/schema/apply.graphqls @@ -15,32 +15,60 @@ type GenericKubernetesResourceActivityLogEntryData { changedFields: [ResourceChangedField!]! "GitHub Actions OIDC token claims at the time of the apply. Only present when the request was authenticated via a GitHub token." gitHubActorClaims: GitHubActorClaims + @deprecated(reason: "Use gitHubActorClaims on the activity log entry instead.") } """ -GitHub Actions OIDC token claims captured at the time of an apply operation. +GitHub Actions OIDC token claims captured when an activity log entry is created. +See https://docs.github.com/en/actions/reference/security/oidc#custom-claims-provided-by-github """ type GitHubActorClaims { + "The GitHub username that triggered the workflow." + actor: String! + "The ID of the personal account that initiated the workflow run." + actorID: String + "The target branch of the pull request in a workflow run." + baseRef: String + "The check run ID of the current job." + checkRunID: String + "The GitHub deployment environment name, if the job targets one." + environment: String! + "The event that triggered the workflow, e.g. 'push' or 'workflow_dispatch'." + eventName: String! + "The source branch of the pull request in a workflow run." + headRef: String + "The ref of the reusable workflow called by this job, if any. E.g. 'org/repo/.github/workflows/deploy.yaml@refs/heads/main'." + jobWorkflowRef: String! + "The commit SHA for the reusable workflow file, if the job uses one." + jobWorkflowSha: String "The git ref that triggered the workflow, e.g. 'refs/heads/main'." ref: String! + "The type of ref, e.g. 'branch'." + refType: String "The repository name that triggered the workflow, e.g. 'org/repo'." repository: String! "The immutable numeric GitHub repository ID." repositoryID: String! - "The unique identifier of the Actions workflow run. Links to https://github.com//actions/runs/." - runID: String! + "The name of the organization in which the repository is stored." + repositoryOwner: String + "The ID of the organization in which the repository is stored." + repositoryOwnerID: String + "The visibility of the repository, e.g. 'internal', 'private', or 'public'." + repositoryVisibility: String "The attempt number of the workflow run (1-indexed)." runAttempt: String! - "The GitHub username that triggered the workflow." - actor: String! + "The unique identifier of the Actions workflow run. Links to https://github.com//actions/runs/." + runID: String! + "The type of runner used by the job, e.g. 'github-hosted' or 'self-hosted'." + runnerEnvironment: String + "The number of times this workflow has been run." + runNumber: String "The path to the workflow file, e.g. '.github/workflows/deploy.yaml'." workflow: String! - "The event that triggered the workflow, e.g. 'push' or 'workflow_dispatch'." - eventName: String! - "The GitHub deployment environment name, if the job targets one." - environment: String! - "The ref of the reusable workflow called by this job, if any. E.g. 'org/repo/.github/workflows/deploy.yaml@refs/heads/main'." - jobWorkflowRef: String! + "The ref path to the workflow, e.g. 'org/repo/.github/workflows/deploy.yaml@refs/heads/main'." + workflowRef: String + "The commit SHA for the workflow file." + workflowSha: String } """ @@ -66,6 +94,9 @@ type GenericKubernetesResourceActivityLogEntry implements ActivityLogEntry & Nod "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! diff --git a/internal/graph/schema/cluster.graphqls b/internal/graph/schema/cluster.graphqls index fa9c42283..465238c66 100644 --- a/internal/graph/schema/cluster.graphqls +++ b/internal/graph/schema/cluster.graphqls @@ -15,6 +15,9 @@ type ClusterAuditActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! diff --git a/internal/graph/schema/config.graphqls b/internal/graph/schema/config.graphqls index b34f9a0d6..b30a699bd 100644 --- a/internal/graph/schema/config.graphqls +++ b/internal/graph/schema/config.graphqls @@ -438,6 +438,9 @@ type ConfigCreatedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -464,6 +467,9 @@ type ConfigUpdatedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -509,6 +515,9 @@ type ConfigDeletedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! diff --git a/internal/graph/schema/deployment.graphqls b/internal/graph/schema/deployment.graphqls index 0816a6685..bf63282a9 100644 --- a/internal/graph/schema/deployment.graphqls +++ b/internal/graph/schema/deployment.graphqls @@ -378,6 +378,9 @@ type TeamDeployKeyUpdatedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -406,6 +409,9 @@ type DeploymentActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! diff --git a/internal/graph/schema/jobs.graphqls b/internal/graph/schema/jobs.graphqls index ea70381cd..91a66bc71 100644 --- a/internal/graph/schema/jobs.graphqls +++ b/internal/graph/schema/jobs.graphqls @@ -496,6 +496,9 @@ type JobDeletedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -522,6 +525,9 @@ type JobTriggeredActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -567,6 +573,9 @@ type JobRunDeletedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -601,6 +610,9 @@ type JobCreatedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -633,6 +645,9 @@ type JobUpdatedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -663,6 +678,7 @@ type JobUpdatedActivityLogEntryData { changedFields: [ResourceChangedField!]! "GitHub Actions OIDC token claims at the time of the apply. Only present when the request was authenticated via a GitHub token." gitHubActorClaims: GitHubActorClaims + @deprecated(reason: "Use gitHubActorClaims on the activity log entry instead.") } extend enum ActivityLogActivityType { diff --git a/internal/graph/schema/kafka.graphqls b/internal/graph/schema/kafka.graphqls index 55acd2746..99a56e685 100644 --- a/internal/graph/schema/kafka.graphqls +++ b/internal/graph/schema/kafka.graphqls @@ -278,6 +278,9 @@ type KafkaCredentialsCreatedActivityLogEntry implements ActivityLogEntry & Node "The identity of the actor who performed the action." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -312,6 +315,9 @@ type KafkaTopicUpdatedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! diff --git a/internal/graph/schema/opensearch.graphqls b/internal/graph/schema/opensearch.graphqls index 4aba769ec..d93cf80a2 100644 --- a/internal/graph/schema/opensearch.graphqls +++ b/internal/graph/schema/opensearch.graphqls @@ -374,6 +374,9 @@ type OpenSearchCreatedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -400,6 +403,9 @@ type OpenSearchUpdatedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -452,6 +458,9 @@ type OpenSearchDeletedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -509,6 +518,9 @@ type OpenSearchCredentialsCreatedActivityLogEntry implements ActivityLogEntry & "The identity of the actor who performed the action." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! diff --git a/internal/graph/schema/postgres.graphqls b/internal/graph/schema/postgres.graphqls index c836500b2..b1fb7676f 100644 --- a/internal/graph/schema/postgres.graphqls +++ b/internal/graph/schema/postgres.graphqls @@ -23,9 +23,20 @@ extend type Team { extend type TeamEnvironment { "Postgres in the team environment." - postgres(name: String!): Postgres! + postgres( + "Name of the Postgres in this team environment." + name: String! + ): Postgres! "Named PostgresInstance in the team environment." - postgresInstance(name: String!): PostgresInstance! + postgresInstance( + "Name of the PostgresInstance in this team environment." + name: String! + ): PostgresInstance! + "Get a PostgresAccess and its state. Available to authorized team members." + postgresAccess( + "Name of the PostgresAccess in this team environment." + name: String! + ): PostgresAccess! } extend interface Workload { @@ -52,8 +63,11 @@ extend type Job { ): PostgresInstanceConnection! } +"Ordering options for Postgres instances." input PostgresInstanceOrder { + "Field to order instances by." field: PostgresInstanceOrderField! + "Direction of the ordering." direction: OrderDirection! } @@ -74,53 +88,88 @@ input PostgresInstanceFilter { labels: [LabelFilter!] } +"Fields available when ordering Postgres instances." enum PostgresInstanceOrderField { + "Instance name." NAME + "Environment name." ENVIRONMENT } "A named PostgresInstance belonging to a Postgres." type PostgresInstance implements Persistence & Node { + "Opaque identifier for this instance." id: ID! + "Name of the instance." name: String! + "Team owning this instance." team: Team! + "Team environment containing this instance." teamEnvironment: TeamEnvironment! "Postgres owning this PostgresInstance." postgres: Postgres! "Workloads using this instance while it is active." - workloads(first: Int, after: Cursor, last: Int, before: Cursor): WorkloadConnection! + workloads( + "Return the first n workloads." + first: Int + "Return workloads after this cursor." + after: Cursor + "Return the last n workloads." + last: Int + "Return workloads before this cursor." + before: Cursor + ): WorkloadConnection! + "Current observed state of the instance." state: PostgresInstanceState! + "User-defined labels on this instance." labels: [ResourceLabel!]! } "A Postgres whose active instance can change." type Postgres implements Node { + "Opaque identifier for this Postgres." id: ID! + "Name of this Postgres." name: String! + "Configured PostgreSQL major version." majorVersion: String! + "Whether high availability is configured." highAvailability: Boolean! "Requested CPU, memory and disk size, when present on this Postgres." resources: PostgresResources! + "Name of the currently active PostgresInstance, if selected." activeInstance: String + "User-defined labels on this Postgres." labels: [ResourceLabel!]! } "Resource requests configured on Postgres. Omitted requests are null." type PostgresResources { + "Requested CPU." cpu: String + "Requested memory." memory: String + "Requested disk size." diskSize: String } +"Reconciliation and observed health of a PostgresInstance." enum PostgresInstanceState { + "The instance is healthy and ready." AVAILABLE + "The instance is provisioning or its state has not been observed yet." PROGRESSING + "The instance has reported a failure." DEGRADED } +"Paginated PostgresInstance results." type PostgresInstanceConnection { + "Pagination metadata." pageInfo: PageInfo! + "Instances in this page." nodes: [PostgresInstance!]! + "Instances and their pagination cursors." edges: [PostgresInstanceEdge!]! """ @@ -130,8 +179,11 @@ type PostgresInstanceConnection { facets: PostgresInstanceFacets } +"A PostgresInstance and its pagination cursor." type PostgresInstanceEdge { + "Cursor identifying this result." cursor: Cursor! + "The matching instance." node: PostgresInstance! } @@ -171,8 +223,7 @@ extend enum ActivityLogEntryResourceType { POSTGRES } -# This is managed directly by the activitylog package since it -# combines data within the database. +"An earlier Postgres access grant recorded in the activity log." type PostgresGrantAccessActivityLogEntry implements ActivityLogEntry & Node { "ID of the entry." id: ID! @@ -180,6 +231,9 @@ type PostgresGrantAccessActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -202,8 +256,11 @@ type PostgresGrantAccessActivityLogEntry implements ActivityLogEntry & Node { data: PostgresGrantAccessActivityLogEntryData! } +"Details of an earlier Postgres access grant." type PostgresGrantAccessActivityLogEntryData { + "Identity that received access." grantee: String! + "End of the granted access period." until: Time! } @@ -213,6 +270,8 @@ type PostgresPersonalAccessCreatedActivityLogEntry implements ActivityLogEntry & id: ID! "The identity of the actor who created the personal access." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims "Creation time of the entry." createdAt: Time! "Message that summarizes the entry." @@ -245,6 +304,8 @@ type PostgresPersonalAccessConnectionActivityLogEntry implements ActivityLogEntr id: ID! "Identity that retrieved the connection materials." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims "Creation time of the entry." createdAt: Time! "Message that summarizes the entry." @@ -266,6 +327,9 @@ type PostgresDeletedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -307,7 +371,7 @@ extend enum ActivityLogActivityType { extend type Mutation { """ Create time-limited personal access to a NAIS Postgres instance through the brokered PostgresAccess and relay flow. - Use this for new NAIS Postgres personal access. When the access is ready, retrieve its connection materials with postgresAccessConnection. + When the access is ready, retrieve its connection materials through PostgresAccess.connection. """ createPostgresAccess(input: CreatePostgresAccessInput!): CreatePostgresAccessPayload! "Delete a PostgresInstance that is not active on its Postgres." @@ -348,6 +412,7 @@ enum PostgresAccessLevel { READWRITECREATE } +"Input identifying the PostgresInstance to delete." input DeletePostgresInput { "Name of the Postgres instance." name: String! @@ -357,37 +422,23 @@ input DeletePostgresInput { teamSlug: Slug! } +"Result of requesting deletion of a PostgresInstance." type DeletePostgresPayload { "Whether or not the Postgres instance was deleted." postgresDeleted: Boolean } extend type TeamInventoryCounts { + "Counts of Postgres instances owned by the team." postgresInstances: TeamInventoryCountPostgresInstances! } +"Inventory totals for Postgres instances." type TeamInventoryCountPostgresInstances { "Total number of Postgres instances." total: Int! } -extend type Query { - "Get connection materials for a ready personal Postgres access owned by the caller." - postgresAccessConnection(input: PostgresAccessConnectionInput!): PostgresAccessConnection! - - "Get a personal PostgresAccess resource and its state. Available to authorized team members." - postgresAccess( - "Name of the PostgresAccess resource." - name: String! - - "Team slug that owns the Postgres instance." - teamSlug: Slug! - - "Environment name that the Postgres instance belongs to." - environmentName: String! - ): PostgresAccess! -} - "A time-limited personal access request for a Postgres instance." type PostgresAccess implements Node { "Opaque ID for this PostgresAccess resource." @@ -410,6 +461,8 @@ type PostgresAccess implements Node { message: String "Name of the controller-owned relay mapping, once created. Contains no credential." relayAccess: String + "Get connection materials for this ready access. Only its owner can read them." + connection: PostgresAccessConnection! } "High-level reconciliation state of a personal Postgres access." @@ -424,16 +477,6 @@ enum PostgresAccessState { EXPIRED } -"Input for retrieving connection materials for a ready personal access." -input PostgresAccessConnectionInput { - "Name of the PostgresAccess resource." - name: String! - "Team that owns the PostgresAccess resource." - teamSlug: Slug! - "Environment containing the PostgresAccess resource." - environmentName: String! -} - "Sensitive connection materials for a ready personal Postgres access." type PostgresAccessConnection { "Database username for the caller's personal role." diff --git a/internal/graph/schema/reconcilers.graphqls b/internal/graph/schema/reconcilers.graphqls index 3d471e5c4..fbfbbc3ef 100644 --- a/internal/graph/schema/reconcilers.graphqls +++ b/internal/graph/schema/reconcilers.graphqls @@ -180,6 +180,9 @@ type ReconcilerEnabledActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -206,6 +209,9 @@ type ReconcilerDisabledActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -232,6 +238,9 @@ type ReconcilerConfiguredActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! diff --git a/internal/graph/schema/repository.graphqls b/internal/graph/schema/repository.graphqls index 02a7c75be..d128c1e2b 100644 --- a/internal/graph/schema/repository.graphqls +++ b/internal/graph/schema/repository.graphqls @@ -114,6 +114,9 @@ type RepositoryAddedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -140,6 +143,9 @@ type RepositoryRemovedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! diff --git a/internal/graph/schema/secret.graphqls b/internal/graph/schema/secret.graphqls index b4ac5c832..7b149a847 100644 --- a/internal/graph/schema/secret.graphqls +++ b/internal/graph/schema/secret.graphqls @@ -460,6 +460,9 @@ type SecretCreatedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -486,6 +489,9 @@ type SecretUpdatedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -531,6 +537,9 @@ type SecretValueAddedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -565,6 +574,9 @@ type SecretValueUpdatedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -599,6 +611,9 @@ type SecretValueRemovedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -633,6 +648,9 @@ type SecretDeletedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -679,6 +697,9 @@ type SecretValuesViewedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! diff --git a/internal/graph/schema/serviceaccount_workload_bindings.graphqls b/internal/graph/schema/serviceaccount_workload_bindings.graphqls index db6728e15..5cbe2c9b8 100644 --- a/internal/graph/schema/serviceaccount_workload_bindings.graphqls +++ b/internal/graph/schema/serviceaccount_workload_bindings.graphqls @@ -179,6 +179,9 @@ type ServiceAccountWorkloadBindingAddedActivityLogEntry implements ActivityLogEn """ actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + """ Creation time of the entry. """ @@ -243,6 +246,9 @@ type ServiceAccountWorkloadBindingRemovedActivityLogEntry implements ActivityLog """ actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + """ Creation time of the entry. """ diff --git a/internal/graph/schema/serviceaccounts.graphqls b/internal/graph/schema/serviceaccounts.graphqls index bc0b2e8be..23602f0c4 100644 --- a/internal/graph/schema/serviceaccounts.graphqls +++ b/internal/graph/schema/serviceaccounts.graphqls @@ -547,6 +547,9 @@ type ServiceAccountCreatedActivityLogEntry implements ActivityLogEntry & Node { """ actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + """ Creation time of the entry. """ @@ -589,6 +592,9 @@ type ServiceAccountUpdatedActivityLogEntry implements ActivityLogEntry & Node { """ actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + """ Creation time of the entry. """ @@ -660,6 +666,9 @@ type ServiceAccountDeletedActivityLogEntry implements ActivityLogEntry & Node { """ actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + """ Creation time of the entry. """ @@ -702,6 +711,9 @@ type RoleAssignedToServiceAccountActivityLogEntry implements ActivityLogEntry & """ actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + """ Creation time of the entry. """ @@ -756,6 +768,9 @@ type RoleRevokedFromServiceAccountActivityLogEntry implements ActivityLogEntry & """ actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + """ Creation time of the entry. """ @@ -810,6 +825,9 @@ type ServiceAccountTokenCreatedActivityLogEntry implements ActivityLogEntry & No """ actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + """ Creation time of the entry. """ @@ -864,6 +882,9 @@ type ServiceAccountTokenUpdatedActivityLogEntry implements ActivityLogEntry & No """ actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + """ Creation time of the entry. """ @@ -940,6 +961,9 @@ type ServiceAccountTokenDeletedActivityLogEntry implements ActivityLogEntry & No """ actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + """ Creation time of the entry. """ diff --git a/internal/graph/schema/servicemaintenance.graphqls b/internal/graph/schema/servicemaintenance.graphqls index 0f5feb705..ae0015094 100644 --- a/internal/graph/schema/servicemaintenance.graphqls +++ b/internal/graph/schema/servicemaintenance.graphqls @@ -164,6 +164,9 @@ type ServiceMaintenanceActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! diff --git a/internal/graph/schema/teams.graphqls b/internal/graph/schema/teams.graphqls index d57795bee..68bf4d91f 100644 --- a/internal/graph/schema/teams.graphqls +++ b/internal/graph/schema/teams.graphqls @@ -453,6 +453,9 @@ type TeamCreatedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -479,6 +482,9 @@ type TeamUpdatedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -524,6 +530,9 @@ type TeamCreateDeleteKeyActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -550,6 +559,9 @@ type TeamConfirmDeleteKeyActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -576,6 +588,9 @@ type TeamMemberAddedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -616,6 +631,9 @@ type TeamMemberRemovedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -653,6 +671,9 @@ type TeamMemberSetRoleActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -693,6 +714,9 @@ type TeamEnvironmentUpdatedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! diff --git a/internal/graph/schema/tunnel.graphqls b/internal/graph/schema/tunnel.graphqls index c26a8df56..979f23c72 100644 --- a/internal/graph/schema/tunnel.graphqls +++ b/internal/graph/schema/tunnel.graphqls @@ -168,6 +168,9 @@ type TunnelCreatedActivityLogEntry implements ActivityLogEntry & Node { """ actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + """ Creation time of the entry. """ @@ -227,6 +230,9 @@ type TunnelDeletedActivityLogEntry implements ActivityLogEntry & Node { """ actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + """ Creation time of the entry. """ diff --git a/internal/graph/schema/unleash.graphqls b/internal/graph/schema/unleash.graphqls index e803c4447..3a6eebd49 100644 --- a/internal/graph/schema/unleash.graphqls +++ b/internal/graph/schema/unleash.graphqls @@ -185,6 +185,9 @@ type UnleashInstanceCreatedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -211,6 +214,9 @@ type UnleashInstanceUpdatedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -251,6 +257,9 @@ type UnleashInstanceDeletedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! diff --git a/internal/graph/schema/valkey.graphqls b/internal/graph/schema/valkey.graphqls index 4d1280922..0277dd45d 100644 --- a/internal/graph/schema/valkey.graphqls +++ b/internal/graph/schema/valkey.graphqls @@ -398,6 +398,9 @@ type ValkeyCreatedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -424,6 +427,9 @@ type ValkeyUpdatedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -476,6 +482,9 @@ type ValkeyDeletedActivityLogEntry implements ActivityLogEntry & Node { "The identity of the actor who performed the action. The value is either the name of a service account, or the email address of a user." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! @@ -533,6 +542,9 @@ type ValkeyCredentialsCreatedActivityLogEntry implements ActivityLogEntry & Node "The identity of the actor who performed the action." actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + "Creation time of the entry." createdAt: Time! diff --git a/internal/graph/schema/vulnerability.graphqls b/internal/graph/schema/vulnerability.graphqls index cb85562c3..e7f244b2a 100644 --- a/internal/graph/schema/vulnerability.graphqls +++ b/internal/graph/schema/vulnerability.graphqls @@ -851,6 +851,9 @@ type VulnerabilityUpdatedActivityLogEntry implements ActivityLogEntry & Node { """ actor: String! + "GitHub Actions OIDC claims when authenticated by a GitHub repository." + gitHubActorClaims: GitHubActorClaims + """ Creation time of the entry. """ diff --git a/internal/kubernetes/fake/postgres_fixtures_test.go b/internal/kubernetes/fake/postgres_fixtures_test.go index abb4d9d9f..d10508d96 100644 --- a/internal/kubernetes/fake/postgres_fixtures_test.go +++ b/internal/kubernetes/fake/postgres_fixtures_test.go @@ -13,6 +13,8 @@ func TestPostgresFixturesUseRegisteredV1Kinds(t *testing.T) { if err != nil { t.Fatal(err) } + // Each directory is a separate integration suite; fixtures in different + // suites may intentionally describe the same resource. for _, path := range []string{ "../../../integration_tests/k8s_resources/create_postgres_access", "../../../integration_tests/k8s_resources/postgres_instances", @@ -30,7 +32,8 @@ func TestPostgresFixturesUseRegisteredV1Kinds(t *testing.T) { t.Errorf("%s: no fixtures", path) } // Parsing alone does not detect two files declaring the same resource. - // Insert every object into the same fake tracker used by the Lua suite. + // One fake tracker per cluster and suite catches duplicate identities + // across all files belonging to that cluster, as in the Lua runner. for _, objects := range resources { client := fake.NewDynamicClient(scheme) fake.AddObjectToDynamicClient(scheme, client, objects...) diff --git a/internal/workload/application/activitylog.go b/internal/workload/application/activitylog.go index 5c69abb16..841a402c6 100644 --- a/internal/workload/application/activitylog.go +++ b/internal/workload/application/activitylog.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/nais/api/internal/activitylog" + "github.com/nais/api/internal/auth/middleware/github" "github.com/nais/api/internal/deployment/deploymentactivity" ) @@ -61,6 +62,7 @@ func init() { if err != nil { return nil, fmt.Errorf("transforming application created activity log entry data: %w", err) } + data.GitHubActorClaims = entry.GitHubActorClaims return ApplicationCreatedActivityLogEntry{ GenericActivityLogEntry: entry.WithMessage(fmt.Sprintf("Application %s created", entry.ResourceName)), Data: data, @@ -70,6 +72,7 @@ func init() { if err != nil { return nil, fmt.Errorf("transforming application updated activity log entry data: %w", err) } + data.GitHubActorClaims = entry.GitHubActorClaims return ApplicationUpdatedActivityLogEntry{ GenericActivityLogEntry: entry.WithMessage(fmt.Sprintf("Application %s updated", entry.ResourceName)), Data: data, @@ -120,5 +123,5 @@ type ApplicationUpdatedActivityLogEntry struct { type ApplicationUpdatedActivityLogEntryData struct { ChangedFields []*activitylog.ResourceChangedField `json:"changedFields"` - GitHubActorClaims *activitylog.GitHubActorClaims `json:"gitHubActorClaims,omitempty"` + GitHubActorClaims *github.GitHubActorClaims `json:"-"` } diff --git a/internal/workload/job/activitylog.go b/internal/workload/job/activitylog.go index eb7acb5ac..b9aad7e0d 100644 --- a/internal/workload/job/activitylog.go +++ b/internal/workload/job/activitylog.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/nais/api/internal/activitylog" + "github.com/nais/api/internal/auth/middleware/github" "github.com/nais/api/internal/deployment/deploymentactivity" ) @@ -58,6 +59,7 @@ func init() { if err != nil { return nil, fmt.Errorf("transforming job created activity log entry data: %w", err) } + data.GitHubActorClaims = entry.GitHubActorClaims return JobCreatedActivityLogEntry{ GenericActivityLogEntry: entry.WithMessage(fmt.Sprintf("Job %s created", entry.ResourceName)), Data: data, @@ -67,6 +69,7 @@ func init() { if err != nil { return nil, fmt.Errorf("transforming job updated activity log entry data: %w", err) } + data.GitHubActorClaims = entry.GitHubActorClaims return JobUpdatedActivityLogEntry{ GenericActivityLogEntry: entry.WithMessage(fmt.Sprintf("Job %s updated", entry.ResourceName)), Data: data, @@ -115,5 +118,5 @@ type JobUpdatedActivityLogEntry struct { type JobUpdatedActivityLogEntryData struct { ChangedFields []*activitylog.ResourceChangedField `json:"changedFields"` - GitHubActorClaims *activitylog.GitHubActorClaims `json:"gitHubActorClaims,omitempty"` + GitHubActorClaims *github.GitHubActorClaims `json:"-"` } From 060cae63a3153b5fe0ada9a224531497b49f04ca Mon Sep 17 00:00:00 2001 From: Johnny Fredheim Horvi Date: Tue, 29 Sep 2026 08:11:39 +0200 Subject: [PATCH 09/19] Consolidate PostgresAccess integration fixtures and add access level --- .../activitylog_github_actor_claims.lua | 139 ++++++++++++++++ integration_tests/create_postgres_access.lua | 4 +- .../dev/someteamname/accesses.yaml | 102 ++++++++++++ .../cnpg_cluster_foobar-recovered.yaml | 15 -- .../dev/someteamname/cnpg_cluster_foobar.yaml | 15 -- .../dev/someteamname/connection.yaml | 76 +++++++++ .../dev/someteamname/postgres.yaml | 108 +++++++++++++ .../postgres_access_expired-access.yaml | 14 -- .../postgres_access_failed-access.yaml | 16 -- ...postgres_access_missing-secret-access.yaml | 18 --- .../postgres_access_pending-access.yaml | 14 -- .../someteamname/postgres_access_ready.yaml | 20 --- .../postgres_access_recovered-access.yaml | 14 -- .../dev/someteamname/postgres_foobar.yaml | 10 -- .../postgres_instance_foobar.yaml | 15 -- .../postgres_instance_progressing.yaml | 15 -- .../postgres_instance_recovered.yaml | 15 -- .../someteamname/postgres_legacy-only.yaml | 8 - .../someteamname/postgres_progressing.yaml | 10 -- .../relay_access_missing_secret.yaml | 17 -- .../dev/someteamname/relay_access_ready.yaml | 17 -- .../dev/someteamname/secret_pg_foobar_ca.yaml | 8 - .../secret_ready_access_credentials.yaml | 15 -- .../secret_ready_access_relay_token.yaml | 14 -- internal/activitylog/queries_test.go | 153 ++++++++++++++++++ internal/auth/middleware/github/claims.go | 30 ++++ .../0075_normalize_github_actor_claims.sql | 84 ++++++++++ .../0076_activity_log_github_actor_claims.sql | 72 +++++++++ internal/graph/gengql/postgres.generated.go | 41 +++++ internal/graph/gengql/root_.generated.go | 18 ++- internal/graph/schema/postgres.graphqls | 7 +- internal/persistence/postgres/activitylog.go | 13 +- internal/persistence/postgres/queries.go | 7 +- 33 files changed, 839 insertions(+), 285 deletions(-) create mode 100644 integration_tests/activitylog_github_actor_claims.lua create mode 100644 integration_tests/k8s_resources/create_postgres_access/dev/someteamname/accesses.yaml delete mode 100644 integration_tests/k8s_resources/create_postgres_access/dev/someteamname/cnpg_cluster_foobar-recovered.yaml delete mode 100644 integration_tests/k8s_resources/create_postgres_access/dev/someteamname/cnpg_cluster_foobar.yaml create mode 100644 integration_tests/k8s_resources/create_postgres_access/dev/someteamname/connection.yaml create mode 100644 integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres.yaml delete mode 100644 integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_expired-access.yaml delete mode 100644 integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_failed-access.yaml delete mode 100644 integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_missing-secret-access.yaml delete mode 100644 integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_pending-access.yaml delete mode 100644 integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_ready.yaml delete mode 100644 integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_recovered-access.yaml delete mode 100644 integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_foobar.yaml delete mode 100644 integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_instance_foobar.yaml delete mode 100644 integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_instance_progressing.yaml delete mode 100644 integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_instance_recovered.yaml delete mode 100644 integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_legacy-only.yaml delete mode 100644 integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_progressing.yaml delete mode 100644 integration_tests/k8s_resources/create_postgres_access/dev/someteamname/relay_access_missing_secret.yaml delete mode 100644 integration_tests/k8s_resources/create_postgres_access/dev/someteamname/relay_access_ready.yaml delete mode 100644 integration_tests/k8s_resources/create_postgres_access/dev/someteamname/secret_pg_foobar_ca.yaml delete mode 100644 integration_tests/k8s_resources/create_postgres_access/dev/someteamname/secret_ready_access_credentials.yaml delete mode 100644 integration_tests/k8s_resources/create_postgres_access/dev/someteamname/secret_ready_access_relay_token.yaml create mode 100644 internal/activitylog/queries_test.go create mode 100644 internal/auth/middleware/github/claims.go create mode 100644 internal/database/migrations/0075_normalize_github_actor_claims.sql create mode 100644 internal/database/migrations/0076_activity_log_github_actor_claims.sql diff --git a/integration_tests/activitylog_github_actor_claims.lua b/integration_tests/activitylog_github_actor_claims.lua new file mode 100644 index 000000000..e3a57bfb7 --- /dev/null +++ b/integration_tests/activitylog_github_actor_claims.lua @@ -0,0 +1,139 @@ +local user = User.new() +local team = Team.new("activity-claims", "Activity claims", "#activity-claims") +team:addMember(user) + +Test.sql("Store GitHub actor claims separately from activity log data", function(t) + Helper.SQLExec([[ + INSERT INTO activity_log_entries + (actor, action, resource_type, resource_name, team_slug, environment, created_at, data, github_actor_claims) + VALUES + ( + 'github-repo:nais/example', 'CREATED', 'APP', 'claims-created', $1, 'dev', + NOW() - INTERVAL '1 minute', + CONVERT_TO('{"apiVersion":"nais.io/v1alpha1","kind":"Application"}', 'UTF8'), + '{"actor":"octocat","repository":"nais/example","run_id":"123"}'::JSONB + ), + ( + 'github-repo:nais/example', 'UPDATED', 'APP', 'claims-updated', $1, 'dev', + NOW() - INTERVAL '2 minutes', + CONVERT_TO('{"changedFields":[{"field":"spec.image"}]}', 'UTF8'), + '{"actor":"octocat","repository":"nais/example","run_id":"124"}'::JSONB + ), + ( + 'github-repo:nais/example', 'UPDATED', 'JOB', 'claims-job-updated', $1, 'dev', + NOW() - INTERVAL '150 seconds', + CONVERT_TO('{"changedFields":[]}', 'UTF8'), + '{"actor":"octocat","repository":"nais/example","run_id":"126"}'::JSONB + ), + ( + 'github-repo:nais/example', 'CREATED', 'APP', 'claims-legacy', $1, 'dev', + NOW() - INTERVAL '3 minutes', + CONVERT_TO('{"apiVersion":"nais.io/v1alpha1","kind":"Application","gitHubActorClaims":{"actor":"octocat","repository":"nais/example","run_id":"125"}}', 'UTF8'), + NULL + ), + ( + 'human@example.com', 'CREATED', 'APP', 'claims-absent', $1, 'dev', + NOW() - INTERVAL '4 minutes', + CONVERT_TO('{"apiVersion":"nais.io/v1alpha1","kind":"Application"}', 'UTF8'), + NULL + ) + ]], team:slug()) + + t.queryRow([[ + SELECT + github_actor_claims ->> 'actor' AS actor, + CONVERT_FROM(data, 'UTF8')::JSONB ? 'gitHubActorClaims' AS claims_in_data + FROM activity_log_entries + WHERE resource_name = 'claims-created' + ]]) + t.check { + actor = "octocat", + claims_in_data = false, + } +end) + +Test.gql("Activity log exposes stored and legacy GitHub actor claims", function(t) + t.addHeader("x-user-email", user:email()) + t.query(string.format([[ + query { + team(slug: "%s") { + activityLog( + first: 10 + filter: { activityTypes: [GENERIC_KUBERNETES_RESOURCE_CREATED, APPLICATION_UPDATED, JOB_UPDATED] } + ) { + nodes { + resourceName + gitHubActorClaims { actor repository runID } + ... on ApplicationCreatedActivityLogEntry { + data { + kind + gitHubActorClaims { actor runID } + } + } + ... on ApplicationUpdatedActivityLogEntry { + data { + changedFields { field } + gitHubActorClaims { actor runID } + } + } + ... on JobUpdatedActivityLogEntry { + data { + gitHubActorClaims { actor runID } + } + } + } + } + } + } + ]], team:slug())) + + t.check { + data = { + team = { + activityLog = { + nodes = { + { + resourceName = "claims-created", + gitHubActorClaims = { actor = "octocat", repository = "nais/example", runID = "123" }, + data = { + kind = "Application", + gitHubActorClaims = { actor = "octocat", runID = "123" }, + }, + }, + { + resourceName = "claims-updated", + gitHubActorClaims = { actor = "octocat", repository = "nais/example", runID = "124" }, + data = { + changedFields = { { field = "spec.image" } }, + gitHubActorClaims = { actor = "octocat", runID = "124" }, + }, + }, + { + resourceName = "claims-job-updated", + gitHubActorClaims = { actor = "octocat", repository = "nais/example", runID = "126" }, + data = { + gitHubActorClaims = { actor = "octocat", runID = "126" }, + }, + }, + { + resourceName = "claims-legacy", + gitHubActorClaims = { actor = "octocat", repository = "nais/example", runID = "125" }, + data = { + kind = "Application", + gitHubActorClaims = { actor = "octocat", runID = "125" }, + }, + }, + { + resourceName = "claims-absent", + gitHubActorClaims = Null, + data = { + kind = "Application", + gitHubActorClaims = Null, + }, + }, + }, + }, + }, + }, + } +end) diff --git a/integration_tests/create_postgres_access.lua b/integration_tests/create_postgres_access.lua index 4f47bf038..9d8969e1e 100644 --- a/integration_tests/create_postgres_access.lua +++ b/integration_tests/create_postgres_access.lua @@ -177,6 +177,7 @@ Test.gql("Personal postgres access is audited as a self-grant", function(t) ... on PostgresPersonalAccessCreatedActivityLogEntry { data { username + accessLevel expiresAt reason } @@ -193,9 +194,10 @@ Test.gql("Personal postgres access is audited as a self-grant", function(t) activityLog = { nodes = { { - message = Contains("Created personal Postgres access for user@usersen.com"), + message = Contains("Requested READWRITE personal Postgres access for user@usersen.com"), data = { username = "user@usersen.com", + accessLevel = "READWRITE", expiresAt = NotNull(), reason = "Testing personal database access", }, diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/accesses.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/accesses.yaml new file mode 100644 index 000000000..035e27731 --- /dev/null +++ b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/accesses.yaml @@ -0,0 +1,102 @@ +--- +apiVersion: nais.io/v1 +kind: PostgresAccess +metadata: + name: ready-access + namespace: someteamname + uid: 11111111-1111-4111-8111-111111111111 +spec: + postgresInstance: foobar + username: user@usersen.com + accessLevel: readwrite + expiresAt: "2099-09-17T12:00:00Z" +status: + databaseRole: user-foobar-role + relayAccess: ready-access + tokenSecret: ready-access-relay-token + conditions: + - type: Ready + status: "True" + reason: Ready + message: "database role and relay mapping are ready" +--- +apiVersion: nais.io/v1 +kind: PostgresAccess +metadata: + name: recovered-access + namespace: someteamname +spec: + postgresInstance: foobar-recovered + username: user@usersen.com + accessLevel: read + expiresAt: "2099-09-17T12:00:00Z" +status: + conditions: + - type: Ready + status: "False" +--- +apiVersion: nais.io/v1 +kind: PostgresAccess +metadata: + name: pending-access + namespace: someteamname +spec: + postgresInstance: foobar + username: user@usersen.com + accessLevel: read + expiresAt: "2099-09-17T12:00:00Z" +status: + conditions: + - type: Ready + status: "False" +--- +apiVersion: nais.io/v1 +kind: PostgresAccess +metadata: + name: failed-access + namespace: someteamname +spec: + postgresInstance: foobar + username: user@usersen.com + accessLevel: readwritecreate + expiresAt: "2099-09-17T12:00:00Z" +status: + conditions: + - type: Ready + status: "False" + reason: UnsupportedAccessLevel + message: "readwritecreate is not supported for this Postgres instance" +--- +apiVersion: nais.io/v1 +kind: PostgresAccess +metadata: + name: expired-access + namespace: someteamname +spec: + postgresInstance: foobar + username: user@usersen.com + accessLevel: read + expiresAt: "2000-01-01T00:00:00Z" +status: + conditions: + - type: Ready + status: "True" +--- +apiVersion: nais.io/v1 +kind: PostgresAccess +metadata: + name: missing-secret-access + namespace: someteamname + uid: 22222222-2222-4222-8222-222222222222 +spec: + postgresInstance: foobar + username: user@usersen.com + accessLevel: read + expiresAt: "2099-09-17T12:00:00Z" +status: + databaseRole: user-foobar-role + relayAccess: missing-secret-access + tokenSecret: missing-secret-access-relay-token + conditions: + - type: Ready + status: "True" diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/cnpg_cluster_foobar-recovered.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/cnpg_cluster_foobar-recovered.yaml deleted file mode 100644 index 240b9a489..000000000 --- a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/cnpg_cluster_foobar-recovered.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: postgresql.cnpg.io/v1 -kind: Cluster -metadata: - name: pg-foobar-recovered - namespace: someteamname -spec: - certificates: - serverCASecret: pg-foobar-ca -status: - phase: Cluster in healthy state - conditions: - - type: Ready - status: "True" - reason: ClusterReady - lastTransitionTime: "2026-09-17T00:00:00Z" diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/cnpg_cluster_foobar.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/cnpg_cluster_foobar.yaml deleted file mode 100644 index 7b8a21ba8..000000000 --- a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/cnpg_cluster_foobar.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: postgresql.cnpg.io/v1 -kind: Cluster -metadata: - name: pg-foobar - namespace: someteamname -spec: - certificates: - serverCASecret: pg-foobar-ca -status: - phase: Cluster in healthy state - conditions: - - type: Ready - status: "True" - reason: ClusterReady - lastTransitionTime: "2026-09-17T00:00:00Z" diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/connection.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/connection.yaml new file mode 100644 index 000000000..dd158c40a --- /dev/null +++ b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/connection.yaml @@ -0,0 +1,76 @@ +--- +apiVersion: nais.io/v1alpha1 +kind: RelayAccess +metadata: + name: ready-access + namespace: someteamname + ownerReferences: + - apiVersion: nais.io/v1 + kind: PostgresAccess + name: ready-access + uid: 11111111-1111-4111-8111-111111111111 + controller: true +spec: + target: + serviceName: pg-foobar-rw + port: 5432 + expiresAt: "2099-09-17T12:00:00Z" + tokenSHA256: 630dcd2966c4336691125448bbb25b4ff412a49c732db2c8abc1b8581bd710dd +--- +apiVersion: nais.io/v1alpha1 +kind: RelayAccess +metadata: + name: missing-secret-access + namespace: someteamname + ownerReferences: + - apiVersion: nais.io/v1 + kind: PostgresAccess + name: missing-secret-access + uid: 22222222-2222-4222-8222-222222222222 + controller: true +spec: + target: + serviceName: pg-foobar-rw + port: 5432 + expiresAt: "2099-09-17T12:00:00Z" + tokenSHA256: 630dcd2966c4336691125448bbb25b4ff412a49c732db2c8abc1b8581bd710dd +--- +apiVersion: v1 +kind: Secret +metadata: + name: ready-access-relay-token + namespace: someteamname + ownerReferences: + - apiVersion: nais.io/v1 + kind: PostgresAccess + name: ready-access + uid: 11111111-1111-4111-8111-111111111111 + controller: true +type: Opaque +data: + token: QUFFQ0F3UUZCZ2NJQ1FvTERBME9EeEFSRWhNVUZSWVhHQmthR3h3ZEhoOA== +--- +apiVersion: v1 +kind: Secret +metadata: + name: ready-access-credentials + namespace: someteamname + ownerReferences: + - apiVersion: nais.io/v1 + kind: PostgresAccess + name: ready-access + uid: 11111111-1111-4111-8111-111111111111 + controller: true +type: kubernetes.io/basic-auth +data: + username: dXNlci1mb29iYXItcm9sZQ== + password: c3VwZXJzZWNyZXQ= +--- +apiVersion: v1 +kind: Secret +metadata: + name: pg-foobar-ca + namespace: someteamname +type: Opaque +data: + ca.crt: dGVzdC1jYS1jZXJ0aWZpY2F0ZQ== diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres.yaml new file mode 100644 index 000000000..7f490efa7 --- /dev/null +++ b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres.yaml @@ -0,0 +1,108 @@ +--- +apiVersion: nais.io/v1 +kind: Postgres +metadata: + name: foobar + namespace: someteamname +spec: + majorVersion: "17" +status: + activeInstance: foobar +--- +apiVersion: nais.io/v1 +kind: Postgres +metadata: + name: progressing + namespace: someteamname +spec: + majorVersion: "17" +status: + activeInstance: progressing +--- +apiVersion: nais.io/v1 +kind: Postgres +metadata: + name: legacy-only + namespace: someteamname +spec: + majorVersion: "17" +--- +apiVersion: nais.io/v1 +kind: PostgresInstance +metadata: + name: foobar + namespace: someteamname +spec: + postgres: foobar +status: + reconcilePhase: Completed + conditions: + - type: cluster.postgresql.cnpg.io/ObservedState + status: "True" + reason: Reconciled + message: "Cluster is in phase: Cluster in healthy state" + lastTransitionTime: "2026-09-17T00:00:00Z" +--- +apiVersion: nais.io/v1 +kind: PostgresInstance +metadata: + name: progressing + namespace: someteamname +spec: + postgres: progressing +status: + reconcilePhase: Preparing + conditions: + - type: cluster.postgresql.cnpg.io/ObservedState + status: "False" + reason: Reconciling + message: "Cluster is in phase: " + lastTransitionTime: "2026-09-17T00:00:00Z" +--- +apiVersion: nais.io/v1 +kind: PostgresInstance +metadata: + name: foobar-recovered + namespace: someteamname +spec: + postgres: foobar +status: + reconcilePhase: Completed + conditions: + - type: cluster.postgresql.cnpg.io/ObservedState + status: "True" + reason: Reconciled + message: "Cluster is in phase: Cluster in healthy state" + lastTransitionTime: "2026-09-17T00:00:00Z" +--- +apiVersion: postgresql.cnpg.io/v1 +kind: Cluster +metadata: + name: pg-foobar + namespace: someteamname +spec: + certificates: + serverCASecret: pg-foobar-ca +status: + phase: Cluster in healthy state + conditions: + - type: Ready + status: "True" + reason: ClusterReady + lastTransitionTime: "2026-09-17T00:00:00Z" +--- +apiVersion: postgresql.cnpg.io/v1 +kind: Cluster +metadata: + name: pg-foobar-recovered + namespace: someteamname +spec: + certificates: + serverCASecret: pg-foobar-ca +status: + phase: Cluster in healthy state + conditions: + - type: Ready + status: "True" + reason: ClusterReady + lastTransitionTime: "2026-09-17T00:00:00Z" diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_expired-access.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_expired-access.yaml deleted file mode 100644 index aab36f8c9..000000000 --- a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_expired-access.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: nais.io/v1 -kind: PostgresAccess -metadata: - name: expired-access - namespace: someteamname -spec: - postgresInstance: foobar - username: user@usersen.com - accessLevel: read - expiresAt: "2000-01-01T00:00:00Z" -status: - conditions: - - type: Ready - status: "True" diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_failed-access.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_failed-access.yaml deleted file mode 100644 index 1a13c599a..000000000 --- a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_failed-access.yaml +++ /dev/null @@ -1,16 +0,0 @@ -apiVersion: nais.io/v1 -kind: PostgresAccess -metadata: - name: failed-access - namespace: someteamname -spec: - postgresInstance: foobar - username: user@usersen.com - accessLevel: readwritecreate - expiresAt: "2099-09-17T12:00:00Z" -status: - conditions: - - type: Ready - status: "False" - reason: UnsupportedAccessLevel - message: "readwritecreate is not supported for this Postgres instance" diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_missing-secret-access.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_missing-secret-access.yaml deleted file mode 100644 index 91c78eebe..000000000 --- a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_missing-secret-access.yaml +++ /dev/null @@ -1,18 +0,0 @@ -apiVersion: nais.io/v1 -kind: PostgresAccess -metadata: - name: missing-secret-access - namespace: someteamname - uid: 22222222-2222-4222-8222-222222222222 -spec: - postgresInstance: foobar - username: user@usersen.com - accessLevel: read - expiresAt: "2099-09-17T12:00:00Z" -status: - databaseRole: user-foobar-role - relayAccess: missing-secret-access - tokenSecret: missing-secret-access-relay-token - conditions: - - type: Ready - status: "True" diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_pending-access.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_pending-access.yaml deleted file mode 100644 index 85448e023..000000000 --- a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_pending-access.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: nais.io/v1 -kind: PostgresAccess -metadata: - name: pending-access - namespace: someteamname -spec: - postgresInstance: foobar - username: user@usersen.com - accessLevel: read - expiresAt: "2099-09-17T12:00:00Z" -status: - conditions: - - type: Ready - status: "False" diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_ready.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_ready.yaml deleted file mode 100644 index e6d9f6cf6..000000000 --- a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_ready.yaml +++ /dev/null @@ -1,20 +0,0 @@ -apiVersion: nais.io/v1 -kind: PostgresAccess -metadata: - name: ready-access - namespace: someteamname - uid: 11111111-1111-4111-8111-111111111111 -spec: - postgresInstance: foobar - username: user@usersen.com - accessLevel: readwrite - expiresAt: "2099-09-17T12:00:00Z" -status: - databaseRole: user-foobar-role - relayAccess: ready-access - tokenSecret: ready-access-relay-token - conditions: - - type: Ready - status: "True" - reason: Ready - message: "database role and relay mapping are ready" diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_recovered-access.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_recovered-access.yaml deleted file mode 100644 index 2abfe46e9..000000000 --- a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_access_recovered-access.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: nais.io/v1 -kind: PostgresAccess -metadata: - name: recovered-access - namespace: someteamname -spec: - postgresInstance: foobar-recovered - username: user@usersen.com - accessLevel: read - expiresAt: "2099-09-17T12:00:00Z" -status: - conditions: - - type: Ready - status: "False" diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_foobar.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_foobar.yaml deleted file mode 100644 index 086fe4610..000000000 --- a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_foobar.yaml +++ /dev/null @@ -1,10 +0,0 @@ ---- -apiVersion: nais.io/v1 -kind: Postgres -metadata: - name: foobar - namespace: someteamname -spec: - majorVersion: "17" -status: - activeInstance: foobar diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_instance_foobar.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_instance_foobar.yaml deleted file mode 100644 index 88ea525d5..000000000 --- a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_instance_foobar.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: nais.io/v1 -kind: PostgresInstance -metadata: - name: foobar - namespace: someteamname -spec: - postgres: foobar -status: - reconcilePhase: Completed - conditions: - - type: cluster.postgresql.cnpg.io/ObservedState - status: "True" - reason: Reconciled - message: "Cluster is in phase: Cluster in healthy state" - lastTransitionTime: "2026-09-17T00:00:00Z" diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_instance_progressing.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_instance_progressing.yaml deleted file mode 100644 index 988638ad5..000000000 --- a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_instance_progressing.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: nais.io/v1 -kind: PostgresInstance -metadata: - name: progressing - namespace: someteamname -spec: - postgres: progressing -status: - reconcilePhase: Preparing - conditions: - - type: cluster.postgresql.cnpg.io/ObservedState - status: "False" - reason: Reconciling - message: "Cluster is in phase: " - lastTransitionTime: "2026-09-17T00:00:00Z" diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_instance_recovered.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_instance_recovered.yaml deleted file mode 100644 index f24d799ac..000000000 --- a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_instance_recovered.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: nais.io/v1 -kind: PostgresInstance -metadata: - name: foobar-recovered - namespace: someteamname -spec: - postgres: foobar -status: - reconcilePhase: Completed - conditions: - - type: cluster.postgresql.cnpg.io/ObservedState - status: "True" - reason: Reconciled - message: "Cluster is in phase: Cluster in healthy state" - lastTransitionTime: "2026-09-17T00:00:00Z" diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_legacy-only.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_legacy-only.yaml deleted file mode 100644 index 9f78de4bf..000000000 --- a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_legacy-only.yaml +++ /dev/null @@ -1,8 +0,0 @@ ---- -apiVersion: nais.io/v1 -kind: Postgres -metadata: - name: legacy-only - namespace: someteamname -spec: - majorVersion: "17" diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_progressing.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_progressing.yaml deleted file mode 100644 index b274f7d3b..000000000 --- a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres_progressing.yaml +++ /dev/null @@ -1,10 +0,0 @@ ---- -apiVersion: nais.io/v1 -kind: Postgres -metadata: - name: progressing - namespace: someteamname -spec: - majorVersion: "17" -status: - activeInstance: progressing diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/relay_access_missing_secret.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/relay_access_missing_secret.yaml deleted file mode 100644 index 012d84507..000000000 --- a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/relay_access_missing_secret.yaml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: nais.io/v1alpha1 -kind: RelayAccess -metadata: - name: missing-secret-access - namespace: someteamname - ownerReferences: - - apiVersion: nais.io/v1 - kind: PostgresAccess - name: missing-secret-access - uid: 22222222-2222-4222-8222-222222222222 - controller: true -spec: - target: - serviceName: pg-foobar-rw - port: 5432 - expiresAt: "2099-09-17T12:00:00Z" - tokenSHA256: 630dcd2966c4336691125448bbb25b4ff412a49c732db2c8abc1b8581bd710dd diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/relay_access_ready.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/relay_access_ready.yaml deleted file mode 100644 index c95c5fdd9..000000000 --- a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/relay_access_ready.yaml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: nais.io/v1alpha1 -kind: RelayAccess -metadata: - name: ready-access - namespace: someteamname - ownerReferences: - - apiVersion: nais.io/v1 - kind: PostgresAccess - name: ready-access - uid: 11111111-1111-4111-8111-111111111111 - controller: true -spec: - target: - serviceName: pg-foobar-rw - port: 5432 - expiresAt: "2099-09-17T12:00:00Z" - tokenSHA256: 630dcd2966c4336691125448bbb25b4ff412a49c732db2c8abc1b8581bd710dd diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/secret_pg_foobar_ca.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/secret_pg_foobar_ca.yaml deleted file mode 100644 index 6c7b171d1..000000000 --- a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/secret_pg_foobar_ca.yaml +++ /dev/null @@ -1,8 +0,0 @@ -apiVersion: v1 -kind: Secret -metadata: - name: pg-foobar-ca - namespace: someteamname -type: Opaque -data: - ca.crt: dGVzdC1jYS1jZXJ0aWZpY2F0ZQ== diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/secret_ready_access_credentials.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/secret_ready_access_credentials.yaml deleted file mode 100644 index 34631543a..000000000 --- a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/secret_ready_access_credentials.yaml +++ /dev/null @@ -1,15 +0,0 @@ -apiVersion: v1 -kind: Secret -metadata: - name: ready-access-credentials - namespace: someteamname - ownerReferences: - - apiVersion: nais.io/v1 - kind: PostgresAccess - name: ready-access - uid: 11111111-1111-4111-8111-111111111111 - controller: true -type: kubernetes.io/basic-auth -data: - username: dXNlci1mb29iYXItcm9sZQ== - password: c3VwZXJzZWNyZXQ= diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/secret_ready_access_relay_token.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/secret_ready_access_relay_token.yaml deleted file mode 100644 index 0d8d2d958..000000000 --- a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/secret_ready_access_relay_token.yaml +++ /dev/null @@ -1,14 +0,0 @@ -apiVersion: v1 -kind: Secret -metadata: - name: ready-access-relay-token - namespace: someteamname - ownerReferences: - - apiVersion: nais.io/v1 - kind: PostgresAccess - name: ready-access - uid: 11111111-1111-4111-8111-111111111111 - controller: true -type: Opaque -data: - token: QUFFQ0F3UUZCZ2NJQ1FvTERBME9EeEFSRWhNVUZSWVhHQmthR3h3ZEhoOA== diff --git a/internal/activitylog/queries_test.go b/internal/activitylog/queries_test.go new file mode 100644 index 000000000..d95a5a1b3 --- /dev/null +++ b/internal/activitylog/queries_test.go @@ -0,0 +1,153 @@ +package activitylog + +import ( + "context" + "encoding/json" + "testing" + + "github.com/jackc/pgx/v5/pgconn" + "github.com/nais/api/internal/activitylog/activitylogsql" + "github.com/nais/api/internal/auth/authz" + "github.com/nais/api/internal/auth/middleware/github" +) + +type claimsActor struct { + authz.AuthenticatedUser + claims *github.GitHubActorClaims +} + +func (a claimsActor) Identity() string { return "github-repo:nais/example" } + +func (a claimsActor) GitHubActorClaims() *github.GitHubActorClaims { return a.claims } + +type captureActivityLogDB struct { + activitylogsql.DBTX + args []any +} + +func (db *captureActivityLogDB) Exec(_ context.Context, _ string, args ...any) (pgconn.CommandTag, error) { + db.args = args + return pgconn.CommandTag{}, nil +} + +func TestCreateGitHubActorClaimsColumn(t *testing.T) { + claims := &github.GitHubActorClaims{Actor: "octocat", Repository: "nais/example", RunID: "123"} + for _, test := range []struct { + name string + data any + }{ + {name: "without data"}, + {name: "with data", data: &GenericKubernetesResourceActivityLogEntryData{Kind: "Application", GitHubActorClaims: claims}}, + } { + t.Run(test.name, func(t *testing.T) { + db := &captureActivityLogDB{} + ctx := context.WithValue(context.Background(), loadersKey, &loaders{internalQuerier: activitylogsql.New(db)}) + if err := Create(ctx, CreateInput{Actor: claimsActor{claims: claims}, Data: test.data}); err != nil { + t.Fatal(err) + } + if len(db.args) != 8 { + t.Fatalf("expected 8 arguments, got %d", len(db.args)) + } + if data := db.args[6].([]byte); test.data == nil { + if data != nil { + t.Fatalf("expected no data, got %s", data) + } + } else { + var payload map[string]json.RawMessage + if err := json.Unmarshal(data, &payload); err != nil { + t.Fatal(err) + } + if _, ok := payload["gitHubActorClaims"]; ok { + t.Fatalf("claims were stored in data: %s", data) + } + } + var stored github.GitHubActorClaims + if err := json.Unmarshal(db.args[7].([]byte), &stored); err != nil { + t.Fatal(err) + } + if stored.Actor != claims.Actor || stored.RunID != claims.RunID { + t.Fatalf("unexpected stored claims: %+v", stored) + } + }) + } +} + +func TestGitHubActorClaimsNotInActivityLogData(t *testing.T) { + claims := &github.GitHubActorClaims{Actor: "octocat", Repository: "nais/example", RunID: "123"} + for _, test := range []struct { + name string + data any + }{ + {name: "entry without data"}, + {name: "entry with data", data: &GenericKubernetesResourceActivityLogEntryData{ + Kind: "Application", + GitHubActorClaims: claims, + }}, + } { + t.Run(test.name, func(t *testing.T) { + data, err := MarshalData(CreateInput{Data: test.data}) + if err != nil { + t.Fatal(err) + } + if test.data == nil { + if data != nil { + t.Fatalf("expected no data, got %s", data) + } + return + } + var payload map[string]json.RawMessage + if err := json.Unmarshal(data, &payload); err != nil { + t.Fatal(err) + } + if _, ok := payload["gitHubActorClaims"]; ok { + t.Fatalf("claims must not be stored in data: %s", data) + } + if _, ok := payload["kind"]; !ok { + t.Fatalf("existing payload was lost: %s", data) + } + }) + } +} + +func TestActivityLogEntryGitHubActorClaims(t *testing.T) { + data := []byte(`{"apiVersion":"v1","kind":"ConfigMap"}`) + claims := []byte(`{"actor":"octocat","repository":"nais/example","run_id":"123"}`) + for _, test := range []struct { + name string + claims []byte + data []byte + wantClaims bool + }{ + {name: "repository actor", claims: claims, data: data, wantClaims: true}, + {name: "column takes precedence over legacy data", claims: claims, data: []byte(`{"kind":"ConfigMap","gitHubActorClaims":{"actor":"old"}}`), wantClaims: true}, + {name: "legacy entry", data: []byte(`{"apiVersion":"v1","kind":"ConfigMap","gitHubActorClaims":{"actor":"octocat","run_id":"123"}}`), wantClaims: true}, + {name: "entry without claims", data: data}, + } { + t.Run(test.name, func(t *testing.T) { + entry, err := toGraphActivityLogEntry(&activitylogsql.ActivityLogCombinedView{ + Actor: "github-repo:nais/example", + Action: string(ActivityLogEntryActionCreated), + ResourceType: "ConfigMap", + ResourceName: "example", + Data: test.data, + GithubActorClaims: test.claims, + }) + if err != nil { + t.Fatal(err) + } + generic := entry.(GenericKubernetesResourceActivityLogEntry) + if (generic.GitHubActorClaims != nil) != test.wantClaims { + t.Fatalf("unexpected claims: %+v", generic.GitHubActorClaims) + } + if test.wantClaims && generic.GitHubActorClaims.RunID != "123" { + t.Fatalf("unexpected claims: %+v", generic.GitHubActorClaims) + } + if generic.Data.GitHubActorClaims != generic.GitHubActorClaims { + t.Fatalf("deprecated data field does not match entry claims") + } + if generic.Data.Kind != "ConfigMap" { + t.Fatalf("existing data was lost: %+v", generic.Data) + } + }) + } +} diff --git a/internal/auth/middleware/github/claims.go b/internal/auth/middleware/github/claims.go new file mode 100644 index 000000000..b50abd129 --- /dev/null +++ b/internal/auth/middleware/github/claims.go @@ -0,0 +1,30 @@ +package github + +// GitHubActorClaims holds the GitHub OIDC claims that are stored +// alongside activity log entries for audit purposes. +// See https://docs.github.com/en/actions/reference/security/oidc#oidc-token-claims. +type GitHubActorClaims struct { + Actor string `json:"actor"` + ActorID *string `json:"actor_id,omitempty"` + BaseRef *string `json:"base_ref,omitempty"` + CheckRunID *string `json:"check_run_id,omitempty"` + Environment string `json:"environment"` + EventName string `json:"event_name"` + HeadRef *string `json:"head_ref,omitempty"` + JobWorkflowRef string `json:"job_workflow_ref"` + JobWorkflowSha *string `json:"job_workflow_sha,omitempty"` + Ref string `json:"ref"` + RefType *string `json:"ref_type,omitempty"` + Repository string `json:"repository"` + RepositoryID string `json:"repository_id"` + RepositoryOwner *string `json:"repository_owner,omitempty"` + RepositoryOwnerID *string `json:"repository_owner_id,omitempty"` + RepositoryVisibility *string `json:"repository_visibility,omitempty"` + RunAttempt string `json:"run_attempt"` + RunID string `json:"run_id"` + RunnerEnvironment *string `json:"runner_environment,omitempty"` + RunNumber *string `json:"run_number,omitempty"` + Workflow string `json:"workflow"` + WorkflowRef *string `json:"workflow_ref,omitempty"` + WorkflowSha *string `json:"workflow_sha,omitempty"` +} diff --git a/internal/database/migrations/0075_normalize_github_actor_claims.sql b/internal/database/migrations/0075_normalize_github_actor_claims.sql new file mode 100644 index 000000000..cba5af9bc --- /dev/null +++ b/internal/database/migrations/0075_normalize_github_actor_claims.sql @@ -0,0 +1,84 @@ +-- +goose Up +-- Activity log data predates the OIDC claim struct and uses camelCase keys. +-- Normalize those keys to match the names used when decoding GitHub tokens. +WITH + entries AS ( + SELECT + id, + CONVERT_FROM(data, 'UTF8')::JSONB AS payload + FROM + activity_log_entries + WHERE + data IS NOT NULL + ), + renamed AS ( + SELECT + id, + JSONB_SET( + payload, + '{gitHubActorClaims}', + ( + SELECT + JSONB_OBJECT_AGG( + CASE claim.key + WHEN 'actorId' THEN 'actor_id' + WHEN 'baseRef' THEN 'base_ref' + WHEN 'checkRunId' THEN 'check_run_id' + WHEN 'eventName' THEN 'event_name' + WHEN 'headRef' THEN 'head_ref' + WHEN 'jobWorkflowRef' THEN 'job_workflow_ref' + WHEN 'jobWorkflowSha' THEN 'job_workflow_sha' + WHEN 'refType' THEN 'ref_type' + WHEN 'repositoryId' THEN 'repository_id' + WHEN 'repositoryOwner' THEN 'repository_owner' + WHEN 'repositoryOwnerId' THEN 'repository_owner_id' + WHEN 'repositoryVisibility' THEN 'repository_visibility' + WHEN 'runAttempt' THEN 'run_attempt' + WHEN 'runId' THEN 'run_id' + WHEN 'runnerEnvironment' THEN 'runner_environment' + WHEN 'runNumber' THEN 'run_number' + WHEN 'workflowRef' THEN 'workflow_ref' + WHEN 'workflowSha' THEN 'workflow_sha' + ELSE claim.key + END, + claim.value + ORDER BY + STRPOS(claim.key, '_') > 0 + ) + FROM + JSONB_EACH(payload -> 'gitHubActorClaims') AS claim (key, value) + ) + ) AS payload + FROM + entries + WHERE + JSONB_TYPEOF(payload -> 'gitHubActorClaims') = 'object' + AND (payload -> 'gitHubActorClaims') ?| ARRAY[ + 'actorId', + 'baseRef', + 'checkRunId', + 'eventName', + 'headRef', + 'jobWorkflowRef', + 'jobWorkflowSha', + 'refType', + 'repositoryId', + 'repositoryOwner', + 'repositoryOwnerId', + 'repositoryVisibility', + 'runAttempt', + 'runId', + 'runnerEnvironment', + 'runNumber', + 'workflowRef', + 'workflowSha' + ] + ) +UPDATE activity_log_entries AS entry +SET + data = CONVERT_TO(renamed.payload::TEXT, 'UTF8') +FROM + renamed +WHERE + entry.id = renamed.id +; diff --git a/internal/database/migrations/0076_activity_log_github_actor_claims.sql b/internal/database/migrations/0076_activity_log_github_actor_claims.sql new file mode 100644 index 000000000..883d9698b --- /dev/null +++ b/internal/database/migrations/0076_activity_log_github_actor_claims.sql @@ -0,0 +1,72 @@ +-- +goose Up +ALTER TABLE activity_log_entries +ADD COLUMN IF NOT EXISTS github_actor_claims JSONB +; + +-- Move legacy claims out of data now that all writers use the dedicated column. +-- Safe to rerun: only rows still containing the legacy key are updated. +WITH + entries AS ( + SELECT + id, + CONVERT_FROM(data, 'UTF8')::JSONB AS payload + FROM + activity_log_entries + WHERE + data IS NOT NULL + ) +UPDATE activity_log_entries AS entry +SET + github_actor_claims = COALESCE( + entry.github_actor_claims, + NULLIF( + entries.payload -> 'gitHubActorClaims', + 'null'::JSONB + ) + ), + data = CONVERT_TO( + (entries.payload - 'gitHubActorClaims')::TEXT, + 'UTF8' + ) +FROM + entries +WHERE + entry.id = entries.id + AND JSONB_TYPEOF(entries.payload) = 'object' + AND entries.payload ? 'gitHubActorClaims' +; + +-- Some tenants still have team_slug typed as slug in this view. Replacing it +-- would fail when the new SELECT produces text, so recreate the view instead. +DROP VIEW IF EXISTS activity_log_combined_view +; + +CREATE VIEW activity_log_combined_view AS +SELECT + id, + created_at, + actor, + action, + resource_type, + resource_name, + team_slug::TEXT AS team_slug, + data, + environment, + github_actor_claims +FROM + activity_log_entries +UNION ALL +SELECT + id, + created_at, + actor, + action, + resource_type, + resource_name, + team_slug, + data, + environment, + NULL::JSONB AS github_actor_claims +FROM + activity_log_subset_mat_view +; diff --git a/internal/graph/gengql/postgres.generated.go b/internal/graph/gengql/postgres.generated.go index 3508589f4..614f6aa3b 100644 --- a/internal/graph/gengql/postgres.generated.go +++ b/internal/graph/gengql/postgres.generated.go @@ -2353,6 +2353,29 @@ func (ec *executionContext) fieldContext_PostgresPersonalAccessCreatedActivityLo return graphql.NewScalarFieldContext("PostgresPersonalAccessCreatedActivityLogEntryData", field, false, false, errors.New("field of type String does not have child fields")) } +func (ec *executionContext) _PostgresPersonalAccessCreatedActivityLogEntryData_accessLevel(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresPersonalAccessCreatedActivityLogEntryData) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_PostgresPersonalAccessCreatedActivityLogEntryData_accessLevel(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.AccessLevel, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *postgres.PostgresAccessLevel) graphql.Marshaler { + return ec.marshalOPostgresAccessLevel2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccessLevel(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_PostgresPersonalAccessCreatedActivityLogEntryData_accessLevel(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresPersonalAccessCreatedActivityLogEntryData", field, false, false, errors.New("field of type PostgresAccessLevel does not have child fields")) +} + func (ec *executionContext) _PostgresPersonalAccessCreatedActivityLogEntryData_expiresAt(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresPersonalAccessCreatedActivityLogEntryData) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -3994,6 +4017,8 @@ func (ec *executionContext) _PostgresPersonalAccessCreatedActivityLogEntryData(c if out.Values[i] == graphql.Null { out.Invalids++ } + case "accessLevel": + out.Values[i] = ec._PostgresPersonalAccessCreatedActivityLogEntryData_accessLevel(ctx, field, obj) case "expiresAt": out.Values[i] = ec._PostgresPersonalAccessCreatedActivityLogEntryData_expiresAt(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -4352,6 +4377,22 @@ func (ec *executionContext) marshalNTeamInventoryCountPostgresInstances2ᚖgithu return ec._TeamInventoryCountPostgresInstances(ctx, sel, v) } +func (ec *executionContext) unmarshalOPostgresAccessLevel2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccessLevel(ctx context.Context, v any) (*postgres.PostgresAccessLevel, error) { + if v == nil { + return nil, nil + } + var res = new(postgres.PostgresAccessLevel) + err := res.UnmarshalGQL(v) + return res, graphql.ErrorOnPath(ctx, err) +} + +func (ec *executionContext) marshalOPostgresAccessLevel2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccessLevel(ctx context.Context, sel ast.SelectionSet, v *postgres.PostgresAccessLevel) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return v +} + func (ec *executionContext) marshalOPostgresInstanceFacets2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceFacets(ctx context.Context, sel ast.SelectionSet, v *postgres.PostgresInstanceFacets) graphql.Marshaler { if v == nil { return graphql.Null diff --git a/internal/graph/gengql/root_.generated.go b/internal/graph/gengql/root_.generated.go index 2715b03cc..be74da54f 100644 --- a/internal/graph/gengql/root_.generated.go +++ b/internal/graph/gengql/root_.generated.go @@ -2012,9 +2012,10 @@ type ComplexityRoot struct { } PostgresPersonalAccessCreatedActivityLogEntryData struct { - ExpiresAt func(childComplexity int) int - Reason func(childComplexity int) int - Username func(childComplexity int) int + AccessLevel func(childComplexity int) int + ExpiresAt func(childComplexity int) int + Reason func(childComplexity int) int + Username func(childComplexity int) int } PostgresResources struct { @@ -12210,6 +12211,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.PostgresPersonalAccessCreatedActivityLogEntry.TeamSlug(childComplexity), true + case "PostgresPersonalAccessCreatedActivityLogEntryData.accessLevel": + if e.ComplexityRoot.PostgresPersonalAccessCreatedActivityLogEntryData.AccessLevel == nil { + break + } + + return e.ComplexityRoot.PostgresPersonalAccessCreatedActivityLogEntryData.AccessLevel(childComplexity), true + case "PostgresPersonalAccessCreatedActivityLogEntryData.expiresAt": if e.ComplexityRoot.PostgresPersonalAccessCreatedActivityLogEntryData.ExpiresAt == nil { break @@ -27664,6 +27672,8 @@ type PostgresPersonalAccessCreatedActivityLogEntry implements ActivityLogEntry & type PostgresPersonalAccessCreatedActivityLogEntryData { "Identity that owns the new personal access." username: String! + "Requested privilege level; null for events recorded before this field was added." + accessLevel: PostgresAccessLevel "Server-controlled expiry of the access." expiresAt: Time! "Caller-provided audit reason." @@ -37824,6 +37834,8 @@ func (ec *executionContext) childFields_PostgresPersonalAccessCreatedActivityLog switch field.Name { case "username": return ec.fieldContext_PostgresPersonalAccessCreatedActivityLogEntryData_username(ctx, field) + case "accessLevel": + return ec.fieldContext_PostgresPersonalAccessCreatedActivityLogEntryData_accessLevel(ctx, field) case "expiresAt": return ec.fieldContext_PostgresPersonalAccessCreatedActivityLogEntryData_expiresAt(ctx, field) case "reason": diff --git a/internal/graph/schema/postgres.graphqls b/internal/graph/schema/postgres.graphqls index b1fb7676f..7966e1e1b 100644 --- a/internal/graph/schema/postgres.graphqls +++ b/internal/graph/schema/postgres.graphqls @@ -23,10 +23,7 @@ extend type Team { extend type TeamEnvironment { "Postgres in the team environment." - postgres( - "Name of the Postgres in this team environment." - name: String! - ): Postgres! + postgres("Name of the Postgres in this team environment." name: String!): Postgres! "Named PostgresInstance in the team environment." postgresInstance( "Name of the PostgresInstance in this team environment." @@ -292,6 +289,8 @@ type PostgresPersonalAccessCreatedActivityLogEntry implements ActivityLogEntry & type PostgresPersonalAccessCreatedActivityLogEntryData { "Identity that owns the new personal access." username: String! + "Requested privilege level; null for events recorded before this field was added." + accessLevel: PostgresAccessLevel "Server-controlled expiry of the access." expiresAt: Time! "Caller-provided audit reason." diff --git a/internal/persistence/postgres/activitylog.go b/internal/persistence/postgres/activitylog.go index 0d4b9e21c..1c6999c74 100644 --- a/internal/persistence/postgres/activitylog.go +++ b/internal/persistence/postgres/activitylog.go @@ -42,8 +42,12 @@ func init() { if err != nil { return nil, fmt.Errorf("transforming postgres personal access activity log entry data: %w", err) } + message := fmt.Sprintf("Created personal Postgres access for %s until %s", data.Username, data.ExpiresAt) + if data.AccessLevel != nil { + message = fmt.Sprintf("Requested %s personal Postgres access for %s until %s", *data.AccessLevel, data.Username, data.ExpiresAt) + } return PostgresPersonalAccessCreatedActivityLogEntry{ - GenericActivityLogEntry: entry.WithMessage(fmt.Sprintf("Created personal Postgres access for %s until %s", data.Username, data.ExpiresAt)), + GenericActivityLogEntry: entry.WithMessage(message), Data: data, }, nil case activityLogEntryActionGetPersonalAccessConnection: @@ -83,9 +87,10 @@ type PostgresPersonalAccessCreatedActivityLogEntry struct { } type PostgresPersonalAccessCreatedActivityLogEntryData struct { - Username string `json:"username"` - ExpiresAt time.Time `json:"expiresAt"` - Reason string `json:"reason"` + Username string `json:"username"` + AccessLevel *PostgresAccessLevel `json:"accessLevel,omitempty"` + ExpiresAt time.Time `json:"expiresAt"` + Reason string `json:"reason"` } type PostgresPersonalAccessConnectionActivityLogEntry struct { diff --git a/internal/persistence/postgres/queries.go b/internal/persistence/postgres/queries.go index caf8f0c24..577bb2a4b 100644 --- a/internal/persistence/postgres/queries.go +++ b/internal/persistence/postgres/queries.go @@ -497,9 +497,10 @@ func CreatePostgresAccess(ctx context.Context, input CreatePostgresAccessInput) EnvironmentName: new(input.EnvironmentName), TeamSlug: new(input.TeamSlug), Data: PostgresPersonalAccessCreatedActivityLogEntryData{ - Username: authz.ActorFromContext(ctx).User.Identity(), - ExpiresAt: expiresAt, - Reason: input.Reason, + Username: authz.ActorFromContext(ctx).User.Identity(), + AccessLevel: new(input.AccessLevel), + ExpiresAt: expiresAt, + Reason: input.Reason, }, }); err != nil { return nil, err From 8775a906bfa7b150d985097cfa09138232e1f684 Mon Sep 17 00:00:00 2001 From: Johnny Fredheim Horvi Date: Tue, 29 Sep 2026 09:57:01 +0200 Subject: [PATCH 10/19] Fix Postgres integration test expectations --- integration_tests/create_postgres_access.lua | 2 +- integration_tests/grant_postgres_access.lua | 7 +++++-- integration_tests/postgres_audit_log.lua | 2 +- integration_tests/postgres_delete.lua | 2 +- integration_tests/postgres_instances.lua | 2 +- 5 files changed, 9 insertions(+), 6 deletions(-) diff --git a/integration_tests/create_postgres_access.lua b/integration_tests/create_postgres_access.lua index 9d8969e1e..541cdf8fc 100644 --- a/integration_tests/create_postgres_access.lua +++ b/integration_tests/create_postgres_access.lua @@ -322,7 +322,7 @@ Test.gql("PostgresAccess credentials cannot be read through generic Secret eleva }) { values { name value } } } ]], name)) t.check { - errors = { { path = { "viewSecretValues" }, message = Contains("only available through postgresAccessConnection") } }, + errors = { { locations = NotNull(), path = { "viewSecretValues" }, message = Contains("only available through postgresAccessConnection") } }, data = Null, } end diff --git a/integration_tests/grant_postgres_access.lua b/integration_tests/grant_postgres_access.lua index eb7a7ee16..fd3458337 100644 --- a/integration_tests/grant_postgres_access.lua +++ b/integration_tests/grant_postgres_access.lua @@ -1,8 +1,11 @@ --- Port-forward RBAC grants were removed with the legacy Postgres CRD. +-- The old port-forward grant mutation must not reappear in the public schema. +local user = User.new("postgres-grant-check", "postgres-grant-check@usersen.com") + Test.gql("Legacy Postgres grant mutation is no longer available", function(t) + t.addHeader("x-user-email", user:email()) t.query [[mutation { grantPostgresAccess(input: { clusterName: "legacy", teamSlug: "someteamname", environmentName: "dev", grantee: "someone@example.com", duration: "1h" }) { error } }]] - t.check { errors = { { message = Contains("grantPostgresAccess") } }, data = Null } + t.check { errors = { { message = Contains("Cannot query field \"grantPostgresAccess\""), locations = NotNull() } }, data = Null } end) diff --git a/integration_tests/postgres_audit_log.lua b/integration_tests/postgres_audit_log.lua index a59785d13..ae7259636 100644 --- a/integration_tests/postgres_audit_log.lua +++ b/integration_tests/postgres_audit_log.lua @@ -11,6 +11,6 @@ Test.gql("Logical Postgres settings are not fabricated on physical instances", f postgresInstance(name:"audit-enabled") { name state postgres { name majorVersion } } } } }]] t.check { data = { team = { environment = { postgresInstance = { - name = "audit-enabled", state = "AVAILABLE", postgres = { name = "audit-enabled", majorVersion = "17" }, + name = "audit-enabled", state = "AVAILABLE", postgres = { name = "audit-enabled", majorVersion = "16" }, } } } } } end) diff --git a/integration_tests/postgres_delete.lua b/integration_tests/postgres_delete.lua index 190b79bcc..d0bf6b416 100644 --- a/integration_tests/postgres_delete.lua +++ b/integration_tests/postgres_delete.lua @@ -8,7 +8,7 @@ Test.gql("Active PostgresInstance cannot be marked for deletion", function(t) t.query [[mutation { deletePostgres(input: { name: "orders-new", environmentName: "dev", teamSlug: "pg-delete-team" }) { postgresDeleted } }]] - t.check { errors = { { path = { "deletePostgres" }, message = Contains("is active and cannot be deleted") } }, data = Null } + t.check { errors = { { locations = NotNull(), path = { "deletePostgres" }, message = Contains("is active and cannot be deleted") } }, data = Null } end) Test.gql("Inactive PostgresInstance can be deleted", function(t) diff --git a/integration_tests/postgres_instances.lua b/integration_tests/postgres_instances.lua index 0de06fcb4..8d5f80c0c 100644 --- a/integration_tests/postgres_instances.lua +++ b/integration_tests/postgres_instances.lua @@ -59,5 +59,5 @@ end) Test.gql("Delete a concrete PostgresInstance requires authorization", function(t) t.addHeader("x-user-email", nonMember:email()) t.query [[mutation { deletePostgres(input:{name:"foobar",environmentName:"dev",teamSlug:"someteamname"}) { postgresDeleted } }]] - t.check { errors = { { message = Contains('postgres:delete'), path = { "deletePostgres" } } }, data = Null } + t.check { errors = { { locations = NotNull(), message = Contains('postgres:delete'), path = { "deletePostgres" } } }, data = Null } end) From 8556f4e66ff4d89e65de9509b477c77628a1b402 Mon Sep 17 00:00:00 2001 From: Johnny Fredheim Horvi Date: Tue, 29 Sep 2026 10:25:42 +0200 Subject: [PATCH 11/19] Limit Postgres GraphQL descriptions to changed API and fix validation test --- integration_tests/grant_postgres_access.lua | 2 +- internal/graph/gengql/root_.generated.go | 49 ++++++++------------- internal/graph/schema/postgres.graphqls | 49 ++++++++------------- 3 files changed, 37 insertions(+), 63 deletions(-) diff --git a/integration_tests/grant_postgres_access.lua b/integration_tests/grant_postgres_access.lua index fd3458337..14304f3ab 100644 --- a/integration_tests/grant_postgres_access.lua +++ b/integration_tests/grant_postgres_access.lua @@ -7,5 +7,5 @@ Test.gql("Legacy Postgres grant mutation is no longer available", function(t) clusterName: "legacy", teamSlug: "someteamname", environmentName: "dev", grantee: "someone@example.com", duration: "1h" }) { error } }]] - t.check { errors = { { message = Contains("Cannot query field \"grantPostgresAccess\""), locations = NotNull() } }, data = Null } + t.check { errors = { { message = Contains("Cannot query field \"grantPostgresAccess\""), locations = NotNull(), extensions = { code = "GRAPHQL_VALIDATION_FAILED" } } }, data = Null } end) diff --git a/internal/graph/gengql/root_.generated.go b/internal/graph/gengql/root_.generated.go index c82fb9cf2..14175ca56 100644 --- a/internal/graph/gengql/root_.generated.go +++ b/internal/graph/gengql/root_.generated.go @@ -27409,7 +27409,10 @@ extend type TeamEnvironment { "Name of the PostgresInstance in this team environment." name: String! ): PostgresInstance! - "Get a PostgresAccess and its state. Available to authorized team members." + """ + EXPERIMENTAL: DO NOT USE + Get a PostgresAccess and its state. Available to authorized team members. + """ postgresAccess( "Name of the PostgresAccess in this team environment." name: String! @@ -27440,11 +27443,8 @@ extend type Job { ): PostgresInstanceConnection! } -"Ordering options for Postgres instances." input PostgresInstanceOrder { - "Field to order instances by." field: PostgresInstanceOrderField! - "Direction of the ordering." direction: OrderDirection! } @@ -27465,35 +27465,31 @@ input PostgresInstanceFilter { labels: [LabelFilter!] } -"Fields available when ordering Postgres instances." enum PostgresInstanceOrderField { - "Instance name." NAME - "Environment name." ENVIRONMENT } "A named PostgresInstance belonging to a Postgres." type PostgresInstance implements Persistence & Node { - "Opaque identifier for this instance." id: ID! - "Name of the instance." name: String! - "Team owning this instance." team: Team! - "Team environment containing this instance." teamEnvironment: TeamEnvironment! "Postgres owning this PostgresInstance." postgres: Postgres! "Workloads using this instance while it is active." workloads( - "Return the first n workloads." + "Get the first n items in the connection. This can be used in combination with the after parameter." first: Int - "Return workloads after this cursor." + + "Get items after this cursor." after: Cursor - "Return the last n workloads." + + "Get the last n items in the connection. This can be used in combination with the before parameter." last: Int - "Return workloads before this cursor." + + "Get items before this cursor." before: Cursor ): WorkloadConnection! "Current observed state of the instance." @@ -27540,13 +27536,9 @@ enum PostgresInstanceState { DEGRADED } -"Paginated PostgresInstance results." type PostgresInstanceConnection { - "Pagination metadata." pageInfo: PageInfo! - "Instances in this page." nodes: [PostgresInstance!]! - "Instances and their pagination cursors." edges: [PostgresInstanceEdge!]! """ @@ -27556,11 +27548,8 @@ type PostgresInstanceConnection { facets: PostgresInstanceFacets } -"A PostgresInstance and its pagination cursor." type PostgresInstanceEdge { - "Cursor identifying this result." cursor: Cursor! - "The matching instance." node: PostgresInstance! } @@ -27600,7 +27589,8 @@ extend enum ActivityLogEntryResourceType { POSTGRES } -"An earlier Postgres access grant recorded in the activity log." +# This is managed directly by the activitylog package since it +# combines data within the database. type PostgresGrantAccessActivityLogEntry implements ActivityLogEntry & Node { "ID of the entry." id: ID! @@ -27633,11 +27623,8 @@ type PostgresGrantAccessActivityLogEntry implements ActivityLogEntry & Node { data: PostgresGrantAccessActivityLogEntryData! } -"Details of an earlier Postgres access grant." type PostgresGrantAccessActivityLogEntryData { - "Identity that received access." grantee: String! - "End of the granted access period." until: Time! } @@ -27749,6 +27736,7 @@ extend enum ActivityLogActivityType { extend type Mutation { """ + EXPERIMENTAL: DO NOT USE Create time-limited personal access to a NAIS Postgres instance through the brokered PostgresAccess and relay flow. When the access is ready, retrieve its connection materials through PostgresAccess.connection. """ @@ -27791,7 +27779,6 @@ enum PostgresAccessLevel { READWRITECREATE } -"Input identifying the PostgresInstance to delete." input DeletePostgresInput { "Name of the Postgres instance." name: String! @@ -27801,18 +27788,15 @@ input DeletePostgresInput { teamSlug: Slug! } -"Result of requesting deletion of a PostgresInstance." type DeletePostgresPayload { "Whether or not the Postgres instance was deleted." postgresDeleted: Boolean } extend type TeamInventoryCounts { - "Counts of Postgres instances owned by the team." postgresInstances: TeamInventoryCountPostgresInstances! } -"Inventory totals for Postgres instances." type TeamInventoryCountPostgresInstances { "Total number of Postgres instances." total: Int! @@ -27840,7 +27824,10 @@ type PostgresAccess implements Node { message: String "Name of the controller-owned relay mapping, once created. Contains no credential." relayAccess: String - "Get connection materials for this ready access. Only its owner can read them." + """ + EXPERIMENTAL: DO NOT USE + Get connection materials for this ready access. Only its owner can read them. + """ connection: PostgresAccessConnection! } diff --git a/internal/graph/schema/postgres.graphqls b/internal/graph/schema/postgres.graphqls index 7966e1e1b..3b4bcd179 100644 --- a/internal/graph/schema/postgres.graphqls +++ b/internal/graph/schema/postgres.graphqls @@ -29,7 +29,10 @@ extend type TeamEnvironment { "Name of the PostgresInstance in this team environment." name: String! ): PostgresInstance! - "Get a PostgresAccess and its state. Available to authorized team members." + """ + EXPERIMENTAL: DO NOT USE + Get a PostgresAccess and its state. Available to authorized team members. + """ postgresAccess( "Name of the PostgresAccess in this team environment." name: String! @@ -60,11 +63,8 @@ extend type Job { ): PostgresInstanceConnection! } -"Ordering options for Postgres instances." input PostgresInstanceOrder { - "Field to order instances by." field: PostgresInstanceOrderField! - "Direction of the ordering." direction: OrderDirection! } @@ -85,35 +85,31 @@ input PostgresInstanceFilter { labels: [LabelFilter!] } -"Fields available when ordering Postgres instances." enum PostgresInstanceOrderField { - "Instance name." NAME - "Environment name." ENVIRONMENT } "A named PostgresInstance belonging to a Postgres." type PostgresInstance implements Persistence & Node { - "Opaque identifier for this instance." id: ID! - "Name of the instance." name: String! - "Team owning this instance." team: Team! - "Team environment containing this instance." teamEnvironment: TeamEnvironment! "Postgres owning this PostgresInstance." postgres: Postgres! "Workloads using this instance while it is active." workloads( - "Return the first n workloads." + "Get the first n items in the connection. This can be used in combination with the after parameter." first: Int - "Return workloads after this cursor." + + "Get items after this cursor." after: Cursor - "Return the last n workloads." + + "Get the last n items in the connection. This can be used in combination with the before parameter." last: Int - "Return workloads before this cursor." + + "Get items before this cursor." before: Cursor ): WorkloadConnection! "Current observed state of the instance." @@ -160,13 +156,9 @@ enum PostgresInstanceState { DEGRADED } -"Paginated PostgresInstance results." type PostgresInstanceConnection { - "Pagination metadata." pageInfo: PageInfo! - "Instances in this page." nodes: [PostgresInstance!]! - "Instances and their pagination cursors." edges: [PostgresInstanceEdge!]! """ @@ -176,11 +168,8 @@ type PostgresInstanceConnection { facets: PostgresInstanceFacets } -"A PostgresInstance and its pagination cursor." type PostgresInstanceEdge { - "Cursor identifying this result." cursor: Cursor! - "The matching instance." node: PostgresInstance! } @@ -220,7 +209,8 @@ extend enum ActivityLogEntryResourceType { POSTGRES } -"An earlier Postgres access grant recorded in the activity log." +# This is managed directly by the activitylog package since it +# combines data within the database. type PostgresGrantAccessActivityLogEntry implements ActivityLogEntry & Node { "ID of the entry." id: ID! @@ -253,11 +243,8 @@ type PostgresGrantAccessActivityLogEntry implements ActivityLogEntry & Node { data: PostgresGrantAccessActivityLogEntryData! } -"Details of an earlier Postgres access grant." type PostgresGrantAccessActivityLogEntryData { - "Identity that received access." grantee: String! - "End of the granted access period." until: Time! } @@ -369,6 +356,7 @@ extend enum ActivityLogActivityType { extend type Mutation { """ + EXPERIMENTAL: DO NOT USE Create time-limited personal access to a NAIS Postgres instance through the brokered PostgresAccess and relay flow. When the access is ready, retrieve its connection materials through PostgresAccess.connection. """ @@ -411,7 +399,6 @@ enum PostgresAccessLevel { READWRITECREATE } -"Input identifying the PostgresInstance to delete." input DeletePostgresInput { "Name of the Postgres instance." name: String! @@ -421,18 +408,15 @@ input DeletePostgresInput { teamSlug: Slug! } -"Result of requesting deletion of a PostgresInstance." type DeletePostgresPayload { "Whether or not the Postgres instance was deleted." postgresDeleted: Boolean } extend type TeamInventoryCounts { - "Counts of Postgres instances owned by the team." postgresInstances: TeamInventoryCountPostgresInstances! } -"Inventory totals for Postgres instances." type TeamInventoryCountPostgresInstances { "Total number of Postgres instances." total: Int! @@ -460,7 +444,10 @@ type PostgresAccess implements Node { message: String "Name of the controller-owned relay mapping, once created. Contains no credential." relayAccess: String - "Get connection materials for this ready access. Only its owner can read them." + """ + EXPERIMENTAL: DO NOT USE + Get connection materials for this ready access. Only its owner can read them. + """ connection: PostgresAccessConnection! } From 4bb168c0f1f94b1dcafc3340543dd6a6dfa69887 Mon Sep 17 00:00:00 2001 From: Johnny Fredheim Horvi Date: Tue, 29 Sep 2026 10:59:35 +0200 Subject: [PATCH 12/19] leave old grantpgaccess for now --- .../console-backend-rbac/templates/rbac.yaml | 7 + integration_tests/create_postgres_access.lua | 16 +- integration_tests/grant_postgres_access.lua | 342 +++++++++++++++++- internal/graph/gengql/postgres.generated.go | 246 ++++++++++--- internal/graph/gengql/root_.generated.go | 114 ++++-- internal/graph/gengql/schema.generated.go | 66 ++++ internal/graph/postgres.resolvers.go | 12 +- internal/graph/schema/postgres.graphqls | 19 +- internal/kubernetes/fake/fake.go | 1 + internal/kubernetes/scheme.go | 1 + internal/persistence/postgres/connection.go | 2 +- internal/persistence/postgres/models.go | 57 ++- internal/persistence/postgres/queries.go | 6 +- 13 files changed, 772 insertions(+), 117 deletions(-) diff --git a/charts/console-backend-rbac/templates/rbac.yaml b/charts/console-backend-rbac/templates/rbac.yaml index 11e6d206d..6fff69ad4 100644 --- a/charts/console-backend-rbac/templates/rbac.yaml +++ b/charts/console-backend-rbac/templates/rbac.yaml @@ -302,6 +302,13 @@ rules: - get - list - watch + # Legacy CLI port-forward grants still validate the old Zalando cluster. + - apiGroups: + - "data.nais.io" + resources: + - postgres + verbs: + - get - apiGroups: - "nais.io" resources: diff --git a/integration_tests/create_postgres_access.lua b/integration_tests/create_postgres_access.lua index 541cdf8fc..770edb298 100644 --- a/integration_tests/create_postgres_access.lua +++ b/integration_tests/create_postgres_access.lua @@ -304,11 +304,11 @@ end) Test.gql("PostgresAccess connection rejects a different team member", function(t) t.addHeader("x-user-email", otherMemberUser:email()) t.query [[ - query { team(slug: "someteamname") { environment(name: "dev") { postgresAccess(name: "ready-access") { connection { password } } } } } + query { team(slug: "someteamname") { environment(name: "dev") { postgresAccess(name: "ready-access") { state connection { password } } } } } ]] t.check { errors = { { locations = NotNull(), path = { "team", "environment", "postgresAccess", "connection" }, message = Contains("not authorized") } }, - data = Null, + data = { team = { environment = { postgresAccess = { state = "READY", connection = Null } } } }, } end) @@ -331,17 +331,17 @@ end) Test.gql("PostgresAccess connection rejects expired, unready, and missing-secret access", function(t) t.addHeader("x-user-email", user:email()) for _, test in ipairs({ - { name = "expired-access", message = "has expired" }, - { name = "pending-access", message = "is not ready" }, - { name = "failed-access", message = "is not ready" }, - { name = "missing-secret-access", message = "secrets for PostgresAccess is not available" }, + { name = "expired-access", state = "EXPIRED", message = "has expired" }, + { name = "pending-access", state = "PENDING", message = "is not ready" }, + { name = "failed-access", state = "FAILED", message = "is not ready" }, + { name = "missing-secret-access", state = "READY", message = "secrets for PostgresAccess is not available" }, }) do t.query(string.format( - [[query { team(slug: "someteamname") { environment(name: "dev") { postgresAccess(name: "%s") { connection { password } } } } }]], + [[query { team(slug: "someteamname") { environment(name: "dev") { postgresAccess(name: "%s") { state connection { password } } } } }]], test.name)) t.check { errors = { { locations = NotNull(), path = { "team", "environment", "postgresAccess", "connection" }, message = Contains(test.message) } }, - data = Null, + data = { team = { environment = { postgresAccess = { state = test.state, connection = Null } } } }, } end end) diff --git a/integration_tests/grant_postgres_access.lua b/integration_tests/grant_postgres_access.lua index 14304f3ab..adaf55453 100644 --- a/integration_tests/grant_postgres_access.lua +++ b/integration_tests/grant_postgres_access.lua @@ -1,11 +1,337 @@ --- The old port-forward grant mutation must not reappear in the public schema. -local user = User.new("postgres-grant-check", "postgres-grant-check@usersen.com") +local user = User.new("user", "user@usersen.com") +local nonMemberUser = User.new("nonmember", "other@user.com") -Test.gql("Legacy Postgres grant mutation is no longer available", function(t) +local mainTeam = Team.new("someteamname", "purpose", "#slack_channel") +mainTeam:addMember(user) + +Helper.readK8sResources("k8s_resources/grant_zalando_postgres_access") + +Test.gql("Grant postgres access without authorization in non-existent team", function(t) + t.addHeader("x-user-email", user:email()) + t.query([[ + mutation GrantPostgresAccess { + grantPostgresAccess( + input: { + clusterName: "foobar" + environmentName: "dev" + teamSlug: "non-existing-team" + grantee: "some@email.com" + duration: "30m" + } + ) { + error + } + } + ]]) + + t.check({ + errors = { + { + locations = NotNull(), + message = Contains('you need the "postgres:access:grant" authorization.'), + path = { + "grantPostgresAccess", + }, + }, + }, + data = Null, + }) +end) + +Test.gql("Grant postgres access without authorization in existing team", function(t) + t.addHeader("x-user-email", nonMemberUser:email()) + t.query([[ + mutation GrantPostgresAccess { + grantPostgresAccess( + input: { + clusterName: "foobar" + environmentName: "dev" + teamSlug: "someteamname" + grantee: "some@email.com" + duration: "30m" + } + ) { + error + } + } + ]]) + + t.check({ + errors = { + { + locations = NotNull(), + message = Contains('you need the "postgres:access:grant" authorization.'), + path = { + "grantPostgresAccess", + }, + }, + }, + data = Null, + }) +end) + +Test.gql("Grant postgres access with invalid duration", function(t) + t.addHeader("x-user-email", user:email()) + t.query([[ + mutation GrantPostgresAccess { + grantPostgresAccess( + input: { + clusterName: "foobar" + environmentName: "dev" + teamSlug: "someteamname" + grantee: "some@email.com" + duration: "halfhour" + } + ) { + error + } + } + ]]) + + t.check({ + errors = { + { + extensions = { + field = "duration", + }, + message = Contains('invalid duration "halfhour"'), + path = { + "grantPostgresAccess", + }, + }, + }, + data = Null, + }) +end) + +Test.gql("Grant postgres access with out-of-bounds duration", function(t) + t.addHeader("x-user-email", user:email()) + t.query([[ + mutation GrantPostgresAccess { + grantPostgresAccess( + input: { + clusterName: "foobar" + environmentName: "dev" + teamSlug: "someteamname" + grantee: "some@email.com" + duration: "24h" + } + ) { + error + } + } + ]]) + + t.check({ + errors = { + { + extensions = { + field = "duration", + }, + message = Contains('Duration "24h" is out-of-bounds'), + path = { + "grantPostgresAccess", + }, + }, + }, + data = Null, + }) +end) + +Test.gql("Grant postgres access to non-existing cluster", function(t) + t.addHeader("x-user-email", user:email()) + t.query([[ + mutation GrantPostgresAccess { + grantPostgresAccess( + input: { + clusterName: "baz" + environmentName: "dev" + teamSlug: "someteamname" + grantee: "some@email.com" + duration: "4h" + } + ) { + error + } + } + ]]) + + t.check({ + errors = { + { + extensions = { + field = "clusterName", + }, + message = Contains("Could not find postgres cluster"), + path = { + "grantPostgresAccess", + }, + }, + }, + data = Null, + }) +end) + +Test.gql("Grant postgres access with authorization", function(t) + t.addHeader("x-user-email", user:email()) + t.query([[ + mutation GrantPostgresAccess { + grantPostgresAccess( + input: { + clusterName: "foobar" + environmentName: "dev" + teamSlug: "someteamname" + grantee: "some@email.com" + duration: "30m" + } + ) { + error + } + } + ]]) + + t.check({ + data = { + grantPostgresAccess = { + error = "", + }, + }, + }) +end) + +Test.k8s("Validate Role resource", function(t) + local resourceName = "pg-grant-93a898ea" + local pgNamespace = string.format("pg-%s", mainTeam:slug()) + + t.check("rbac.authorization.k8s.io/v1", "roles", "dev", pgNamespace, resourceName, { + apiVersion = "rbac.authorization.k8s.io/v1", + kind = "Role", + metadata = { + name = resourceName, + namespace = pgNamespace, + annotations = { + ["console.nais.io/last-modified-at"] = NotNull(), + ["console.nais.io/last-modified-by"] = user:email(), + }, + labels = { + ["app.kubernetes.io/managed-by"] = "console", + ["euthanaisa.nais.io/kill-after"] = NotNull(), + ["nais.io/managed-by"] = "console", + ["postgres.data.nais.io/name"] = "foobar", + }, + }, + rules = { + { + apiGroups = { + "", + }, + resourceNames = { + "foobar-0", + "foobar-1", + "foobar-2", + }, + resources = { + "pods", + }, + verbs = { + "get", + "list", + "watch", + }, + }, + { + apiGroups = { + "", + }, + resourceNames = { + "foobar-0", + "foobar-1", + "foobar-2", + }, + resources = { + "pods/portforward", + }, + verbs = { + "get", + "list", + "watch", + "create", + }, + }, + }, + }) +end) + +Test.k8s("Validate RoleBinding resource", function(t) + local resourceName = "pg-grant-93a898ea" + local pgNamespace = string.format("pg-%s", mainTeam:slug()) + + t.check("rbac.authorization.k8s.io/v1", "rolebindings", "dev", pgNamespace, resourceName, { + apiVersion = "rbac.authorization.k8s.io/v1", + kind = "RoleBinding", + metadata = { + name = resourceName, + namespace = pgNamespace, + annotations = { + ["console.nais.io/last-modified-at"] = NotNull(), + ["console.nais.io/last-modified-by"] = user:email(), + }, + labels = { + ["app.kubernetes.io/managed-by"] = "console", + ["euthanaisa.nais.io/kill-after"] = NotNull(), + ["nais.io/managed-by"] = "console", + ["postgres.data.nais.io/name"] = "foobar", + }, + }, + roleRef = { + apiGroup = "rbac.authorization.k8s.io", + kind = "Role", + name = resourceName, + }, + subjects = { + { + kind = "User", + name = "some@email.com", + }, + }, + }) +end) + +Test.gql("Check acitivity log entry", function(t) t.addHeader("x-user-email", user:email()) - t.query [[mutation { grantPostgresAccess(input: { - clusterName: "legacy", teamSlug: "someteamname", environmentName: "dev", - grantee: "someone@example.com", duration: "1h" - }) { error } }]] - t.check { errors = { { message = Contains("Cannot query field \"grantPostgresAccess\""), locations = NotNull(), extensions = { code = "GRAPHQL_VALIDATION_FAILED" } } }, data = Null } + t.query([[ + { + team(slug:"someteamname") { + activityLog { + nodes { + message + ... on PostgresGrantAccessActivityLogEntry { + data { + grantee + until + } + } + } + } + } + } + ]]) + + t.check({ + data = { + team = { + activityLog = { + nodes = { + { + message = Contains("Granted access to some@email.com"), + data = { + grantee = "some@email.com", + ["until"] = NotNull(), + }, + }, + }, + }, + }, + }, + }) end) diff --git a/internal/graph/gengql/postgres.generated.go b/internal/graph/gengql/postgres.generated.go index 614f6aa3b..7b3d56582 100644 --- a/internal/graph/gengql/postgres.generated.go +++ b/internal/graph/gengql/postgres.generated.go @@ -30,7 +30,7 @@ type PostgresAccessResolver interface { TeamEnvironment(ctx context.Context, obj *postgres.PostgresAccess) (*team.TeamEnvironment, error) PostgresInstance(ctx context.Context, obj *postgres.PostgresAccess) (*postgres.PostgresInstance, error) - Connection(ctx context.Context, obj *postgres.PostgresAccess) (*postgres.PostgresAccessConnection, error) + Connection(ctx context.Context, obj *postgres.PostgresAccess) (*postgres.PostgresAccessConnectionDetails, error) } type PostgresInstanceResolver interface { Team(ctx context.Context, obj *postgres.PostgresInstance) (*team.Team, error) @@ -161,6 +161,29 @@ func (ec *executionContext) fieldContext_DeletePostgresPayload_postgresDeleted(_ return graphql.NewScalarFieldContext("DeletePostgresPayload", field, false, false, errors.New("field of type Boolean does not have child fields")) } +func (ec *executionContext) _GrantPostgresAccessPayload_error(ctx context.Context, field graphql.CollectedField, obj *postgres.GrantPostgresAccessPayload) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_GrantPostgresAccessPayload_error(ctx, field) + }, + func(ctx context.Context) (any, error) { + return obj.Error, nil + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *string) graphql.Marshaler { + return ec.marshalOString2ᚖstring(ctx, selections, v) + }, + true, + false, + ) +} +func (ec *executionContext) fieldContext_GrantPostgresAccessPayload_error(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("GrantPostgresAccessPayload", field, false, false, errors.New("field of type String does not have child fields")) +} + func (ec *executionContext) _Postgres_id(ctx context.Context, field graphql.CollectedField, obj *postgres.Postgres) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -609,11 +632,11 @@ func (ec *executionContext) _PostgresAccess_connection(ctx context.Context, fiel return ec.Resolvers.PostgresAccess().Connection(ctx, obj) }, nil, - func(ctx context.Context, selections ast.SelectionSet, v *postgres.PostgresAccessConnection) graphql.Marshaler { - return ec.marshalNPostgresAccessConnection2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccessConnection(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *postgres.PostgresAccessConnectionDetails) graphql.Marshaler { + return ec.marshalOPostgresAccessConnectionDetails2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccessConnectionDetails(ctx, selections, v) }, true, - true, + false, ) } func (ec *executionContext) fieldContext_PostgresAccess_connection(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { @@ -623,19 +646,19 @@ func (ec *executionContext) fieldContext_PostgresAccess_connection(_ context.Con IsMethod: true, IsResolver: true, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_PostgresAccessConnection(ctx, field) + return ec.childFields_PostgresAccessConnectionDetails(ctx, field) }, } return fc, nil } -func (ec *executionContext) _PostgresAccessConnection_username(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccessConnection) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresAccessConnectionDetails_username(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccessConnectionDetails) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresAccessConnection_username(ctx, field) + return ec.fieldContext_PostgresAccessConnectionDetails_username(ctx, field) }, func(ctx context.Context) (any, error) { return obj.Username, nil @@ -648,17 +671,17 @@ func (ec *executionContext) _PostgresAccessConnection_username(ctx context.Conte true, ) } -func (ec *executionContext) fieldContext_PostgresAccessConnection_username(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresAccessConnection", field, false, false, errors.New("field of type String does not have child fields")) +func (ec *executionContext) fieldContext_PostgresAccessConnectionDetails_username(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresAccessConnectionDetails", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresAccessConnection_password(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccessConnection) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresAccessConnectionDetails_password(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccessConnectionDetails) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresAccessConnection_password(ctx, field) + return ec.fieldContext_PostgresAccessConnectionDetails_password(ctx, field) }, func(ctx context.Context) (any, error) { return obj.Password, nil @@ -671,17 +694,17 @@ func (ec *executionContext) _PostgresAccessConnection_password(ctx context.Conte true, ) } -func (ec *executionContext) fieldContext_PostgresAccessConnection_password(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresAccessConnection", field, false, false, errors.New("field of type String does not have child fields")) +func (ec *executionContext) fieldContext_PostgresAccessConnectionDetails_password(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresAccessConnectionDetails", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresAccessConnection_caCertificate(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccessConnection) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresAccessConnectionDetails_caCertificate(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccessConnectionDetails) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresAccessConnection_caCertificate(ctx, field) + return ec.fieldContext_PostgresAccessConnectionDetails_caCertificate(ctx, field) }, func(ctx context.Context) (any, error) { return obj.CACertificate, nil @@ -694,17 +717,17 @@ func (ec *executionContext) _PostgresAccessConnection_caCertificate(ctx context. true, ) } -func (ec *executionContext) fieldContext_PostgresAccessConnection_caCertificate(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresAccessConnection", field, false, false, errors.New("field of type String does not have child fields")) +func (ec *executionContext) fieldContext_PostgresAccessConnectionDetails_caCertificate(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresAccessConnectionDetails", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresAccessConnection_serverName(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccessConnection) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresAccessConnectionDetails_serverName(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccessConnectionDetails) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresAccessConnection_serverName(ctx, field) + return ec.fieldContext_PostgresAccessConnectionDetails_serverName(ctx, field) }, func(ctx context.Context) (any, error) { return obj.ServerName, nil @@ -717,17 +740,17 @@ func (ec *executionContext) _PostgresAccessConnection_serverName(ctx context.Con true, ) } -func (ec *executionContext) fieldContext_PostgresAccessConnection_serverName(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresAccessConnection", field, false, false, errors.New("field of type String does not have child fields")) +func (ec *executionContext) fieldContext_PostgresAccessConnectionDetails_serverName(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresAccessConnectionDetails", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresAccessConnection_relayEndpoint(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccessConnection) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresAccessConnectionDetails_relayEndpoint(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccessConnectionDetails) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresAccessConnection_relayEndpoint(ctx, field) + return ec.fieldContext_PostgresAccessConnectionDetails_relayEndpoint(ctx, field) }, func(ctx context.Context) (any, error) { return obj.RelayEndpoint, nil @@ -740,17 +763,17 @@ func (ec *executionContext) _PostgresAccessConnection_relayEndpoint(ctx context. true, ) } -func (ec *executionContext) fieldContext_PostgresAccessConnection_relayEndpoint(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresAccessConnection", field, false, false, errors.New("field of type String does not have child fields")) +func (ec *executionContext) fieldContext_PostgresAccessConnectionDetails_relayEndpoint(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresAccessConnectionDetails", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresAccessConnection_relayAccess(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccessConnection) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresAccessConnectionDetails_relayAccess(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccessConnectionDetails) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresAccessConnection_relayAccess(ctx, field) + return ec.fieldContext_PostgresAccessConnectionDetails_relayAccess(ctx, field) }, func(ctx context.Context) (any, error) { return obj.RelayAccess, nil @@ -763,17 +786,17 @@ func (ec *executionContext) _PostgresAccessConnection_relayAccess(ctx context.Co true, ) } -func (ec *executionContext) fieldContext_PostgresAccessConnection_relayAccess(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresAccessConnection", field, false, false, errors.New("field of type String does not have child fields")) +func (ec *executionContext) fieldContext_PostgresAccessConnectionDetails_relayAccess(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresAccessConnectionDetails", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresAccessConnection_relayToken(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccessConnection) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresAccessConnectionDetails_relayToken(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccessConnectionDetails) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresAccessConnection_relayToken(ctx, field) + return ec.fieldContext_PostgresAccessConnectionDetails_relayToken(ctx, field) }, func(ctx context.Context) (any, error) { return obj.RelayToken, nil @@ -786,8 +809,8 @@ func (ec *executionContext) _PostgresAccessConnection_relayToken(ctx context.Con true, ) } -func (ec *executionContext) fieldContext_PostgresAccessConnection_relayToken(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresAccessConnection", field, false, false, errors.New("field of type String does not have child fields")) +func (ec *executionContext) fieldContext_PostgresAccessConnectionDetails_relayToken(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresAccessConnectionDetails", field, false, false, errors.New("field of type String does not have child fields")) } func (ec *executionContext) _PostgresDeletedActivityLogEntry_id(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresDeletedActivityLogEntry) (ret graphql.Marshaler) { @@ -2627,6 +2650,64 @@ func (ec *executionContext) unmarshalInputDeletePostgresInput(ctx context.Contex return it, nil } +func (ec *executionContext) unmarshalInputGrantPostgresAccessInput(ctx context.Context, obj any) (postgres.GrantPostgresAccessInput, error) { + var it postgres.GrantPostgresAccessInput + if obj == nil { + return it, nil + } + + asMap := map[string]any{} + for k, v := range obj.(map[string]any) { + asMap[k] = v + } + + fieldsInOrder := [...]string{"clusterName", "teamSlug", "environmentName", "grantee", "duration"} + for _, k := range fieldsInOrder { + v, ok := asMap[k] + if !ok { + continue + } + switch k { + case "clusterName": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("clusterName")) + data, err := ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + it.ClusterName = data + case "teamSlug": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("teamSlug")) + data, err := ec.unmarshalNSlug2githubᚗcomᚋnaisᚋapiᚋinternalᚋslugᚐSlug(ctx, v) + if err != nil { + return it, err + } + it.TeamSlug = data + case "environmentName": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("environmentName")) + data, err := ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + it.EnvironmentName = data + case "grantee": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("grantee")) + data, err := ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + it.Grantee = data + case "duration": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("duration")) + data, err := ec.unmarshalNString2string(ctx, v) + if err != nil { + return it, err + } + it.Duration = data + } + } + return it, nil +} + func (ec *executionContext) unmarshalInputPostgresInstanceFilter(ctx context.Context, obj any) (postgres.PostgresInstanceFilter, error) { var it postgres.PostgresInstanceFilter if obj == nil { @@ -2803,6 +2884,42 @@ func (ec *executionContext) _DeletePostgresPayload(ctx context.Context, sel ast. return out } +var grantPostgresAccessPayloadImplementors = []string{"GrantPostgresAccessPayload"} + +func (ec *executionContext) _GrantPostgresAccessPayload(ctx context.Context, sel ast.SelectionSet, obj *postgres.GrantPostgresAccessPayload) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, grantPostgresAccessPayloadImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("GrantPostgresAccessPayload") + case "error": + out.Values[i] = ec._GrantPostgresAccessPayload_error(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.Deferred, int32(min(len(deferred), math.MaxInt32))) + + for label, dfs := range deferred { + ec.ProcessDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + var postgresImplementors = []string{"Postgres", "Node"} func (ec *executionContext) _Postgres(ctx context.Context, sel ast.SelectionSet, obj *postgres.Postgres) graphql.Marshaler { @@ -3020,16 +3137,13 @@ func (ec *executionContext) _PostgresAccess(ctx context.Context, sel ast.Selecti case "connection": field := field - innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { + innerFunc := func(ctx context.Context, _ *graphql.FieldSet) (res graphql.Marshaler) { defer func() { if r := recover(); r != nil { ec.Error(ctx, ec.Recover(ctx, r)) } }() res = ec._PostgresAccess_connection(ctx, field, obj) - if res == graphql.Null { - atomic.AddUint32(&fs.Invalids, 1) - } return res } @@ -3076,49 +3190,49 @@ func (ec *executionContext) _PostgresAccess(ctx context.Context, sel ast.Selecti return out } -var postgresAccessConnectionImplementors = []string{"PostgresAccessConnection"} +var postgresAccessConnectionDetailsImplementors = []string{"PostgresAccessConnectionDetails"} -func (ec *executionContext) _PostgresAccessConnection(ctx context.Context, sel ast.SelectionSet, obj *postgres.PostgresAccessConnection) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, postgresAccessConnectionImplementors) +func (ec *executionContext) _PostgresAccessConnectionDetails(ctx context.Context, sel ast.SelectionSet, obj *postgres.PostgresAccessConnectionDetails) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, postgresAccessConnectionDetailsImplementors) out := graphql.NewFieldSet(fields) deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": - out.Values[i] = graphql.MarshalString("PostgresAccessConnection") + out.Values[i] = graphql.MarshalString("PostgresAccessConnectionDetails") case "username": - out.Values[i] = ec._PostgresAccessConnection_username(ctx, field, obj) + out.Values[i] = ec._PostgresAccessConnectionDetails_username(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } case "password": - out.Values[i] = ec._PostgresAccessConnection_password(ctx, field, obj) + out.Values[i] = ec._PostgresAccessConnectionDetails_password(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } case "caCertificate": - out.Values[i] = ec._PostgresAccessConnection_caCertificate(ctx, field, obj) + out.Values[i] = ec._PostgresAccessConnectionDetails_caCertificate(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } case "serverName": - out.Values[i] = ec._PostgresAccessConnection_serverName(ctx, field, obj) + out.Values[i] = ec._PostgresAccessConnectionDetails_serverName(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } case "relayEndpoint": - out.Values[i] = ec._PostgresAccessConnection_relayEndpoint(ctx, field, obj) + out.Values[i] = ec._PostgresAccessConnectionDetails_relayEndpoint(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } case "relayAccess": - out.Values[i] = ec._PostgresAccessConnection_relayAccess(ctx, field, obj) + out.Values[i] = ec._PostgresAccessConnectionDetails_relayAccess(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } case "relayToken": - out.Values[i] = ec._PostgresAccessConnection_relayToken(ctx, field, obj) + out.Values[i] = ec._PostgresAccessConnectionDetails_relayToken(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } @@ -4173,46 +4287,51 @@ func (ec *executionContext) marshalNDeletePostgresPayload2ᚖgithubᚗcomᚋnais return ec._DeletePostgresPayload(ctx, sel, v) } -func (ec *executionContext) marshalNPostgres2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgres(ctx context.Context, sel ast.SelectionSet, v postgres.Postgres) graphql.Marshaler { - return ec._Postgres(ctx, sel, &v) +func (ec *executionContext) unmarshalNGrantPostgresAccessInput2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐGrantPostgresAccessInput(ctx context.Context, v any) (postgres.GrantPostgresAccessInput, error) { + res, err := ec.unmarshalInputGrantPostgresAccessInput(ctx, v) + return res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) marshalNPostgres2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgres(ctx context.Context, sel ast.SelectionSet, v *postgres.Postgres) graphql.Marshaler { +func (ec *executionContext) marshalNGrantPostgresAccessPayload2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐGrantPostgresAccessPayload(ctx context.Context, sel ast.SelectionSet, v postgres.GrantPostgresAccessPayload) graphql.Marshaler { + return ec._GrantPostgresAccessPayload(ctx, sel, &v) +} + +func (ec *executionContext) marshalNGrantPostgresAccessPayload2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐGrantPostgresAccessPayload(ctx context.Context, sel ast.SelectionSet, v *postgres.GrantPostgresAccessPayload) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { graphql.AddErrorf(ctx, "the requested element is null which the schema does not allow") } return graphql.Null } - return ec._Postgres(ctx, sel, v) + return ec._GrantPostgresAccessPayload(ctx, sel, v) } -func (ec *executionContext) marshalNPostgresAccess2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccess(ctx context.Context, sel ast.SelectionSet, v postgres.PostgresAccess) graphql.Marshaler { - return ec._PostgresAccess(ctx, sel, &v) +func (ec *executionContext) marshalNPostgres2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgres(ctx context.Context, sel ast.SelectionSet, v postgres.Postgres) graphql.Marshaler { + return ec._Postgres(ctx, sel, &v) } -func (ec *executionContext) marshalNPostgresAccess2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccess(ctx context.Context, sel ast.SelectionSet, v *postgres.PostgresAccess) graphql.Marshaler { +func (ec *executionContext) marshalNPostgres2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgres(ctx context.Context, sel ast.SelectionSet, v *postgres.Postgres) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { graphql.AddErrorf(ctx, "the requested element is null which the schema does not allow") } return graphql.Null } - return ec._PostgresAccess(ctx, sel, v) + return ec._Postgres(ctx, sel, v) } -func (ec *executionContext) marshalNPostgresAccessConnection2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccessConnection(ctx context.Context, sel ast.SelectionSet, v postgres.PostgresAccessConnection) graphql.Marshaler { - return ec._PostgresAccessConnection(ctx, sel, &v) +func (ec *executionContext) marshalNPostgresAccess2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccess(ctx context.Context, sel ast.SelectionSet, v postgres.PostgresAccess) graphql.Marshaler { + return ec._PostgresAccess(ctx, sel, &v) } -func (ec *executionContext) marshalNPostgresAccessConnection2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccessConnection(ctx context.Context, sel ast.SelectionSet, v *postgres.PostgresAccessConnection) graphql.Marshaler { +func (ec *executionContext) marshalNPostgresAccess2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccess(ctx context.Context, sel ast.SelectionSet, v *postgres.PostgresAccess) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { graphql.AddErrorf(ctx, "the requested element is null which the schema does not allow") } return graphql.Null } - return ec._PostgresAccessConnection(ctx, sel, v) + return ec._PostgresAccess(ctx, sel, v) } func (ec *executionContext) unmarshalNPostgresAccessLevel2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccessLevel(ctx context.Context, v any) (postgres.PostgresAccessLevel, error) { @@ -4377,6 +4496,13 @@ func (ec *executionContext) marshalNTeamInventoryCountPostgresInstances2ᚖgithu return ec._TeamInventoryCountPostgresInstances(ctx, sel, v) } +func (ec *executionContext) marshalOPostgresAccessConnectionDetails2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccessConnectionDetails(ctx context.Context, sel ast.SelectionSet, v *postgres.PostgresAccessConnectionDetails) graphql.Marshaler { + if v == nil { + return graphql.Null + } + return ec._PostgresAccessConnectionDetails(ctx, sel, v) +} + func (ec *executionContext) unmarshalOPostgresAccessLevel2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccessLevel(ctx context.Context, v any) (*postgres.PostgresAccessLevel, error) { if v == nil { return nil, nil diff --git a/internal/graph/gengql/root_.generated.go b/internal/graph/gengql/root_.generated.go index 14175ca56..6c2ee5bd3 100644 --- a/internal/graph/gengql/root_.generated.go +++ b/internal/graph/gengql/root_.generated.go @@ -1062,6 +1062,10 @@ type ComplexityRoot struct { WorkflowSha func(childComplexity int) int } + GrantPostgresAccessPayload struct { + Error func(childComplexity int) int + } + IDPortenAuthIntegration struct { Name func(childComplexity int) int } @@ -1644,6 +1648,7 @@ type ComplexityRoot struct { DeleteValkey func(childComplexity int, input valkey.DeleteValkeyInput) int DisableReconciler func(childComplexity int, input reconciler.DisableReconcilerInput) int EnableReconciler func(childComplexity int, input reconciler.EnableReconcilerInput) int + GrantPostgresAccess func(childComplexity int, input postgres.GrantPostgresAccessInput) int RemoveConfigValue func(childComplexity int, input config.RemoveConfigValueInput) int RemoveRepositoryFromTeam func(childComplexity int, input repository.RemoveRepositoryFromTeamInput) int RemoveSecretValue func(childComplexity int, input secret.RemoveSecretValueInput) int @@ -1912,7 +1917,7 @@ type ComplexityRoot struct { TeamEnvironment func(childComplexity int) int } - PostgresAccessConnection struct { + PostgresAccessConnectionDetails struct { CACertificate func(childComplexity int) int Password func(childComplexity int) int RelayAccess func(childComplexity int) int @@ -7590,6 +7595,13 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.GitHubActorClaims.WorkflowSha(childComplexity), true + case "GrantPostgresAccessPayload.error": + if e.ComplexityRoot.GrantPostgresAccessPayload.Error == nil { + break + } + + return e.ComplexityRoot.GrantPostgresAccessPayload.Error(childComplexity), true + case "IDPortenAuthIntegration.name": if e.ComplexityRoot.IDPortenAuthIntegration.Name == nil { break @@ -10347,6 +10359,18 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.Mutation.EnableReconciler(childComplexity, args["input"].(reconciler.EnableReconcilerInput)), true + case "Mutation.grantPostgresAccess": + if e.ComplexityRoot.Mutation.GrantPostgresAccess == nil { + break + } + + args, err := ec.field_Mutation_grantPostgresAccess_args(ctx, rawArgs) + if err != nil { + return 0, false + } + + return e.ComplexityRoot.Mutation.GrantPostgresAccess(childComplexity, args["input"].(postgres.GrantPostgresAccessInput)), true + case "Mutation.removeConfigValue": if e.ComplexityRoot.Mutation.RemoveConfigValue == nil { break @@ -11744,54 +11768,54 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.PostgresAccess.TeamEnvironment(childComplexity), true - case "PostgresAccessConnection.caCertificate": - if e.ComplexityRoot.PostgresAccessConnection.CACertificate == nil { + case "PostgresAccessConnectionDetails.caCertificate": + if e.ComplexityRoot.PostgresAccessConnectionDetails.CACertificate == nil { break } - return e.ComplexityRoot.PostgresAccessConnection.CACertificate(childComplexity), true + return e.ComplexityRoot.PostgresAccessConnectionDetails.CACertificate(childComplexity), true - case "PostgresAccessConnection.password": - if e.ComplexityRoot.PostgresAccessConnection.Password == nil { + case "PostgresAccessConnectionDetails.password": + if e.ComplexityRoot.PostgresAccessConnectionDetails.Password == nil { break } - return e.ComplexityRoot.PostgresAccessConnection.Password(childComplexity), true + return e.ComplexityRoot.PostgresAccessConnectionDetails.Password(childComplexity), true - case "PostgresAccessConnection.relayAccess": - if e.ComplexityRoot.PostgresAccessConnection.RelayAccess == nil { + case "PostgresAccessConnectionDetails.relayAccess": + if e.ComplexityRoot.PostgresAccessConnectionDetails.RelayAccess == nil { break } - return e.ComplexityRoot.PostgresAccessConnection.RelayAccess(childComplexity), true + return e.ComplexityRoot.PostgresAccessConnectionDetails.RelayAccess(childComplexity), true - case "PostgresAccessConnection.relayEndpoint": - if e.ComplexityRoot.PostgresAccessConnection.RelayEndpoint == nil { + case "PostgresAccessConnectionDetails.relayEndpoint": + if e.ComplexityRoot.PostgresAccessConnectionDetails.RelayEndpoint == nil { break } - return e.ComplexityRoot.PostgresAccessConnection.RelayEndpoint(childComplexity), true + return e.ComplexityRoot.PostgresAccessConnectionDetails.RelayEndpoint(childComplexity), true - case "PostgresAccessConnection.relayToken": - if e.ComplexityRoot.PostgresAccessConnection.RelayToken == nil { + case "PostgresAccessConnectionDetails.relayToken": + if e.ComplexityRoot.PostgresAccessConnectionDetails.RelayToken == nil { break } - return e.ComplexityRoot.PostgresAccessConnection.RelayToken(childComplexity), true + return e.ComplexityRoot.PostgresAccessConnectionDetails.RelayToken(childComplexity), true - case "PostgresAccessConnection.serverName": - if e.ComplexityRoot.PostgresAccessConnection.ServerName == nil { + case "PostgresAccessConnectionDetails.serverName": + if e.ComplexityRoot.PostgresAccessConnectionDetails.ServerName == nil { break } - return e.ComplexityRoot.PostgresAccessConnection.ServerName(childComplexity), true + return e.ComplexityRoot.PostgresAccessConnectionDetails.ServerName(childComplexity), true - case "PostgresAccessConnection.username": - if e.ComplexityRoot.PostgresAccessConnection.Username == nil { + case "PostgresAccessConnectionDetails.username": + if e.ComplexityRoot.PostgresAccessConnectionDetails.Username == nil { break } - return e.ComplexityRoot.PostgresAccessConnection.Username(childComplexity), true + return e.ComplexityRoot.PostgresAccessConnectionDetails.Username(childComplexity), true case "PostgresDeletedActivityLogEntry.actor": if e.ComplexityRoot.PostgresDeletedActivityLogEntry.Actor == nil { @@ -20891,6 +20915,7 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { ec.unmarshalInputEnableReconcilerInput, ec.unmarshalInputEnvironmentOrder, ec.unmarshalInputEnvironmentWorkloadOrder, + ec.unmarshalInputGrantPostgresAccessInput, ec.unmarshalInputImageVulnerabilityFilter, ec.unmarshalInputImageVulnerabilityOrder, ec.unmarshalInputIssueFilter, @@ -27735,6 +27760,8 @@ extend enum ActivityLogActivityType { } extend type Mutation { + "Grant temporary access to a Postgres cluster." + grantPostgresAccess(input: GrantPostgresAccessInput!): GrantPostgresAccessPayload! """ EXPERIMENTAL: DO NOT USE Create time-limited personal access to a NAIS Postgres instance through the brokered PostgresAccess and relay flow. @@ -27745,6 +27772,19 @@ extend type Mutation { deletePostgres(input: DeletePostgresInput!): DeletePostgresPayload! } +type GrantPostgresAccessPayload { + error: String +} + +input GrantPostgresAccessInput { + clusterName: String! + teamSlug: Slug! + environmentName: String! + grantee: String! + "Duration of the access grant (maximum 4 hours)." + duration: String! +} + "Result of creating a personal Postgres access." type CreatePostgresAccessPayload { "Name of the newly created PostgresAccess resource." @@ -27828,7 +27868,7 @@ type PostgresAccess implements Node { EXPERIMENTAL: DO NOT USE Get connection materials for this ready access. Only its owner can read them. """ - connection: PostgresAccessConnection! + connection: PostgresAccessConnectionDetails } "High-level reconciliation state of a personal Postgres access." @@ -27844,7 +27884,7 @@ enum PostgresAccessState { } "Sensitive connection materials for a ready personal Postgres access." -type PostgresAccessConnection { +type PostgresAccessConnectionDetails { "Database username for the caller's personal role." username: String! "Short-lived password for the caller's database role." @@ -36570,6 +36610,14 @@ func (ec *executionContext) childFields_GitHubActorClaims(ctx context.Context, f return nil, fmt.Errorf("no field named %q was found under type GitHubActorClaims", field.Name) } +func (ec *executionContext) childFields_GrantPostgresAccessPayload(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "error": + return ec.fieldContext_GrantPostgresAccessPayload_error(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type GrantPostgresAccessPayload", field.Name) +} + func (ec *executionContext) childFields_ImageVulnerability(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { switch field.Name { case "id": @@ -37716,24 +37764,24 @@ func (ec *executionContext) childFields_PostgresAccess(ctx context.Context, fiel return nil, fmt.Errorf("no field named %q was found under type PostgresAccess", field.Name) } -func (ec *executionContext) childFields_PostgresAccessConnection(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { +func (ec *executionContext) childFields_PostgresAccessConnectionDetails(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { switch field.Name { case "username": - return ec.fieldContext_PostgresAccessConnection_username(ctx, field) + return ec.fieldContext_PostgresAccessConnectionDetails_username(ctx, field) case "password": - return ec.fieldContext_PostgresAccessConnection_password(ctx, field) + return ec.fieldContext_PostgresAccessConnectionDetails_password(ctx, field) case "caCertificate": - return ec.fieldContext_PostgresAccessConnection_caCertificate(ctx, field) + return ec.fieldContext_PostgresAccessConnectionDetails_caCertificate(ctx, field) case "serverName": - return ec.fieldContext_PostgresAccessConnection_serverName(ctx, field) + return ec.fieldContext_PostgresAccessConnectionDetails_serverName(ctx, field) case "relayEndpoint": - return ec.fieldContext_PostgresAccessConnection_relayEndpoint(ctx, field) + return ec.fieldContext_PostgresAccessConnectionDetails_relayEndpoint(ctx, field) case "relayAccess": - return ec.fieldContext_PostgresAccessConnection_relayAccess(ctx, field) + return ec.fieldContext_PostgresAccessConnectionDetails_relayAccess(ctx, field) case "relayToken": - return ec.fieldContext_PostgresAccessConnection_relayToken(ctx, field) + return ec.fieldContext_PostgresAccessConnectionDetails_relayToken(ctx, field) } - return nil, fmt.Errorf("no field named %q was found under type PostgresAccessConnection", field.Name) + return nil, fmt.Errorf("no field named %q was found under type PostgresAccessConnectionDetails", field.Name) } func (ec *executionContext) childFields_PostgresGrantAccessActivityLogEntryData(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { diff --git a/internal/graph/gengql/schema.generated.go b/internal/graph/gengql/schema.generated.go index 6241db4c8..0a4737879 100644 --- a/internal/graph/gengql/schema.generated.go +++ b/internal/graph/gengql/schema.generated.go @@ -84,6 +84,7 @@ type MutationResolver interface { UpdateOpenSearch(ctx context.Context, input opensearch.UpdateOpenSearchInput) (*opensearch.UpdateOpenSearchPayload, error) DeleteOpenSearch(ctx context.Context, input opensearch.DeleteOpenSearchInput) (*opensearch.DeleteOpenSearchPayload, error) CreateOpenSearchCredentials(ctx context.Context, input opensearch.CreateOpenSearchCredentialsInput) (*opensearch.CreateOpenSearchCredentialsPayload, error) + GrantPostgresAccess(ctx context.Context, input postgres.GrantPostgresAccessInput) (*postgres.GrantPostgresAccessPayload, error) CreatePostgresAccess(ctx context.Context, input postgres.CreatePostgresAccessInput) (*postgres.CreatePostgresAccessPayload, error) DeletePostgres(ctx context.Context, input postgres.DeletePostgresInput) (*postgres.DeletePostgresPayload, error) EnableReconciler(ctx context.Context, input reconciler.EnableReconcilerInput) (*reconciler.Reconciler, error) @@ -686,6 +687,20 @@ func (ec *executionContext) field_Mutation_enableReconciler_args(ctx context.Con return args, nil } +func (ec *executionContext) field_Mutation_grantPostgresAccess_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { + var err error + args := map[string]any{} + arg0, err := graphql.ProcessArgField(ctx, rawArgs, "input", + func(ctx context.Context, v any) (postgres.GrantPostgresAccessInput, error) { + return ec.unmarshalNGrantPostgresAccessInput2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐGrantPostgresAccessInput(ctx, v) + }) + if err != nil { + return nil, err + } + args["input"] = arg0 + return args, nil +} + func (ec *executionContext) field_Mutation_removeConfigValue_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} @@ -2636,6 +2651,50 @@ func (ec *executionContext) fieldContext_Mutation_createOpenSearchCredentials(ct return fc, nil } +func (ec *executionContext) _Mutation_grantPostgresAccess(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { + return graphql.ResolveField( + ctx, + ec.OperationContext, + field, + func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.fieldContext_Mutation_grantPostgresAccess(ctx, field) + }, + func(ctx context.Context) (any, error) { + fc := graphql.GetFieldContext(ctx) + return ec.Resolvers.Mutation().GrantPostgresAccess(ctx, fc.Args["input"].(postgres.GrantPostgresAccessInput)) + }, + nil, + func(ctx context.Context, selections ast.SelectionSet, v *postgres.GrantPostgresAccessPayload) graphql.Marshaler { + return ec.marshalNGrantPostgresAccessPayload2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐGrantPostgresAccessPayload(ctx, selections, v) + }, + true, + true, + ) +} +func (ec *executionContext) fieldContext_Mutation_grantPostgresAccess(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "Mutation", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GrantPostgresAccessPayload(ctx, field) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_Mutation_grantPostgresAccess_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil +} + func (ec *executionContext) _Mutation_createPostgresAccess(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, @@ -7262,6 +7321,13 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) if out.Values[i] == graphql.Null { out.Invalids++ } + case "grantPostgresAccess": + out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { + return ec._Mutation_grantPostgresAccess(ctx, field) + }) + if out.Values[i] == graphql.Null { + out.Invalids++ + } case "createPostgresAccess": out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { return ec._Mutation_createPostgresAccess(ctx, field) diff --git a/internal/graph/postgres.resolvers.go b/internal/graph/postgres.resolvers.go index f45565e2a..393a8535c 100644 --- a/internal/graph/postgres.resolvers.go +++ b/internal/graph/postgres.resolvers.go @@ -35,6 +35,16 @@ func (r *jobResolver) PostgresInstances(ctx context.Context, obj *job.Job, order return pagination.NewFacetableConnection(pagination.NewConnectionWithoutPagination(instances), instances, (*postgres.PostgresInstanceFilter)(nil)), nil } +func (r *mutationResolver) GrantPostgresAccess(ctx context.Context, input postgres.GrantPostgresAccessInput) (*postgres.GrantPostgresAccessPayload, error) { + if err := authz.CanGrantPostgresAccess(ctx, input.TeamSlug); err != nil { + return nil, err + } + if err := postgres.GrantZalandoPostgresAccess(ctx, input); err != nil { + return nil, err + } + return &postgres.GrantPostgresAccessPayload{Error: new(string)}, nil +} + func (r *mutationResolver) CreatePostgresAccess(ctx context.Context, input postgres.CreatePostgresAccessInput) (*postgres.CreatePostgresAccessPayload, error) { if err := authz.CanGrantPostgresAccess(ctx, input.TeamSlug); err != nil { return nil, err @@ -62,7 +72,7 @@ func (r *postgresAccessResolver) PostgresInstance(ctx context.Context, obj *post return postgres.GetPostgresInstance(ctx, obj.TeamSlug, obj.EnvironmentName, obj.PostgresInstanceName) } -func (r *postgresAccessResolver) Connection(ctx context.Context, obj *postgres.PostgresAccess) (*postgres.PostgresAccessConnection, error) { +func (r *postgresAccessResolver) Connection(ctx context.Context, obj *postgres.PostgresAccess) (*postgres.PostgresAccessConnectionDetails, error) { return postgres.GetPostgresAccessConnection(ctx, postgres.PostgresAccessConnectionInput{ Name: obj.Name, TeamSlug: obj.TeamSlug, EnvironmentName: obj.EnvironmentName, }) diff --git a/internal/graph/schema/postgres.graphqls b/internal/graph/schema/postgres.graphqls index 3b4bcd179..5dca4920f 100644 --- a/internal/graph/schema/postgres.graphqls +++ b/internal/graph/schema/postgres.graphqls @@ -355,6 +355,8 @@ extend enum ActivityLogActivityType { } extend type Mutation { + "Grant temporary access to a Postgres cluster." + grantPostgresAccess(input: GrantPostgresAccessInput!): GrantPostgresAccessPayload! """ EXPERIMENTAL: DO NOT USE Create time-limited personal access to a NAIS Postgres instance through the brokered PostgresAccess and relay flow. @@ -365,6 +367,19 @@ extend type Mutation { deletePostgres(input: DeletePostgresInput!): DeletePostgresPayload! } +type GrantPostgresAccessPayload { + error: String +} + +input GrantPostgresAccessInput { + clusterName: String! + teamSlug: Slug! + environmentName: String! + grantee: String! + "Duration of the access grant (maximum 4 hours)." + duration: String! +} + "Result of creating a personal Postgres access." type CreatePostgresAccessPayload { "Name of the newly created PostgresAccess resource." @@ -448,7 +463,7 @@ type PostgresAccess implements Node { EXPERIMENTAL: DO NOT USE Get connection materials for this ready access. Only its owner can read them. """ - connection: PostgresAccessConnection! + connection: PostgresAccessConnectionDetails } "High-level reconciliation state of a personal Postgres access." @@ -464,7 +479,7 @@ enum PostgresAccessState { } "Sensitive connection materials for a ready personal Postgres access." -type PostgresAccessConnection { +type PostgresAccessConnectionDetails { "Database username for the caller's personal role." username: String! "Short-lived password for the caller's database role." diff --git a/internal/kubernetes/fake/fake.go b/internal/kubernetes/fake/fake.go index 8b1ad8cee..5e7c5831a 100644 --- a/internal/kubernetes/fake/fake.go +++ b/internal/kubernetes/fake/fake.go @@ -216,6 +216,7 @@ func NewDynamicClient(scheme *runtime.Scheme) *dynfake.FakeDynamicClient { unleash_nais_io_v1.GroupVersion.WithResource("unleashes"): "UnleashList", unleash_nais_io_v1.GroupVersion.WithResource("remoteunleashes"): "RemoteUnleashList", mapperatorv1.GroupVersion.WithResource("postgres"): "PostgresList", + {Group: "data.nais.io", Version: "v1", Resource: "postgres"}: "PostgresList", mapperatorv1.GroupVersion.WithResource("postgresinstances"): "PostgresInstanceList", nais_io_v1alpha1.GroupVersion.WithResource("tunnels"): "TunnelList", mapperatorv1.GroupVersion.WithResource("valkeys"): "ValkeyList", diff --git a/internal/kubernetes/scheme.go b/internal/kubernetes/scheme.go index c6c6ce159..f1d2662df 100644 --- a/internal/kubernetes/scheme.go +++ b/internal/kubernetes/scheme.go @@ -57,6 +57,7 @@ func NewScheme() (*runtime.Scheme, error) { }{ {"nais.io", "v1alpha1", "RelayAccess"}, {"postgresql.cnpg.io", "v1", "Cluster"}, + {"data.nais.io", "v1", "Postgres"}, // Legacy port-forward grant validation. } { version := schema.GroupVersion{Group: gv.group, Version: gv.version} scheme.AddKnownTypeWithName(version.WithKind(gv.kind), &unstructured.Unstructured{}) diff --git a/internal/persistence/postgres/connection.go b/internal/persistence/postgres/connection.go index 8a6020b12..946130e61 100644 --- a/internal/persistence/postgres/connection.go +++ b/internal/persistence/postgres/connection.go @@ -21,7 +21,7 @@ import ( // All connection resources are read on demand after the caller has been // authorized as the PostgresAccess owner. No credentials enter the watch cache. -func loadPostgresAccessConnection(ctx context.Context, access *unstructured.Unstructured, input PostgresAccessConnectionInput, connection *PostgresAccessConnection, tokenSecretName string) error { +func loadPostgresAccessConnection(ctx context.Context, access *unstructured.Unstructured, input PostgresAccessConnectionInput, connection *PostgresAccessConnectionDetails, tokenSecretName string) error { instance, _, err := unstructured.NestedString(access.Object, "spec", "postgresInstance") if err != nil || instance == "" || access.GetUID() == "" { return apierror.Errorf("PostgresAccess %q is not ready", access.GetName()) diff --git a/internal/persistence/postgres/models.go b/internal/persistence/postgres/models.go index bd6cbe86b..4438b6be7 100644 --- a/internal/persistence/postgres/models.go +++ b/internal/persistence/postgres/models.go @@ -176,6 +176,61 @@ type DeletePostgresPayload struct { PostgresDeleted *bool `json:"postgresDeleted,omitempty"` } +// GrantPostgresAccessInput retains the temporary port-forward grant for legacy Zalando Postgres clusters. +type GrantPostgresAccessInput struct { + ClusterName string `json:"clusterName"` + TeamSlug slug.Slug `json:"teamSlug"` + EnvironmentName string `json:"environmentName"` + Grantee string `json:"grantee"` + Duration string `json:"duration"` +} + +func (i *GrantPostgresAccessInput) Validate(ctx context.Context) error { + return i.ValidationErrors(ctx).NilIfEmpty() +} + +func (i *GrantPostgresAccessInput) ValidationErrors(ctx context.Context) *validate.ValidationErrors { + verr := validate.New() + i.ClusterName = strings.TrimSpace(i.ClusterName) + i.EnvironmentName = strings.TrimSpace(i.EnvironmentName) + + if i.ClusterName == "" { + verr.Add("clusterName", "ClusterName must not be empty.") + } + if i.EnvironmentName == "" { + verr.Add("environmentName", "Environment name must not be empty.") + } + if i.TeamSlug == "" { + verr.Add("teamSlug", "Team slug must not be empty.") + } + if i.Grantee == "" { + verr.Add("grantee", "Grantee must not be empty.") + } + + duration, err := time.ParseDuration(i.Duration) + if err != nil { + verr.Add("duration", "%s", err) + } else if duration > 4*time.Hour { + verr.Add("duration", "Duration %q is out-of-bounds. Must be less than 4 hours.", i.Duration) + } + + if i.ClusterName == "" || i.EnvironmentName == "" || i.TeamSlug == "" { + return verr + } + if err := getLegacyPostgres(ctx, *i); err != nil { + if k8serrors.IsNotFound(err) { + verr.Add("clusterName", "Could not find postgres cluster named %q", i.ClusterName) + } else { + verr.Add("clusterName", "%s", err) + } + } + return verr +} + +type GrantPostgresAccessPayload struct { + Error *string `json:"error,omitempty"` +} + // CreatePostgresAccessInput requests a new, time-limited personal database access. // The authenticated actor and final expiry are server-controlled. type CreatePostgresAccessInput struct { @@ -540,7 +595,7 @@ func (i *PostgresAccessConnectionInput) ValidationErrors(_ context.Context) *val return verr } -type PostgresAccessConnection struct { +type PostgresAccessConnectionDetails struct { Username string `json:"username"` Password string `json:"password"` CACertificate string `json:"caCertificate"` diff --git a/internal/persistence/postgres/queries.go b/internal/persistence/postgres/queries.go index 577bb2a4b..5db2136bf 100644 --- a/internal/persistence/postgres/queries.go +++ b/internal/persistence/postgres/queries.go @@ -203,7 +203,7 @@ func GetPostgresAccess(ctx context.Context, name string, teamSlug slug.Slug, env return access, nil } -func GetPostgresAccessConnection(ctx context.Context, input PostgresAccessConnectionInput) (*PostgresAccessConnection, error) { +func GetPostgresAccessConnection(ctx context.Context, input PostgresAccessConnectionInput) (*PostgresAccessConnectionDetails, error) { if err := input.Validate(ctx); err != nil { return nil, err } @@ -268,7 +268,7 @@ func getPostgresAccessResource(ctx context.Context, name string, teamSlug slug.S return u, nil } -func postgresAccessConnectionDetails(access *unstructured.Unstructured, now time.Time) (*PostgresAccessConnection, string, error) { +func postgresAccessConnectionDetails(access *unstructured.Unstructured, now time.Time) (*PostgresAccessConnectionDetails, string, error) { expiresAt, _, err := unstructured.NestedString(access.Object, "spec", "expiresAt") if err != nil { return nil, "", fmt.Errorf("reading PostgresAccess %q expiry: %w", access.GetName(), err) @@ -299,7 +299,7 @@ func postgresAccessConnectionDetails(access *unstructured.Unstructured, now time if err != nil || role == "" { return nil, "", apierror.Errorf("PostgresAccess %q is not ready", access.GetName()) } - return &PostgresAccessConnection{}, tokenSecret, nil + return &PostgresAccessConnectionDetails{}, tokenSecret, nil } func postgresAccessIsReady(obj map[string]any) bool { From 82c4d76a676c2f78174b10c76fb46abdb3bf91a1 Mon Sep 17 00:00:00 2001 From: Johnny Fredheim Horvi Date: Tue, 29 Sep 2026 11:02:07 +0200 Subject: [PATCH 13/19] fixes --- .../dev/someteamname/postgres_foobar.yaml | 15 ++ internal/persistence/postgres/grant.go | 133 ++++++++++++++++++ internal/persistence/postgres/grant_test.go | 50 +++++++ 3 files changed, 198 insertions(+) create mode 100644 integration_tests/k8s_resources/grant_zalando_postgres_access/dev/someteamname/postgres_foobar.yaml create mode 100644 internal/persistence/postgres/grant.go create mode 100644 internal/persistence/postgres/grant_test.go diff --git a/integration_tests/k8s_resources/grant_zalando_postgres_access/dev/someteamname/postgres_foobar.yaml b/integration_tests/k8s_resources/grant_zalando_postgres_access/dev/someteamname/postgres_foobar.yaml new file mode 100644 index 000000000..6796d66e0 --- /dev/null +++ b/integration_tests/k8s_resources/grant_zalando_postgres_access/dev/someteamname/postgres_foobar.yaml @@ -0,0 +1,15 @@ +--- +apiVersion: data.nais.io/v1 +kind: Postgres +metadata: + name: foobar + namespace: someteamname +spec: + cluster: + majorVersion: "17" + resources: + cpu: 100m + diskSize: 2Gi + memory: 2G + database: + collation: nb_NO diff --git a/internal/persistence/postgres/grant.go b/internal/persistence/postgres/grant.go new file mode 100644 index 000000000..70be4e361 --- /dev/null +++ b/internal/persistence/postgres/grant.go @@ -0,0 +1,133 @@ +package postgres + +import ( + "context" + "fmt" + "hash/crc32" + "strconv" + "time" + + "github.com/nais/api/internal/activitylog" + "github.com/nais/api/internal/auth/authz" + "github.com/nais/api/internal/kubernetes" + "github.com/nais/api/internal/kubernetes/watcher" + "github.com/nais/api/internal/slug" + k8serrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/dynamic" +) + +// Keep the legacy Zalando port-forward grant independent of the new NAIS Postgres watcher. +// Only this mutation reads data.nais.io; the rest of the Postgres API uses nais.io. +func legacyPostgresClient(ctx context.Context, environment string, gvr schema.GroupVersionResource) (dynamic.NamespaceableResourceInterface, error) { + return fromContext(ctx).postgresWatcher.SystemAuthenticatedClient(ctx, environment, watcher.WithImpersonatedClientGVR(gvr)) +} + +func getLegacyPostgres(ctx context.Context, input GrantPostgresAccessInput) error { + gvr := schema.GroupVersionResource{Group: "data.nais.io", Version: "v1", Resource: "postgres"} + client, err := legacyPostgresClient(ctx, input.EnvironmentName, gvr) + if err != nil { + return err + } + _, err = client.Namespace(input.TeamSlug.String()).Get(ctx, input.ClusterName, metav1.GetOptions{}) + return err +} + +func GrantZalandoPostgresAccess(ctx context.Context, input GrantPostgresAccessInput) error { + if err := input.Validate(ctx); err != nil { + return err + } + + namespace := fmt.Sprintf("pg-%s", input.TeamSlug.String()) + name := resourceNamer(input.TeamSlug, input.Grantee, input.ClusterName) + d, err := time.ParseDuration(input.Duration) + if err != nil { + return fmt.Errorf("parsing TTL: %w", err) + } + until := time.Now().Add(d) + labels := map[string]string{ + "euthanaisa.nais.io/kill-after": strconv.FormatInt(until.Unix(), 10), + "postgres.data.nais.io/name": input.ClusterName, + } + + if err := createGrantRole(ctx, input, name, namespace, labels); err != nil { + return err + } + if err := createGrantRoleBinding(ctx, input, name, namespace, labels); err != nil { + return err + } + + return activitylog.Create(ctx, activitylog.CreateInput{ + Action: activityLogEntryActionGrantAccess, + Actor: authz.ActorFromContext(ctx).User, + ResourceType: activityLogEntryResourceTypePostgres, + ResourceName: input.ClusterName, + EnvironmentName: new(input.EnvironmentName), + TeamSlug: new(input.TeamSlug), + Data: PostgresGrantAccessActivityLogEntryData{ + Grantee: input.Grantee, + Until: until, + }, + }) +} + +func createGrantRoleBinding(ctx context.Context, input GrantPostgresAccessInput, name, namespace string, labels map[string]string) error { + gvr := schema.GroupVersionResource{Group: "rbac.authorization.k8s.io", Version: "v1", Resource: "rolebindings"} + client, err := legacyPostgresClient(ctx, input.EnvironmentName, gvr) + if err != nil { + return err + } + res := &unstructured.Unstructured{} + res.SetAPIVersion(gvr.GroupVersion().String()) + res.SetKind("RoleBinding") + res.SetName(name) + res.SetNamespace(namespace) + res.SetAnnotations(kubernetes.WithCommonAnnotations(nil, authz.ActorFromContext(ctx).User.Identity())) + res.SetLabels(labels) + kubernetes.SetManagedByConsoleLabel(res) + res.Object["roleRef"] = map[string]any{ + "apiGroup": "rbac.authorization.k8s.io", + "kind": "Role", + "name": name, + } + res.Object["subjects"] = []any{map[string]any{"kind": "User", "name": input.Grantee}} + return createOrUpdateGrantResource(ctx, res, client.Namespace(namespace)) +} + +func createGrantRole(ctx context.Context, input GrantPostgresAccessInput, name, namespace string, labels map[string]string) error { + gvr := schema.GroupVersionResource{Group: "rbac.authorization.k8s.io", Version: "v1", Resource: "roles"} + client, err := legacyPostgresClient(ctx, input.EnvironmentName, gvr) + if err != nil { + return err + } + res := &unstructured.Unstructured{} + res.SetAPIVersion(gvr.GroupVersion().String()) + res.SetKind("Role") + res.SetName(name) + res.SetNamespace(namespace) + res.SetAnnotations(kubernetes.WithCommonAnnotations(nil, authz.ActorFromContext(ctx).User.Identity())) + res.SetLabels(labels) + kubernetes.SetManagedByConsoleLabel(res) + pods := []any{fmt.Sprintf("%s-0", input.ClusterName), fmt.Sprintf("%s-1", input.ClusterName), fmt.Sprintf("%s-2", input.ClusterName)} + res.Object["rules"] = []any{ + map[string]any{"apiGroups": []any{""}, "resources": []any{"pods"}, "verbs": []any{"get", "list", "watch"}, "resourceNames": pods}, + map[string]any{"apiGroups": []any{""}, "resources": []any{"pods/portforward"}, "verbs": []any{"get", "list", "watch", "create"}, "resourceNames": pods}, + } + return createOrUpdateGrantResource(ctx, res, client.Namespace(namespace)) +} + +func createOrUpdateGrantResource(ctx context.Context, res *unstructured.Unstructured, client dynamic.ResourceInterface) error { + _, err := client.Create(ctx, res, metav1.CreateOptions{}) + if k8serrors.IsAlreadyExists(err) { + _, err = client.Update(ctx, res, metav1.UpdateOptions{}) + } + return err +} + +func resourceNamer(teamSlug slug.Slug, grantee, name string) string { + hasher := crc32.NewIEEE() + fmt.Fprintf(hasher, "%s-%s-%s", teamSlug.String(), grantee, name) + return fmt.Sprintf("pg-grant-%08x", hasher.Sum32()) +} diff --git a/internal/persistence/postgres/grant_test.go b/internal/persistence/postgres/grant_test.go new file mode 100644 index 000000000..25cacc629 --- /dev/null +++ b/internal/persistence/postgres/grant_test.go @@ -0,0 +1,50 @@ +package postgres + +import ( + "context" + "os" + "testing" + "time" + + "github.com/nais/api/internal/kubernetes" + "github.com/nais/api/internal/kubernetes/fake" + "github.com/nais/api/internal/kubernetes/watcher" + "github.com/nais/api/internal/slug" + "github.com/sirupsen/logrus/hooks/test" +) + +func TestLegacyPostgresGrantValidatesTheOldCluster(t *testing.T) { + scheme, err := kubernetes.NewScheme() + if err != nil { + t.Fatal(err) + } + clusters, err := kubernetes.CreateClusterConfigMap("nav", []string{"dev"}, nil) + if err != nil { + t.Fatal(err) + } + log, _ := test.NewNullLogger() + mgr, err := watcher.NewManager(scheme, clusters, log, watcher.WithClientCreator(fake.Clients(os.DirFS("../../../integration_tests/k8s_resources/grant_zalando_postgres_access")))) + if err != nil { + t.Fatal(err) + } + t.Cleanup(mgr.Stop) + ctx := context.Background() + postgresWatcher := NewPostgresWatcher(ctx, mgr) + wait, cancel := context.WithTimeout(ctx, 5*time.Second) + defer cancel() + if !mgr.WaitForReady(wait) { + t.Fatal("Postgres watcher did not synchronize") + } + ctx = NewLoaderContext(ctx, postgresWatcher, "", "", "nav") + input := GrantPostgresAccessInput{ + ClusterName: "foobar", TeamSlug: slug.Slug("someteamname"), EnvironmentName: "dev", + Grantee: "someone@example.com", Duration: "30m", + } + if err := input.Validate(ctx); err != nil { + t.Fatalf("existing legacy cluster rejected: %v", err) + } + input.ClusterName = "missing" + if err := input.Validate(ctx); err == nil { + t.Fatal("missing legacy cluster accepted") + } +} From 0e65a43a26b766476b2e206f6cfc7b1c00ed8afd Mon Sep 17 00:00:00 2001 From: Johnny Fredheim Horvi Date: Tue, 29 Sep 2026 11:40:50 +0200 Subject: [PATCH 14/19] Preserve Zalando Postgres enum and assign Nais Postgres a distinct value --- pkg/apiclient/protoapi/databases.pb.go | 33 +++++++------ .../protoapi/databases_protoopaque.pb.go | 33 +++++++------ pkg/apiclient/protoapi/databases_test.go | 47 +++++++++++++++++++ pkg/apiclient/protoapi/schema/databases.proto | 3 +- 4 files changed, 87 insertions(+), 29 deletions(-) create mode 100644 pkg/apiclient/protoapi/databases_test.go diff --git a/pkg/apiclient/protoapi/databases.pb.go b/pkg/apiclient/protoapi/databases.pb.go index 29efa0ad7..d7b036ab0 100644 --- a/pkg/apiclient/protoapi/databases.pb.go +++ b/pkg/apiclient/protoapi/databases.pb.go @@ -27,7 +27,8 @@ type DatabaseType int32 const ( DatabaseType_DATABASE_TYPE_UNSPECIFIED DatabaseType = 0 DatabaseType_CLOUD_SQL DatabaseType = 1 - DatabaseType_NAIS_POSTGRES DatabaseType = 2 + DatabaseType_ZALANDO_POSTGRES DatabaseType = 2 + DatabaseType_NAIS_POSTGRES DatabaseType = 3 ) // Enum value maps for DatabaseType. @@ -35,12 +36,14 @@ var ( DatabaseType_name = map[int32]string{ 0: "DATABASE_TYPE_UNSPECIFIED", 1: "CLOUD_SQL", - 2: "NAIS_POSTGRES", + 2: "ZALANDO_POSTGRES", + 3: "NAIS_POSTGRES", } DatabaseType_value = map[string]int32{ "DATABASE_TYPE_UNSPECIFIED": 0, "CLOUD_SQL": 1, - "NAIS_POSTGRES": 2, + "ZALANDO_POSTGRES": 2, + "NAIS_POSTGRES": 3, } ) @@ -378,20 +381,22 @@ var file_databases_proto_rawDesc = string([]byte{ 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6e, 0x61, 0x69, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, - 0x6f, 0x2a, 0x4f, 0x0a, 0x0c, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x54, 0x79, 0x70, + 0x6f, 0x2a, 0x65, 0x0a, 0x0c, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1d, 0x0a, 0x19, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x4c, 0x4f, 0x55, 0x44, 0x5f, 0x53, 0x51, 0x4c, 0x10, 0x01, 0x12, - 0x11, 0x0a, 0x0d, 0x4e, 0x41, 0x49, 0x53, 0x5f, 0x50, 0x4f, 0x53, 0x54, 0x47, 0x52, 0x45, 0x53, - 0x10, 0x02, 0x32, 0x68, 0x0a, 0x09, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x12, - 0x5b, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x27, 0x2e, 0x6e, 0x61, 0x69, 0x73, 0x2e, 0x61, - 0x70, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4c, 0x69, 0x73, 0x74, - 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x28, 0x2e, 0x6e, 0x61, 0x69, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, - 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x1a, 0x5a, 0x18, - 0x2e, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x14, 0x0a, 0x10, 0x5a, 0x41, 0x4c, 0x41, 0x4e, 0x44, 0x4f, 0x5f, 0x50, 0x4f, 0x53, 0x54, 0x47, + 0x52, 0x45, 0x53, 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x4e, 0x41, 0x49, 0x53, 0x5f, 0x50, 0x4f, + 0x53, 0x54, 0x47, 0x52, 0x45, 0x53, 0x10, 0x03, 0x32, 0x68, 0x0a, 0x09, 0x44, 0x61, 0x74, 0x61, + 0x62, 0x61, 0x73, 0x65, 0x73, 0x12, 0x5b, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x27, 0x2e, + 0x6e, 0x61, 0x69, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x6e, 0x61, 0x69, 0x73, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x44, + 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x42, 0x1a, 0x5a, 0x18, 0x2e, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x63, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x61, 0x70, 0x69, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, }) var file_databases_proto_enumTypes = make([]protoimpl.EnumInfo, 1) diff --git a/pkg/apiclient/protoapi/databases_protoopaque.pb.go b/pkg/apiclient/protoapi/databases_protoopaque.pb.go index c85fa69ae..f5b9a9796 100644 --- a/pkg/apiclient/protoapi/databases_protoopaque.pb.go +++ b/pkg/apiclient/protoapi/databases_protoopaque.pb.go @@ -27,7 +27,8 @@ type DatabaseType int32 const ( DatabaseType_DATABASE_TYPE_UNSPECIFIED DatabaseType = 0 DatabaseType_CLOUD_SQL DatabaseType = 1 - DatabaseType_NAIS_POSTGRES DatabaseType = 2 + DatabaseType_ZALANDO_POSTGRES DatabaseType = 2 + DatabaseType_NAIS_POSTGRES DatabaseType = 3 ) // Enum value maps for DatabaseType. @@ -35,12 +36,14 @@ var ( DatabaseType_name = map[int32]string{ 0: "DATABASE_TYPE_UNSPECIFIED", 1: "CLOUD_SQL", - 2: "NAIS_POSTGRES", + 2: "ZALANDO_POSTGRES", + 3: "NAIS_POSTGRES", } DatabaseType_value = map[string]int32{ "DATABASE_TYPE_UNSPECIFIED": 0, "CLOUD_SQL": 1, - "NAIS_POSTGRES": 2, + "ZALANDO_POSTGRES": 2, + "NAIS_POSTGRES": 3, } ) @@ -380,20 +383,22 @@ var file_databases_proto_rawDesc = string([]byte{ 0x69, 0x6e, 0x66, 0x6f, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x6e, 0x61, 0x69, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x50, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x08, 0x70, 0x61, 0x67, 0x65, 0x49, 0x6e, 0x66, - 0x6f, 0x2a, 0x4f, 0x0a, 0x0c, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x54, 0x79, 0x70, + 0x6f, 0x2a, 0x65, 0x0a, 0x0c, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x54, 0x79, 0x70, 0x65, 0x12, 0x1d, 0x0a, 0x19, 0x44, 0x41, 0x54, 0x41, 0x42, 0x41, 0x53, 0x45, 0x5f, 0x54, 0x59, 0x50, 0x45, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x43, 0x4c, 0x4f, 0x55, 0x44, 0x5f, 0x53, 0x51, 0x4c, 0x10, 0x01, 0x12, - 0x11, 0x0a, 0x0d, 0x4e, 0x41, 0x49, 0x53, 0x5f, 0x50, 0x4f, 0x53, 0x54, 0x47, 0x52, 0x45, 0x53, - 0x10, 0x02, 0x32, 0x68, 0x0a, 0x09, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x12, - 0x5b, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x27, 0x2e, 0x6e, 0x61, 0x69, 0x73, 0x2e, 0x61, - 0x70, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4c, 0x69, 0x73, 0x74, - 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, - 0x1a, 0x28, 0x2e, 0x6e, 0x61, 0x69, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, - 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x1a, 0x5a, 0x18, - 0x2e, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2f, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x14, 0x0a, 0x10, 0x5a, 0x41, 0x4c, 0x41, 0x4e, 0x44, 0x4f, 0x5f, 0x50, 0x4f, 0x53, 0x54, 0x47, + 0x52, 0x45, 0x53, 0x10, 0x02, 0x12, 0x11, 0x0a, 0x0d, 0x4e, 0x41, 0x49, 0x53, 0x5f, 0x50, 0x4f, + 0x53, 0x54, 0x47, 0x52, 0x45, 0x53, 0x10, 0x03, 0x32, 0x68, 0x0a, 0x09, 0x44, 0x61, 0x74, 0x61, + 0x62, 0x61, 0x73, 0x65, 0x73, 0x12, 0x5b, 0x0a, 0x04, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x27, 0x2e, + 0x6e, 0x61, 0x69, 0x73, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x44, 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x28, 0x2e, 0x6e, 0x61, 0x69, 0x73, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x44, + 0x61, 0x74, 0x61, 0x62, 0x61, 0x73, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x22, 0x00, 0x42, 0x1a, 0x5a, 0x18, 0x2e, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x61, 0x70, 0x69, 0x63, + 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x61, 0x70, 0x69, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, }) var file_databases_proto_enumTypes = make([]protoimpl.EnumInfo, 1) diff --git a/pkg/apiclient/protoapi/databases_test.go b/pkg/apiclient/protoapi/databases_test.go new file mode 100644 index 000000000..ffc13db6b --- /dev/null +++ b/pkg/apiclient/protoapi/databases_test.go @@ -0,0 +1,47 @@ +package protoapi_test + +import ( + "encoding/json" + "testing" + + "github.com/nais/api/pkg/apiclient/protoapi" + "google.golang.org/protobuf/encoding/protojson" +) + +func TestPostgresDatabaseTypes(t *testing.T) { + if protoapi.DatabaseType_ZALANDO_POSTGRES != 2 || protoapi.DatabaseType_NAIS_POSTGRES != 3 { + t.Fatal("old and new Postgres database types must retain distinct wire values") + } + + for _, tt := range []struct { + name string + typeValue protoapi.DatabaseType + }{ + {name: "ZALANDO_POSTGRES", typeValue: protoapi.DatabaseType_ZALANDO_POSTGRES}, + {name: "NAIS_POSTGRES", typeValue: protoapi.DatabaseType_NAIS_POSTGRES}, + } { + t.Run(tt.name, func(t *testing.T) { + var database protoapi.Database + if err := protojson.Unmarshal([]byte(`{"type":"`+tt.name+`"}`), &database); err != nil { + t.Fatalf("unmarshal database type %q: %v", tt.name, err) + } + if database.GetType() != tt.typeValue { + t.Fatalf("database type = %v, want %v", database.GetType(), tt.typeValue) + } + + data, err := protojson.Marshal(&database) + if err != nil { + t.Fatalf("marshal database: %v", err) + } + var fields struct { + Type string `json:"type"` + } + if err := json.Unmarshal(data, &fields); err != nil { + t.Fatalf("decode database JSON: %v", err) + } + if fields.Type != tt.name { + t.Errorf("serialized database type = %q, want %q", fields.Type, tt.name) + } + }) + } +} diff --git a/pkg/apiclient/protoapi/schema/databases.proto b/pkg/apiclient/protoapi/schema/databases.proto index 31485f34a..8388e50d0 100644 --- a/pkg/apiclient/protoapi/schema/databases.proto +++ b/pkg/apiclient/protoapi/schema/databases.proto @@ -9,7 +9,8 @@ option go_package = "./pkg/apiclient/protoapi"; enum DatabaseType { DATABASE_TYPE_UNSPECIFIED = 0; CLOUD_SQL = 1; - NAIS_POSTGRES = 2; + ZALANDO_POSTGRES = 2; + NAIS_POSTGRES = 3; } message Database { From ab4a76da71303070176b0df68bfd037025538b77 Mon Sep 17 00:00:00 2001 From: Johnny Fredheim Horvi Date: Tue, 29 Sep 2026 11:55:54 +0200 Subject: [PATCH 15/19] Use one PostgresAccess GVR for reads and creation --- internal/persistence/postgres/queries.go | 20 +++++--------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/internal/persistence/postgres/queries.go b/internal/persistence/postgres/queries.go index 5db2136bf..38d3b89d7 100644 --- a/internal/persistence/postgres/queries.go +++ b/internal/persistence/postgres/queries.go @@ -178,10 +178,9 @@ func GetPostgresAccessByIdent(ctx context.Context, id ident.Ident) (*PostgresAcc return GetPostgresAccess(ctx, name, teamSlug, environmentName) } -const ( - postgresAccessResource = "postgresaccesses" - postgresAccessGroup = "nais.io" -) +func postgresAccessGVR() schema.GroupVersionResource { + return schema.GroupVersionResource{Group: "nais.io", Version: "v1", Resource: "postgresaccesses"} +} // GetPostgresAccess returns a personal PostgresAccess status. Connection // credentials are deliberately available only through GetPostgresAccessConnection. @@ -250,11 +249,7 @@ func GetPostgresAccessConnection(ctx context.Context, input PostgresAccessConnec } func getPostgresAccessResource(ctx context.Context, name string, teamSlug slug.Slug, environmentName string) (*unstructured.Unstructured, error) { - accessClient, err := fromContext(ctx).postgresWatcher.SystemAuthenticatedClient(ctx, environmentName, watcher.WithImpersonatedClientGVR(schema.GroupVersionResource{ - Group: postgresAccessGroup, - Version: "v1", - Resource: postgresAccessResource, - })) + accessClient, err := fromContext(ctx).postgresWatcher.SystemAuthenticatedClient(ctx, environmentName, watcher.WithImpersonatedClientGVR(postgresAccessGVR())) if err != nil { return nil, fmt.Errorf("creating postgresaccess client: %w", err) } @@ -471,12 +466,7 @@ func CreatePostgresAccess(ctx context.Context, input CreatePostgresAccessInput) return nil, err } - gvr := schema.GroupVersionResource{ - Group: "nais.io", - Version: "v1", - Resource: "postgresaccesses", - } - client, err := fromContext(ctx).postgresWatcher.SystemAuthenticatedClient(ctx, input.EnvironmentName, watcher.WithImpersonatedClientGVR(gvr)) + client, err := fromContext(ctx).postgresWatcher.SystemAuthenticatedClient(ctx, input.EnvironmentName, watcher.WithImpersonatedClientGVR(postgresAccessGVR())) if err != nil { return nil, err } From bcf6ee1b5f46ce4c9ef76fa8ceccf5d35a356041 Mon Sep 17 00:00:00 2001 From: Johnny Fredheim Horvi Date: Tue, 29 Sep 2026 14:23:31 +0200 Subject: [PATCH 16/19] Resolve personal Postgres connections from PostgresAccess status --- .../console-backend-rbac/templates/rbac.yaml | 13 ---- integration_tests/create_postgres_access.lua | 2 +- .../dev/someteamname/accesses.yaml | 6 +- .../dev/someteamname/connection.yaml | 36 --------- internal/persistence/postgres/connection.go | 74 ++++--------------- .../persistence/postgres/connection_test.go | 18 ----- internal/persistence/postgres/queries.go | 10 ++- internal/persistence/postgres/queries_test.go | 8 ++ 8 files changed, 37 insertions(+), 130 deletions(-) diff --git a/charts/console-backend-rbac/templates/rbac.yaml b/charts/console-backend-rbac/templates/rbac.yaml index 6fff69ad4..ee45d49f7 100644 --- a/charts/console-backend-rbac/templates/rbac.yaml +++ b/charts/console-backend-rbac/templates/rbac.yaml @@ -135,13 +135,6 @@ rules: - list - watch - delete - # Owner-only connection retrieval reads the mapping, not the relay's proof hash via status. - - apiGroups: - - "nais.io" - resources: - - relayaccesses - verbs: - - get - apiGroups: - postgresql.cnpg.io resources: @@ -325,12 +318,6 @@ rules: - list - watch - delete - - apiGroups: - - "nais.io" - resources: - - relayaccesses - verbs: - - get - apiGroups: - postgresql.cnpg.io resources: diff --git a/integration_tests/create_postgres_access.lua b/integration_tests/create_postgres_access.lua index 770edb298..6a81015f0 100644 --- a/integration_tests/create_postgres_access.lua +++ b/integration_tests/create_postgres_access.lua @@ -294,7 +294,7 @@ Test.gql("PostgresAccess connection returns credentials only to its owner", func serverName = "pg-foobar-rw.someteamname.svc.cluster.local", username = "user-foobar-role", relayEndpoint = Contains("https://relay.external.dev."), - relayAccess = "someteamname/ready-access", + relayAccess = "someteamname/mapped-access", relayToken = "AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8", }, } } } }, diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/accesses.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/accesses.yaml index 035e27731..7ac8325a1 100644 --- a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/accesses.yaml +++ b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/accesses.yaml @@ -12,8 +12,10 @@ spec: expiresAt: "2099-09-17T12:00:00Z" status: databaseRole: user-foobar-role - relayAccess: ready-access + relayAccess: mapped-access tokenSecret: ready-access-relay-token + serverName: pg-foobar-rw.someteamname.svc.cluster.local + serverCASecret: pg-foobar-ca conditions: - type: Ready status: "True" @@ -97,6 +99,8 @@ status: databaseRole: user-foobar-role relayAccess: missing-secret-access tokenSecret: missing-secret-access-relay-token + serverName: pg-foobar-rw.someteamname.svc.cluster.local + serverCASecret: pg-foobar-ca conditions: - type: Ready status: "True" diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/connection.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/connection.yaml index dd158c40a..eb8beacb9 100644 --- a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/connection.yaml +++ b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/connection.yaml @@ -1,40 +1,4 @@ --- -apiVersion: nais.io/v1alpha1 -kind: RelayAccess -metadata: - name: ready-access - namespace: someteamname - ownerReferences: - - apiVersion: nais.io/v1 - kind: PostgresAccess - name: ready-access - uid: 11111111-1111-4111-8111-111111111111 - controller: true -spec: - target: - serviceName: pg-foobar-rw - port: 5432 - expiresAt: "2099-09-17T12:00:00Z" - tokenSHA256: 630dcd2966c4336691125448bbb25b4ff412a49c732db2c8abc1b8581bd710dd ---- -apiVersion: nais.io/v1alpha1 -kind: RelayAccess -metadata: - name: missing-secret-access - namespace: someteamname - ownerReferences: - - apiVersion: nais.io/v1 - kind: PostgresAccess - name: missing-secret-access - uid: 22222222-2222-4222-8222-222222222222 - controller: true -spec: - target: - serviceName: pg-foobar-rw - port: 5432 - expiresAt: "2099-09-17T12:00:00Z" - tokenSHA256: 630dcd2966c4336691125448bbb25b4ff412a49c732db2c8abc1b8581bd710dd ---- apiVersion: v1 kind: Secret metadata: diff --git a/internal/persistence/postgres/connection.go b/internal/persistence/postgres/connection.go index 946130e61..a57e1dd98 100644 --- a/internal/persistence/postgres/connection.go +++ b/internal/persistence/postgres/connection.go @@ -2,15 +2,11 @@ package postgres import ( "context" - "crypto/sha256" - "encoding/base64" - "encoding/hex" "fmt" "strings" "github.com/nais/api/internal/graph/apierror" "github.com/nais/api/internal/kubernetes/watcher" - pgratorv1 "github.com/nais/pgrator/pkg/api/v1" corev1 "k8s.io/api/core/v1" k8serrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -22,39 +18,10 @@ import ( // All connection resources are read on demand after the caller has been // authorized as the PostgresAccess owner. No credentials enter the watch cache. func loadPostgresAccessConnection(ctx context.Context, access *unstructured.Unstructured, input PostgresAccessConnectionInput, connection *PostgresAccessConnectionDetails, tokenSecretName string) error { - instance, _, err := unstructured.NestedString(access.Object, "spec", "postgresInstance") - if err != nil || instance == "" || access.GetUID() == "" { - return apierror.Errorf("PostgresAccess %q is not ready", access.GetName()) - } - clusterName := pgratorv1.CNPGClusterName(instance) - if clusterName == "" { + if access.GetUID() == "" { return apierror.Errorf("PostgresAccess %q is not ready", access.GetName()) } namespace := input.TeamSlug.String() - mapping, err := getAccessResource(ctx, input.EnvironmentName, namespace, access.GetName(), schema.GroupVersionResource{Group: "nais.io", Version: "v1alpha1", Resource: "relayaccesses"}) - if err != nil { - return err - } - service, _, err := unstructured.NestedString(mapping.Object, "spec", "target", "serviceName") - if err != nil { - return err - } - port, _, err := unstructured.NestedInt64(mapping.Object, "spec", "target", "port") - if err != nil { - return err - } - expires, _, err := unstructured.NestedString(mapping.Object, "spec", "expiresAt") - if err != nil { - return err - } - accessExpires, _, err := unstructured.NestedString(access.Object, "spec", "expiresAt") - if err != nil { - return err - } - if !metav1.IsControlledBy(mapping, access) || mapping.GetDeletionTimestamp() != nil || service != clusterName+"-rw" || port != 5432 || expires != accessExpires { - return apierror.Errorf("relay mapping for PostgresAccess %q is not available", access.GetName()) - } - tokenSecret, err := getAccessResource(ctx, input.EnvironmentName, namespace, tokenSecretName, schema.GroupVersionResource{Version: "v1", Resource: "secrets"}) if err != nil { return err @@ -63,15 +30,6 @@ func loadPostgresAccessConnection(ctx context.Context, access *unstructured.Unst if err != nil { return err } - raw, decodeErr := base64.RawURLEncoding.DecodeString(token) - digest, _, err := unstructured.NestedString(mapping.Object, "spec", "tokenSHA256") - if err != nil { - return err - } - if decodeErr != nil || len(raw) != 32 || base64.RawURLEncoding.EncodeToString(raw) != token || !tokenMatchesDigest(raw, digest) { - return apierror.Errorf("relay credentials for PostgresAccess %q are not available", access.GetName()) - } - // The broker creates short names (postgres-access-), so this is the // pgrator-owned credential Secret for this access, not a client-supplied name. credential, err := getAccessResource(ctx, input.EnvironmentName, namespace, access.GetName()+"-credentials", schema.GroupVersionResource{Version: "v1", Resource: "secrets"}) @@ -91,16 +49,9 @@ func loadPostgresAccessConnection(ctx context.Context, access *unstructured.Unst return apierror.Errorf("credentials for PostgresAccess %q are not available", access.GetName()) } - cluster, err := getAccessResource(ctx, input.EnvironmentName, namespace, clusterName, schema.GroupVersionResource{Group: "postgresql.cnpg.io", Version: "v1", Resource: "clusters"}) - if err != nil { - return err - } - serverCA, _, err := unstructured.NestedString(cluster.Object, "spec", "certificates", "serverCASecret") - if err != nil { - return err - } - if serverCA == "" { - serverCA = clusterName + "-ca" // CNPG's default server CA Secret name. + serverCA, _, err := unstructured.NestedString(access.Object, "status", "serverCASecret") + if err != nil || serverCA == "" { + return apierror.Errorf("PostgresAccess %q is not ready", access.GetName()) } caSecret, err := getAccessResource(ctx, input.EnvironmentName, namespace, serverCA, schema.GroupVersionResource{Version: "v1", Resource: "secrets"}) if err != nil { @@ -117,18 +68,21 @@ func loadPostgresAccessConnection(ctx context.Context, access *unstructured.Unst connection.Username = username connection.Password = password connection.CACertificate = string(ca.Data["ca.crt"]) - connection.ServerName = service + "." + namespace + ".svc.cluster.local" + serverName, _, err := unstructured.NestedString(access.Object, "status", "serverName") + if err != nil || serverName == "" { + 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) - connection.RelayAccess = namespace + "/" + mapping.GetName() + relayName, _, err := unstructured.NestedString(access.Object, "status", "relayAccess") + if err != nil || relayName == "" { + return apierror.Errorf("PostgresAccess %q is not ready", access.GetName()) + } + connection.RelayAccess = namespace + "/" + relayName connection.RelayToken = token return nil } -func tokenMatchesDigest(raw []byte, digest string) bool { - sum := sha256.Sum256(raw) - return hex.EncodeToString(sum[:]) == digest -} - func accessSecretData(secret, access *unstructured.Unstructured, key string) (string, error) { if !metav1.IsControlledBy(secret, access) || secret.GetDeletionTimestamp() != nil { return "", apierror.Errorf("credentials for PostgresAccess %q are not available", access.GetName()) diff --git a/internal/persistence/postgres/connection_test.go b/internal/persistence/postgres/connection_test.go index c919e24d3..dc24632be 100644 --- a/internal/persistence/postgres/connection_test.go +++ b/internal/persistence/postgres/connection_test.go @@ -1,8 +1,6 @@ package postgres import ( - "crypto/sha256" - "encoding/hex" "strings" "testing" @@ -48,19 +46,3 @@ func TestAccessSecretDataRequiresAccessOwnership(t *testing.T) { t.Fatalf("missing token error = %v", err) } } - -func TestRelayTokenDigest(t *testing.T) { - raw := make([]byte, 32) - for i := range raw { - raw[i] = byte(i) - } - sum := sha256.Sum256(raw) - if !tokenMatchesDigest(raw, hex.EncodeToString(sum[:])) { - t.Fatal("valid token is not accepted") - } - wrong := append([]byte(nil), raw...) - wrong[0]++ - if tokenMatchesDigest(wrong, hex.EncodeToString(sum[:])) { - t.Fatal("wrong token accepted") - } -} diff --git a/internal/persistence/postgres/queries.go b/internal/persistence/postgres/queries.go index 38d3b89d7..a3f827924 100644 --- a/internal/persistence/postgres/queries.go +++ b/internal/persistence/postgres/queries.go @@ -283,7 +283,7 @@ func postgresAccessConnectionDetails(access *unstructured.Unstructured, now time return nil, "", apierror.Errorf("PostgresAccess %q is not ready", access.GetName()) } relayName, _, err := unstructured.NestedString(access.Object, "status", "relayAccess") - if err != nil || relayName != access.GetName() { + if err != nil || relayName == "" { return nil, "", apierror.Errorf("PostgresAccess %q is not ready", access.GetName()) } tokenSecret, _, err := unstructured.NestedString(access.Object, "status", "tokenSecret") @@ -294,6 +294,14 @@ func postgresAccessConnectionDetails(access *unstructured.Unstructured, now time if err != nil || role == "" { return nil, "", apierror.Errorf("PostgresAccess %q is not ready", access.GetName()) } + serverName, _, err := unstructured.NestedString(access.Object, "status", "serverName") + if err != nil || serverName == "" { + return nil, "", apierror.Errorf("PostgresAccess %q is not ready", access.GetName()) + } + serverCA, _, err := unstructured.NestedString(access.Object, "status", "serverCASecret") + if err != nil || serverCA == "" { + return nil, "", apierror.Errorf("PostgresAccess %q is not ready", access.GetName()) + } return &PostgresAccessConnectionDetails{}, tokenSecret, nil } diff --git a/internal/persistence/postgres/queries_test.go b/internal/persistence/postgres/queries_test.go index 860641d44..7c986251f 100644 --- a/internal/persistence/postgres/queries_test.go +++ b/internal/persistence/postgres/queries_test.go @@ -179,6 +179,8 @@ func TestPostgresAccessConnectionDetails(t *testing.T) { "databaseRole": "personal-role", "relayAccess": "access", "tokenSecret": "access-relay-token", + "serverName": "pg-orders-rw.team.svc.cluster.local", + "serverCASecret": "pg-orders-ca", "conditions": []any{map[string]any{"type": "Ready", "status": "True"}}, }, }} @@ -202,6 +204,12 @@ 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 server name", edit: func(u *unstructured.Unstructured) { + unstructured.RemoveNestedField(u.Object, "status", "serverName") + }, want: "not ready"}, + {name: "missing server CA reference", edit: func(u *unstructured.Unstructured) { + unstructured.RemoveNestedField(u.Object, "status", "serverCASecret") + }, want: "not ready"}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { From 2901eec146216594fda3fb3f7e0c286c27a9bbff Mon Sep 17 00:00:00 2001 From: Johnny Fredheim Horvi Date: Tue, 29 Sep 2026 15:40:08 +0200 Subject: [PATCH 17/19] instances -> branches --- .../console-backend-rbac/templates/rbac.yaml | 4 +- data/k8s/dev/devteam/postgres.yaml | 4 +- integration_tests/create_postgres_access.lua | 26 +- .../dev/someteamname/accesses.yaml | 12 +- .../dev/someteamname/postgres.yaml | 10 +- .../dev/labelteam/postgres.yaml | 12 +- .../postgres_with_audit.yaml | 4 +- .../dev/pg-delete-team/postgres.yaml | 6 +- .../dev/someteamname/applications.yaml | 0 .../dev/someteamname/postgres_another_db.yaml | 4 +- .../dev/someteamname/postgres_foobar.yaml | 4 +- .../dev/someteamname/postgres_with_audit.yaml | 4 +- .../someteamname/postgres_without_audit.yaml | 4 +- .../dev/postgres-workload-team/resources.yaml | 8 +- integration_tests/label_selectors.lua | 12 +- integration_tests/postgres_audit_log.lua | 6 +- integration_tests/postgres_branch_delete.lua | 20 + integration_tests/postgres_branches.lua | 63 + integration_tests/postgres_delete.lua | 20 - integration_tests/postgres_instances.lua | 63 - integration_tests/postgres_workloads.lua | 16 +- internal/cmd/api/api.go | 2 +- internal/cmd/api/http.go | 4 +- .../graph/gengql/applications.generated.go | 28 +- internal/graph/gengql/complexity.go | 4 +- internal/graph/gengql/jobs.generated.go | 28 +- .../graph/gengql/persistence.generated.go | 8 +- internal/graph/gengql/postgres.generated.go | 1588 ++++++++--------- internal/graph/gengql/root_.generated.go | 752 ++++---- internal/graph/gengql/schema.generated.go | 42 +- internal/graph/gengql/search.generated.go | 4 +- internal/graph/gengql/teams.generated.go | 76 +- internal/graph/postgres.resolvers.go | 54 +- internal/graph/schema/postgres.graphqls | 172 +- internal/grpc/grpc.go | 4 +- internal/grpc/grpcdatabase/server.go | 20 +- internal/grpc/grpcdatabase/server_test.go | 4 +- .../testdata/dev-gcp/myteam/postgres.yaml | 8 +- internal/kubernetes/fake/fake.go | 4 +- .../kubernetes/fake/postgres_fixtures_test.go | 18 +- internal/kubernetes/watchers/watchers.go | 6 +- internal/persistence/postgres/connection.go | 2 +- internal/persistence/postgres/dataloader.go | 35 +- internal/persistence/postgres/delete_test.go | 42 +- internal/persistence/postgres/facets.go | 22 +- internal/persistence/postgres/facets_test.go | 20 +- internal/persistence/postgres/grant.go | 11 +- internal/persistence/postgres/grant_test.go | 4 +- internal/persistence/postgres/models.go | 214 +-- internal/persistence/postgres/models_test.go | 51 +- internal/persistence/postgres/node.go | 10 +- internal/persistence/postgres/queries.go | 112 +- internal/persistence/postgres/queries_test.go | 26 +- internal/persistence/postgres/search.go | 8 +- internal/persistence/postgres/sortfilter.go | 8 +- 55 files changed, 1860 insertions(+), 1833 deletions(-) rename integration_tests/k8s_resources/{postgres_delete => postgres_branch_delete}/dev/pg-delete-team/postgres.yaml (82%) rename integration_tests/k8s_resources/{postgres_instances => postgres_branches}/dev/someteamname/applications.yaml (100%) rename integration_tests/k8s_resources/{postgres_instances => postgres_branches}/dev/someteamname/postgres_another_db.yaml (90%) rename integration_tests/k8s_resources/{postgres_instances => postgres_branches}/dev/someteamname/postgres_foobar.yaml (92%) rename integration_tests/k8s_resources/{postgres_instances => postgres_branches}/dev/someteamname/postgres_with_audit.yaml (90%) rename integration_tests/k8s_resources/{postgres_instances => postgres_branches}/dev/someteamname/postgres_without_audit.yaml (90%) create mode 100644 integration_tests/postgres_branch_delete.lua create mode 100644 integration_tests/postgres_branches.lua delete mode 100644 integration_tests/postgres_delete.lua delete mode 100644 integration_tests/postgres_instances.lua diff --git a/charts/console-backend-rbac/templates/rbac.yaml b/charts/console-backend-rbac/templates/rbac.yaml index ee45d49f7..b312dd02c 100644 --- a/charts/console-backend-rbac/templates/rbac.yaml +++ b/charts/console-backend-rbac/templates/rbac.yaml @@ -129,7 +129,7 @@ rules: - apiGroups: - "nais.io" resources: - - postgresinstances + - postgresbranches verbs: - get - list @@ -312,7 +312,7 @@ rules: - apiGroups: - "nais.io" resources: - - postgresinstances + - postgresbranches verbs: - get - list diff --git a/data/k8s/dev/devteam/postgres.yaml b/data/k8s/dev/devteam/postgres.yaml index 8930a6aed..7a8df5dbb 100644 --- a/data/k8s/dev/devteam/postgres.yaml +++ b/data/k8s/dev/devteam/postgres.yaml @@ -7,10 +7,10 @@ metadata: spec: majorVersion: "18" status: - activeInstance: postgres-1 + activeBranch: postgres-1 --- apiVersion: nais.io/v1 -kind: PostgresInstance +kind: PostgresBranch metadata: name: postgres-1 namespace: devteam diff --git a/integration_tests/create_postgres_access.lua b/integration_tests/create_postgres_access.lua index 6a81015f0..535a5b906 100644 --- a/integration_tests/create_postgres_access.lua +++ b/integration_tests/create_postgres_access.lua @@ -13,7 +13,7 @@ Test.gql("Create personal postgres access without authorization", function(t) t.query [[ mutation CreatePostgresAccess { createPostgresAccess(input: { - postgresInstance: "foobar" + postgresBranch: "foobar" environmentName: "dev" teamSlug: "someteamname" accessLevel: READ @@ -42,7 +42,7 @@ Test.gql("Create personal postgres access requires an audit reason", function(t) t.query [[ mutation CreatePostgresAccess { createPostgresAccess(input: { - postgresInstance: "foobar" + postgresBranch: "foobar" environmentName: "dev" teamSlug: "someteamname" accessLevel: READ @@ -70,7 +70,7 @@ Test.gql("Create personal postgres access rejects an unknown instance", function t.query [[ mutation CreatePostgresAccess { createPostgresAccess(input: { - postgresInstance: "unknown" + postgresBranch: "unknown" environmentName: "dev" teamSlug: "someteamname" accessLevel: READ @@ -85,8 +85,8 @@ Test.gql("Create personal postgres access rejects an unknown instance", function t.check { errors = { { - extensions = { field = "postgresInstance" }, - message = Contains("Could not find PostgresInstance"), + extensions = { field = "postgresBranch" }, + message = Contains("Could not find PostgresBranch"), path = { "createPostgresAccess" }, }, }, @@ -98,13 +98,13 @@ Test.gql("Create personal postgres access rejects a logical Postgres without a p t.addHeader("x-user-email", user:email()) t.query [[ mutation { createPostgresAccess(input: { - postgresInstance: "legacy-only", environmentName: "dev", + postgresBranch: "legacy-only", environmentName: "dev", teamSlug: "someteamname", accessLevel: READ, reason: "Testing missing physical database instance" }) { name } } ]] t.check { - errors = { { extensions = { field = "postgresInstance" }, message = Contains("Could not find PostgresInstance"), path = { "createPostgresAccess" } } }, + errors = { { extensions = { field = "postgresBranch" }, message = Contains("Could not find PostgresBranch"), path = { "createPostgresAccess" } } }, data = Null, } end) @@ -114,7 +114,7 @@ Test.gql("Create personal postgres access rejects an unavailable instance", func t.query [[ mutation CreatePostgresAccess { createPostgresAccess(input: { - postgresInstance: "progressing" + postgresBranch: "progressing" environmentName: "dev" teamSlug: "someteamname" accessLevel: READ @@ -129,7 +129,7 @@ Test.gql("Create personal postgres access rejects an unavailable instance", func t.check { errors = { { - extensions = { field = "postgresInstance" }, + extensions = { field = "postgresBranch" }, message = Contains("is not available"), path = { "createPostgresAccess" }, }, @@ -143,7 +143,7 @@ Test.gql("Create personal postgres access", function(t) t.query [[ mutation CreatePostgresAccess { createPostgresAccess(input: { - postgresInstance: "foobar" + postgresBranch: "foobar" environmentName: "dev" teamSlug: "someteamname" accessLevel: READWRITE @@ -213,7 +213,7 @@ Test.gql("Personal access targets a physical instance, even when its name differ t.addHeader("x-user-email", user:email()) t.query [[ mutation { createPostgresAccess(input: { - postgresInstance: "foobar-recovered", environmentName: "dev", + postgresBranch: "foobar-recovered", environmentName: "dev", teamSlug: "someteamname", accessLevel: READ, reason: "Testing access to a recovered instance" }) { name } } @@ -222,10 +222,10 @@ Test.gql("Personal access targets a physical instance, even when its name differ t.query [[ query { team(slug: "someteamname") { environment(name: "dev") { - postgresAccess(name: "recovered-access") { postgresInstance { name } } + postgresAccess(name: "recovered-access") { postgresBranch { name } } } } } ]] - t.check { data = { team = { environment = { postgresAccess = { postgresInstance = { name = "foobar-recovered" } } } } } } + t.check { data = { team = { environment = { postgresAccess = { postgresBranch = { name = "foobar-recovered" } } } } } } end) Test.gql("PostgresAccess status is visible to authorized team members", function(t) diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/accesses.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/accesses.yaml index 7ac8325a1..4b232b2b6 100644 --- a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/accesses.yaml +++ b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/accesses.yaml @@ -6,7 +6,7 @@ metadata: namespace: someteamname uid: 11111111-1111-4111-8111-111111111111 spec: - postgresInstance: foobar + postgresBranch: foobar username: user@usersen.com accessLevel: readwrite expiresAt: "2099-09-17T12:00:00Z" @@ -28,7 +28,7 @@ metadata: name: recovered-access namespace: someteamname spec: - postgresInstance: foobar-recovered + postgresBranch: foobar-recovered username: user@usersen.com accessLevel: read expiresAt: "2099-09-17T12:00:00Z" @@ -43,7 +43,7 @@ metadata: name: pending-access namespace: someteamname spec: - postgresInstance: foobar + postgresBranch: foobar username: user@usersen.com accessLevel: read expiresAt: "2099-09-17T12:00:00Z" @@ -58,7 +58,7 @@ metadata: name: failed-access namespace: someteamname spec: - postgresInstance: foobar + postgresBranch: foobar username: user@usersen.com accessLevel: readwritecreate expiresAt: "2099-09-17T12:00:00Z" @@ -75,7 +75,7 @@ metadata: name: expired-access namespace: someteamname spec: - postgresInstance: foobar + postgresBranch: foobar username: user@usersen.com accessLevel: read expiresAt: "2000-01-01T00:00:00Z" @@ -91,7 +91,7 @@ metadata: namespace: someteamname uid: 22222222-2222-4222-8222-222222222222 spec: - postgresInstance: foobar + postgresBranch: foobar username: user@usersen.com accessLevel: read expiresAt: "2099-09-17T12:00:00Z" diff --git a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres.yaml b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres.yaml index 7f490efa7..0c066c162 100644 --- a/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres.yaml +++ b/integration_tests/k8s_resources/create_postgres_access/dev/someteamname/postgres.yaml @@ -7,7 +7,7 @@ metadata: spec: majorVersion: "17" status: - activeInstance: foobar + activeBranch: foobar --- apiVersion: nais.io/v1 kind: Postgres @@ -17,7 +17,7 @@ metadata: spec: majorVersion: "17" status: - activeInstance: progressing + activeBranch: progressing --- apiVersion: nais.io/v1 kind: Postgres @@ -28,7 +28,7 @@ spec: majorVersion: "17" --- apiVersion: nais.io/v1 -kind: PostgresInstance +kind: PostgresBranch metadata: name: foobar namespace: someteamname @@ -44,7 +44,7 @@ status: lastTransitionTime: "2026-09-17T00:00:00Z" --- apiVersion: nais.io/v1 -kind: PostgresInstance +kind: PostgresBranch metadata: name: progressing namespace: someteamname @@ -60,7 +60,7 @@ status: lastTransitionTime: "2026-09-17T00:00:00Z" --- apiVersion: nais.io/v1 -kind: PostgresInstance +kind: PostgresBranch metadata: name: foobar-recovered namespace: someteamname diff --git a/integration_tests/k8s_resources/label_selectors/dev/labelteam/postgres.yaml b/integration_tests/k8s_resources/label_selectors/dev/labelteam/postgres.yaml index d79b3f7a8..5153f6d18 100644 --- a/integration_tests/k8s_resources/label_selectors/dev/labelteam/postgres.yaml +++ b/integration_tests/k8s_resources/label_selectors/dev/labelteam/postgres.yaml @@ -7,10 +7,10 @@ metadata: spec: majorVersion: "17" status: - activeInstance: postgres-one + activeBranch: postgres-one --- apiVersion: nais.io/v1 -kind: PostgresInstance +kind: PostgresBranch metadata: name: postgres-one namespace: labelteam @@ -36,10 +36,10 @@ metadata: spec: majorVersion: "17" status: - activeInstance: postgres-two + activeBranch: postgres-two --- apiVersion: nais.io/v1 -kind: PostgresInstance +kind: PostgresBranch metadata: name: postgres-two namespace: labelteam @@ -64,10 +64,10 @@ metadata: spec: majorVersion: "17" status: - activeInstance: postgres-three + activeBranch: postgres-three --- apiVersion: nais.io/v1 -kind: PostgresInstance +kind: PostgresBranch metadata: name: postgres-three namespace: labelteam diff --git a/integration_tests/k8s_resources/postgres_audit_log/dev-gcp/audit-postgres-team/postgres_with_audit.yaml b/integration_tests/k8s_resources/postgres_audit_log/dev-gcp/audit-postgres-team/postgres_with_audit.yaml index 9b5eb3747..de4f81360 100644 --- a/integration_tests/k8s_resources/postgres_audit_log/dev-gcp/audit-postgres-team/postgres_with_audit.yaml +++ b/integration_tests/k8s_resources/postgres_audit_log/dev-gcp/audit-postgres-team/postgres_with_audit.yaml @@ -7,10 +7,10 @@ metadata: spec: majorVersion: "16" status: - activeInstance: audit-enabled + activeBranch: audit-enabled --- apiVersion: nais.io/v1 -kind: PostgresInstance +kind: PostgresBranch metadata: name: audit-enabled namespace: audit-postgres-team diff --git a/integration_tests/k8s_resources/postgres_delete/dev/pg-delete-team/postgres.yaml b/integration_tests/k8s_resources/postgres_branch_delete/dev/pg-delete-team/postgres.yaml similarity index 82% rename from integration_tests/k8s_resources/postgres_delete/dev/pg-delete-team/postgres.yaml rename to integration_tests/k8s_resources/postgres_branch_delete/dev/pg-delete-team/postgres.yaml index 2f42bcc21..b93fc6429 100644 --- a/integration_tests/k8s_resources/postgres_delete/dev/pg-delete-team/postgres.yaml +++ b/integration_tests/k8s_resources/postgres_branch_delete/dev/pg-delete-team/postgres.yaml @@ -6,10 +6,10 @@ metadata: spec: majorVersion: "17" status: - activeInstance: orders-new + activeBranch: orders-new --- apiVersion: nais.io/v1 -kind: PostgresInstance +kind: PostgresBranch metadata: name: orders-new namespace: pg-delete-team @@ -17,7 +17,7 @@ spec: postgres: orders --- apiVersion: nais.io/v1 -kind: PostgresInstance +kind: PostgresBranch metadata: name: orders-old namespace: pg-delete-team diff --git a/integration_tests/k8s_resources/postgres_instances/dev/someteamname/applications.yaml b/integration_tests/k8s_resources/postgres_branches/dev/someteamname/applications.yaml similarity index 100% rename from integration_tests/k8s_resources/postgres_instances/dev/someteamname/applications.yaml rename to integration_tests/k8s_resources/postgres_branches/dev/someteamname/applications.yaml diff --git a/integration_tests/k8s_resources/postgres_instances/dev/someteamname/postgres_another_db.yaml b/integration_tests/k8s_resources/postgres_branches/dev/someteamname/postgres_another_db.yaml similarity index 90% rename from integration_tests/k8s_resources/postgres_instances/dev/someteamname/postgres_another_db.yaml rename to integration_tests/k8s_resources/postgres_branches/dev/someteamname/postgres_another_db.yaml index 0886470fb..07d4c2daa 100644 --- a/integration_tests/k8s_resources/postgres_instances/dev/someteamname/postgres_another_db.yaml +++ b/integration_tests/k8s_resources/postgres_branches/dev/someteamname/postgres_another_db.yaml @@ -7,10 +7,10 @@ metadata: spec: majorVersion: "16" status: - activeInstance: another-db + activeBranch: another-db --- apiVersion: nais.io/v1 -kind: PostgresInstance +kind: PostgresBranch metadata: name: another-db namespace: someteamname diff --git a/integration_tests/k8s_resources/postgres_instances/dev/someteamname/postgres_foobar.yaml b/integration_tests/k8s_resources/postgres_branches/dev/someteamname/postgres_foobar.yaml similarity index 92% rename from integration_tests/k8s_resources/postgres_instances/dev/someteamname/postgres_foobar.yaml rename to integration_tests/k8s_resources/postgres_branches/dev/someteamname/postgres_foobar.yaml index 38b534fae..ab39ed8c6 100644 --- a/integration_tests/k8s_resources/postgres_instances/dev/someteamname/postgres_foobar.yaml +++ b/integration_tests/k8s_resources/postgres_branches/dev/someteamname/postgres_foobar.yaml @@ -11,10 +11,10 @@ spec: memory: 2Gi diskSize: 2Gi status: - activeInstance: foobar + activeBranch: foobar --- apiVersion: nais.io/v1 -kind: PostgresInstance +kind: PostgresBranch metadata: name: foobar namespace: someteamname diff --git a/integration_tests/k8s_resources/postgres_instances/dev/someteamname/postgres_with_audit.yaml b/integration_tests/k8s_resources/postgres_branches/dev/someteamname/postgres_with_audit.yaml similarity index 90% rename from integration_tests/k8s_resources/postgres_instances/dev/someteamname/postgres_with_audit.yaml rename to integration_tests/k8s_resources/postgres_branches/dev/someteamname/postgres_with_audit.yaml index f926335ea..e26582676 100644 --- a/integration_tests/k8s_resources/postgres_instances/dev/someteamname/postgres_with_audit.yaml +++ b/integration_tests/k8s_resources/postgres_branches/dev/someteamname/postgres_with_audit.yaml @@ -7,10 +7,10 @@ metadata: spec: majorVersion: "16" status: - activeInstance: with-audit + activeBranch: with-audit --- apiVersion: nais.io/v1 -kind: PostgresInstance +kind: PostgresBranch metadata: name: with-audit namespace: someteamname diff --git a/integration_tests/k8s_resources/postgres_instances/dev/someteamname/postgres_without_audit.yaml b/integration_tests/k8s_resources/postgres_branches/dev/someteamname/postgres_without_audit.yaml similarity index 90% rename from integration_tests/k8s_resources/postgres_instances/dev/someteamname/postgres_without_audit.yaml rename to integration_tests/k8s_resources/postgres_branches/dev/someteamname/postgres_without_audit.yaml index 0be70c9d0..54da8fd35 100644 --- a/integration_tests/k8s_resources/postgres_instances/dev/someteamname/postgres_without_audit.yaml +++ b/integration_tests/k8s_resources/postgres_branches/dev/someteamname/postgres_without_audit.yaml @@ -7,10 +7,10 @@ metadata: spec: majorVersion: "15" status: - activeInstance: without-audit + activeBranch: without-audit --- apiVersion: nais.io/v1 -kind: PostgresInstance +kind: PostgresBranch metadata: name: without-audit namespace: someteamname diff --git a/integration_tests/k8s_resources/postgres_workloads/dev/postgres-workload-team/resources.yaml b/integration_tests/k8s_resources/postgres_workloads/dev/postgres-workload-team/resources.yaml index e17382fde..93a64c789 100644 --- a/integration_tests/k8s_resources/postgres_workloads/dev/postgres-workload-team/resources.yaml +++ b/integration_tests/k8s_resources/postgres_workloads/dev/postgres-workload-team/resources.yaml @@ -6,7 +6,7 @@ metadata: spec: majorVersion: "17" status: - activeInstance: orders-green + activeBranch: orders-green --- apiVersion: nais.io/v1 kind: Postgres @@ -16,10 +16,10 @@ metadata: spec: majorVersion: "17" status: - activeInstance: reports-recovered + activeBranch: reports-recovered --- apiVersion: nais.io/v1 -kind: PostgresInstance +kind: PostgresBranch metadata: name: orders-green namespace: postgres-workload-team @@ -27,7 +27,7 @@ spec: postgres: orders --- apiVersion: nais.io/v1 -kind: PostgresInstance +kind: PostgresBranch metadata: name: reports-recovered namespace: postgres-workload-team diff --git a/integration_tests/label_selectors.lua b/integration_tests/label_selectors.lua index 20a087769..f32c7b84b 100644 --- a/integration_tests/label_selectors.lua +++ b/integration_tests/label_selectors.lua @@ -139,7 +139,7 @@ Test.gql("Check all Postgres instances (no filter)", function(t) { team(slug: "labelteam") { slug - postgresInstances { + postgresBranches { pageInfo { totalCount } @@ -159,7 +159,7 @@ Test.gql("Check all Postgres instances (no filter)", function(t) data = { team = { slug = "labelteam", - postgresInstances = { + postgresBranches = { pageInfo = { totalCount = 3, }, @@ -195,7 +195,7 @@ Test.gql("Postgres filter by tag=target", function(t) t.query [[ { team(slug: "labelteam") { - postgresInstances(filter: { labels: [{ key: "tag", value: "target" }] }) { + postgresBranches(filter: { labels: [{ key: "tag", value: "target" }] }) { pageInfo { totalCount } @@ -210,7 +210,7 @@ Test.gql("Postgres filter by tag=target", function(t) t.check { data = { team = { - postgresInstances = { + postgresBranches = { pageInfo = { totalCount = 2, }, @@ -229,7 +229,7 @@ Test.gql("Postgres filter by tag=target and priority=high", function(t) t.query [[ { team(slug: "labelteam") { - postgresInstances(filter: { + postgresBranches(filter: { labels: [ { key: "tag", value: "target" }, { key: "priority", value: "high" } @@ -249,7 +249,7 @@ Test.gql("Postgres filter by tag=target and priority=high", function(t) t.check { data = { team = { - postgresInstances = { + postgresBranches = { pageInfo = { totalCount = 1, }, diff --git a/integration_tests/postgres_audit_log.lua b/integration_tests/postgres_audit_log.lua index ae7259636..9de0f3a1e 100644 --- a/integration_tests/postgres_audit_log.lua +++ b/integration_tests/postgres_audit_log.lua @@ -1,5 +1,5 @@ -- The old per-instance audit flag and Cloud SQL Logs URL are not part of --- nais.io/v1 PostgresInstance. Verify logical configuration instead. +-- nais.io/v1 PostgresBranch. Verify logical configuration instead. Helper.readK8sResources("k8s_resources/postgres_audit_log") local user = User.new("authenticated", "postgres-audit-user@example.com", "postgres-audit-user-id") local team = Team.new("audit-postgres-team", "Testing logical Postgres", "#audit-postgres") @@ -8,9 +8,9 @@ team:addMember(user) Test.gql("Logical Postgres settings are not fabricated on physical instances", function(t) t.addHeader("x-user-email", user:email()) t.query [[{ team(slug:"audit-postgres-team") { environment(name:"dev-gcp") { - postgresInstance(name:"audit-enabled") { name state postgres { name majorVersion } } + postgresBranch(name:"audit-enabled") { name state postgres { name majorVersion } } } } }]] - t.check { data = { team = { environment = { postgresInstance = { + t.check { data = { team = { environment = { postgresBranch = { name = "audit-enabled", state = "AVAILABLE", postgres = { name = "audit-enabled", majorVersion = "16" }, } } } } } end) diff --git a/integration_tests/postgres_branch_delete.lua b/integration_tests/postgres_branch_delete.lua new file mode 100644 index 000000000..df82d8e1a --- /dev/null +++ b/integration_tests/postgres_branch_delete.lua @@ -0,0 +1,20 @@ +local user = User.new("postgres-delete-user", "postgres-delete-user@usersen.com") +local team = Team.new("pg-delete-team", "Testing PostgresBranch deletion", "#postgres-delete") +team:addMember(user) +Helper.readK8sResources("k8s_resources/postgres_branch_delete") + +Test.gql("Active PostgresBranch cannot be marked for deletion", function(t) + t.addHeader("x-user-email", user:email()) + t.query [[mutation { deletePostgresBranch(input: { + name: "orders-new", environmentName: "dev", teamSlug: "pg-delete-team" + }) { postgresBranchDeleted } }]] + t.check { errors = { { locations = NotNull(), path = { "deletePostgresBranch" }, message = Contains("is active and cannot be deleted") } }, data = Null } +end) + +Test.gql("Inactive PostgresBranch can be deleted", function(t) + t.addHeader("x-user-email", user:email()) + t.query [[mutation { deletePostgresBranch(input: { + name: "orders-old", environmentName: "dev", teamSlug: "pg-delete-team" + }) { postgresBranchDeleted } }]] + t.check { data = { deletePostgresBranch = { postgresBranchDeleted = true } } } +end) diff --git a/integration_tests/postgres_branches.lua b/integration_tests/postgres_branches.lua new file mode 100644 index 000000000..5d6ba9a5e --- /dev/null +++ b/integration_tests/postgres_branches.lua @@ -0,0 +1,63 @@ +local user = User.new("user", "user@usersen.com") +local nonMember = User.new("nonmember", "not@usersen.com") +local team = Team.new("someteamname", "purpose", "#slack_channel") +team:addMember(user) +Helper.readK8sResources("k8s_resources/postgres_branches") + +Test.gql("List concrete PostgresBranches with their logical owners", function(t) + t.addHeader("x-user-email", user:email()) + t.query [[{ team(slug: "someteamname") { postgresBranches(orderBy: {field: NAME, direction: ASC}) { + nodes { name state postgres { name majorVersion activeBranch } } + } } }]] + t.check { data = { team = { postgresBranches = { nodes = { + { name = "another-db", state = "AVAILABLE", postgres = { name = "another-db", majorVersion = "16", activeBranch = "another-db" } }, + { name = "foobar", state = "AVAILABLE", postgres = { name = "foobar", majorVersion = "17", activeBranch = "foobar" } }, + { name = "with-audit", state = "AVAILABLE", postgres = { name = "with-audit", majorVersion = "16", activeBranch = "with-audit" } }, + { name = "without-audit", state = "AVAILABLE", postgres = { name = "without-audit", majorVersion = "15", activeBranch = "without-audit" } }, + } } } } } +end) + +Test.gql("Retrieve logical Postgres and selected physical instance separately", function(t) + t.addHeader("x-user-email", user:email()) + t.query [[{ team(slug:"someteamname") { environment(name:"dev") { + postgres(name:"foobar") { name activeBranch majorVersion highAvailability resources { cpu memory diskSize } } + postgresBranch(name:"foobar") { name postgres { name } teamEnvironment { name } } + } } }]] + t.check { data = { team = { environment = { + postgres = { name = "foobar", activeBranch = "foobar", majorVersion = "17", highAvailability = false, resources = { cpu = "100m", memory = "2Gi", diskSize = "2Gi" } }, + postgresBranch = { name = "foobar", postgres = { name = "foobar" }, teamEnvironment = { name = "dev" } }, + } } } } +end) + +Test.gql("Physical instances may be filtered by observed state", function(t) + t.addHeader("x-user-email", user:email()) + t.query [[{ team(slug:"someteamname") { postgresBranches(filter: {states:[AVAILABLE]}) { + nodes { name } facets { states { state count } } + } } }]] + t.check { data = { team = { postgresBranches = { + nodes = { { name = "another-db" }, { name = "foobar" }, { name = "with-audit" }, { name = "without-audit" } }, + facets = { states = { { state = "AVAILABLE", count = 4 } } }, + } } } } +end) + +Test.gql("A workload follows the active physical instance", function(t) + t.addHeader("x-user-email", user:email()) + t.query [[{ team(slug:"someteamname") { environment(name:"dev") { + application(name:"app-with-postgres") { postgresBranches { nodes { name postgres { name } } } } + postgresBranch(name:"foobar") { workloads { nodes { __typename name } } } + } } }]] + t.check { data = { team = { environment = { + application = { postgresBranches = { nodes = { { name = "foobar", postgres = { name = "foobar" } } } } }, + postgresBranch = { workloads = { nodes = { + { __typename = "Application", name = "app-with-postgres" }, + { __typename = "Application", name = "app-with-postgres-2" }, + { __typename = "Job", name = "job-with-postgres" }, + } } }, + } } } } +end) + +Test.gql("Delete a concrete PostgresBranch requires authorization", function(t) + t.addHeader("x-user-email", nonMember:email()) + t.query [[mutation { deletePostgresBranch(input:{name:"foobar",environmentName:"dev",teamSlug:"someteamname"}) { postgresBranchDeleted } }]] + t.check { errors = { { locations = NotNull(), message = Contains('postgres:delete'), path = { "deletePostgresBranch" } } }, data = Null } +end) diff --git a/integration_tests/postgres_delete.lua b/integration_tests/postgres_delete.lua deleted file mode 100644 index d0bf6b416..000000000 --- a/integration_tests/postgres_delete.lua +++ /dev/null @@ -1,20 +0,0 @@ -local user = User.new("postgres-delete-user", "postgres-delete-user@usersen.com") -local team = Team.new("pg-delete-team", "Testing PostgresInstance deletion", "#postgres-delete") -team:addMember(user) -Helper.readK8sResources("k8s_resources/postgres_delete") - -Test.gql("Active PostgresInstance cannot be marked for deletion", function(t) - t.addHeader("x-user-email", user:email()) - t.query [[mutation { deletePostgres(input: { - name: "orders-new", environmentName: "dev", teamSlug: "pg-delete-team" - }) { postgresDeleted } }]] - t.check { errors = { { locations = NotNull(), path = { "deletePostgres" }, message = Contains("is active and cannot be deleted") } }, data = Null } -end) - -Test.gql("Inactive PostgresInstance can be deleted", function(t) - t.addHeader("x-user-email", user:email()) - t.query [[mutation { deletePostgres(input: { - name: "orders-old", environmentName: "dev", teamSlug: "pg-delete-team" - }) { postgresDeleted } }]] - t.check { data = { deletePostgres = { postgresDeleted = true } } } -end) diff --git a/integration_tests/postgres_instances.lua b/integration_tests/postgres_instances.lua deleted file mode 100644 index 8d5f80c0c..000000000 --- a/integration_tests/postgres_instances.lua +++ /dev/null @@ -1,63 +0,0 @@ -local user = User.new("user", "user@usersen.com") -local nonMember = User.new("nonmember", "not@usersen.com") -local team = Team.new("someteamname", "purpose", "#slack_channel") -team:addMember(user) -Helper.readK8sResources("k8s_resources/postgres_instances") - -Test.gql("List concrete PostgresInstances with their logical owners", function(t) - t.addHeader("x-user-email", user:email()) - t.query [[{ team(slug: "someteamname") { postgresInstances(orderBy: {field: NAME, direction: ASC}) { - nodes { name state postgres { name majorVersion activeInstance } } - } } }]] - t.check { data = { team = { postgresInstances = { nodes = { - { name = "another-db", state = "AVAILABLE", postgres = { name = "another-db", majorVersion = "16", activeInstance = "another-db" } }, - { name = "foobar", state = "AVAILABLE", postgres = { name = "foobar", majorVersion = "17", activeInstance = "foobar" } }, - { name = "with-audit", state = "AVAILABLE", postgres = { name = "with-audit", majorVersion = "16", activeInstance = "with-audit" } }, - { name = "without-audit", state = "AVAILABLE", postgres = { name = "without-audit", majorVersion = "15", activeInstance = "without-audit" } }, - } } } } } -end) - -Test.gql("Retrieve logical Postgres and selected physical instance separately", function(t) - t.addHeader("x-user-email", user:email()) - t.query [[{ team(slug:"someteamname") { environment(name:"dev") { - postgres(name:"foobar") { name activeInstance majorVersion highAvailability resources { cpu memory diskSize } } - postgresInstance(name:"foobar") { name postgres { name } teamEnvironment { name } } - } } }]] - t.check { data = { team = { environment = { - postgres = { name = "foobar", activeInstance = "foobar", majorVersion = "17", highAvailability = false, resources = { cpu = "100m", memory = "2Gi", diskSize = "2Gi" } }, - postgresInstance = { name = "foobar", postgres = { name = "foobar" }, teamEnvironment = { name = "dev" } }, - } } } } -end) - -Test.gql("Physical instances may be filtered by observed state", function(t) - t.addHeader("x-user-email", user:email()) - t.query [[{ team(slug:"someteamname") { postgresInstances(filter: {states:[AVAILABLE]}) { - nodes { name } facets { states { state count } } - } } }]] - t.check { data = { team = { postgresInstances = { - nodes = { { name = "another-db" }, { name = "foobar" }, { name = "with-audit" }, { name = "without-audit" } }, - facets = { states = { { state = "AVAILABLE", count = 4 } } }, - } } } } -end) - -Test.gql("A workload follows the active physical instance", function(t) - t.addHeader("x-user-email", user:email()) - t.query [[{ team(slug:"someteamname") { environment(name:"dev") { - application(name:"app-with-postgres") { postgresInstances { nodes { name postgres { name } } } } - postgresInstance(name:"foobar") { workloads { nodes { __typename name } } } - } } }]] - t.check { data = { team = { environment = { - application = { postgresInstances = { nodes = { { name = "foobar", postgres = { name = "foobar" } } } } }, - postgresInstance = { workloads = { nodes = { - { __typename = "Application", name = "app-with-postgres" }, - { __typename = "Application", name = "app-with-postgres-2" }, - { __typename = "Job", name = "job-with-postgres" }, - } } }, - } } } } -end) - -Test.gql("Delete a concrete PostgresInstance requires authorization", function(t) - t.addHeader("x-user-email", nonMember:email()) - t.query [[mutation { deletePostgres(input:{name:"foobar",environmentName:"dev",teamSlug:"someteamname"}) { postgresDeleted } }]] - t.check { errors = { { locations = NotNull(), message = Contains('postgres:delete'), path = { "deletePostgres" } } }, data = Null } -end) diff --git a/integration_tests/postgres_workloads.lua b/integration_tests/postgres_workloads.lua index 3286ce062..f2a1ed8e6 100644 --- a/integration_tests/postgres_workloads.lua +++ b/integration_tests/postgres_workloads.lua @@ -6,31 +6,31 @@ Helper.readK8sResources("k8s_resources/postgres_workloads") Test.gql("Application and job resolve every uses.postgres entry to its selected instance", function(t) t.addHeader("x-user-email", user:email()) t.query [[{ team(slug: "postgres-workload-team") { environment(name: "dev") { - application(name: "consumer") { postgresInstances { nodes { name postgres { name } } } } - job(name: "scheduled-reader") { postgresInstances { nodes { name postgres { name } } } } + application(name: "consumer") { postgresBranches { nodes { name postgres { name } } } } + job(name: "scheduled-reader") { postgresBranches { nodes { name postgres { name } } } } } } }]] local instances = { { name = "orders-green", postgres = { name = "orders" } }, { name = "reports-recovered", postgres = { name = "reports" } }, } t.check { data = { team = { environment = { - application = { postgresInstances = { nodes = instances } }, - job = { postgresInstances = { nodes = instances } }, + application = { postgresBranches = { nodes = instances } }, + job = { postgresBranches = { nodes = instances } }, } } } } end) -Test.gql("PostgresInstance workloads reference its Postgres through uses.postgres", function(t) +Test.gql("PostgresBranch workloads reference its Postgres through uses.postgres", function(t) t.addHeader("x-user-email", user:email()) t.query [[{ team(slug: "postgres-workload-team") { environment(name: "dev") { - postgresInstance(name: "orders-green") { workloads { nodes { __typename name } } } - other: postgresInstance(name: "reports-recovered") { workloads { nodes { __typename name } } } + postgresBranch(name: "orders-green") { workloads { nodes { __typename name } } } + other: postgresBranch(name: "reports-recovered") { workloads { nodes { __typename name } } } } } }]] local workloads = { { __typename = "Application", name = "consumer" }, { __typename = "Job", name = "scheduled-reader" }, } t.check { data = { team = { environment = { - postgresInstance = { workloads = { nodes = workloads } }, + postgresBranch = { workloads = { nodes = workloads } }, other = { workloads = { nodes = workloads } }, } } } } end) diff --git a/internal/cmd/api/api.go b/internal/cmd/api/api.go index 0735961f5..e33861cea 100644 --- a/internal/cmd/api/api.go +++ b/internal/cmd/api/api.go @@ -393,7 +393,7 @@ func run(ctx context.Context, cfg *Config, log logrus.FieldLogger) error { }) wg.Go(func() error { - if err := grpc.Run(ctx, cfg.GRPCListenAddress, pool, watchers.SqlDatabaseWatcher, watchers.PostgresWatcher, log.WithField("subsystem", "grpc")); err != nil { + if err := grpc.Run(ctx, cfg.GRPCListenAddress, pool, watchers.SqlDatabaseWatcher, watchers.PostgresBranchWatcher, log.WithField("subsystem", "grpc")); err != nil { log.WithError(err).Errorf("error in GRPC server") return err } diff --git a/internal/cmd/api/http.go b/internal/cmd/api/http.go index 34a454ccd..b75259623 100644 --- a/internal/cmd/api/http.go +++ b/internal/cmd/api/http.go @@ -232,7 +232,7 @@ func ConfigureGraph( kafkatopic.AddSearch(searcher, watchers.KafkaTopicWatcher) opensearch.AddSearch(searcher, watchers.OpenSearchWatcher) sqlinstance.AddSearchSQLInstance(searcher, watchers.SqlInstanceWatcher) - postgres.AddSearchPostgres(searcher, watchers.PostgresWatcher) + postgres.AddSearchPostgresBranch(searcher, watchers.PostgresBranchWatcher) valkey.AddSearch(searcher, watchers.ValkeyWatcher) team.AddSearch(searcher, pool, notifier, log.WithField("subsystem", "team_search")) return nil @@ -355,7 +355,7 @@ func ConfigureGraph( ctx = alerts.NewLoaderContext(ctx, prometheusClient, log) ctx = metrics.NewLoaderContext(ctx, prometheusClient, log) ctx = sqlinstance.NewLoaderContext(ctx, sqlAdminService, watchers.SqlDatabaseWatcher, watchers.SqlInstanceWatcher, auditLogProjectID, auditLogLocation) - ctx = postgres.NewLoaderContext(ctx, watchers.PostgresWatcher, auditLogProjectID, auditLogLocation, tenantName) + ctx = postgres.NewLoaderContext(ctx, watchers.PostgresBranchWatcher, auditLogProjectID, auditLogLocation, tenantName, dynamicClients) ctx = aivencredentials.NewClientContext(ctx, dynamicClients, log) ctx = database.NewLoaderContext(ctx, pool) ctx = issue.NewContext(ctx, pool) diff --git a/internal/graph/gengql/applications.generated.go b/internal/graph/gengql/applications.generated.go index dcbe7a6e2..f5760a559 100644 --- a/internal/graph/gengql/applications.generated.go +++ b/internal/graph/gengql/applications.generated.go @@ -68,7 +68,7 @@ type ApplicationResolver interface { LogDestinations(ctx context.Context, obj *application.Application) ([]logging.LogDestination, error) NetworkPolicy(ctx context.Context, obj *application.Application) (*netpol.NetworkPolicy, error) OpenSearch(ctx context.Context, obj *application.Application) (*opensearch.OpenSearch, error) - PostgresInstances(ctx context.Context, obj *application.Application, orderBy *postgres.PostgresInstanceOrder) (*pagination.FacetableConnection[*postgres.PostgresInstance, *postgres.PostgresInstanceFilter], error) + PostgresBranches(ctx context.Context, obj *application.Application, orderBy *postgres.PostgresBranchOrder) (*pagination.FacetableConnection[*postgres.PostgresBranch, *postgres.PostgresBranchFilter], error) Secrets(ctx context.Context, obj *application.Application, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor) (*pagination.FacetableConnection[*secret.Secret, *secret.SecretFilter], error) ServiceAccount(ctx context.Context, obj *application.Application) (*serviceaccount.ServiceAccount, error) SQLInstances(ctx context.Context, obj *application.Application, orderBy *sqlinstance.SQLInstanceOrder) (*pagination.Connection[*sqlinstance.SQLInstance], error) @@ -384,12 +384,12 @@ func (ec *executionContext) field_Application_kafkaTopicAcls_args(ctx context.Co return args, nil } -func (ec *executionContext) field_Application_postgresInstances_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { +func (ec *executionContext) field_Application_postgresBranches_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} arg0, err := graphql.ProcessArgField(ctx, rawArgs, "orderBy", - func(ctx context.Context, v any) (*postgres.PostgresInstanceOrder, error) { - return ec.unmarshalOPostgresInstanceOrder2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceOrder(ctx, v) + func(ctx context.Context, v any) (*postgres.PostgresBranchOrder, error) { + return ec.unmarshalOPostgresBranchOrder2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresBranchOrder(ctx, v) }) if err != nil { return nil, err @@ -1369,34 +1369,34 @@ func (ec *executionContext) fieldContext_Application_openSearch(_ context.Contex return fc, nil } -func (ec *executionContext) _Application_postgresInstances(ctx context.Context, field graphql.CollectedField, obj *application.Application) (ret graphql.Marshaler) { +func (ec *executionContext) _Application_postgresBranches(ctx context.Context, field graphql.CollectedField, obj *application.Application) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_Application_postgresInstances(ctx, field) + return ec.fieldContext_Application_postgresBranches(ctx, field) }, func(ctx context.Context) (any, error) { fc := graphql.GetFieldContext(ctx) - return ec.Resolvers.Application().PostgresInstances(ctx, obj, fc.Args["orderBy"].(*postgres.PostgresInstanceOrder)) + return ec.Resolvers.Application().PostgresBranches(ctx, obj, fc.Args["orderBy"].(*postgres.PostgresBranchOrder)) }, nil, - func(ctx context.Context, selections ast.SelectionSet, v *pagination.FacetableConnection[*postgres.PostgresInstance, *postgres.PostgresInstanceFilter]) graphql.Marshaler { - return ec.marshalNPostgresInstanceConnection2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋpaginationᚐFacetableConnection(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *pagination.FacetableConnection[*postgres.PostgresBranch, *postgres.PostgresBranchFilter]) graphql.Marshaler { + return ec.marshalNPostgresBranchConnection2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋpaginationᚐFacetableConnection(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_Application_postgresInstances(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_Application_postgresBranches(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "Application", Field: field, IsMethod: true, IsResolver: true, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_PostgresInstanceConnection(ctx, field) + return ec.childFields_PostgresBranchConnection(ctx, field) }, } defer func() { @@ -1406,7 +1406,7 @@ func (ec *executionContext) fieldContext_Application_postgresInstances(ctx conte } }() ctx = graphql.WithFieldContext(ctx, fc) - if fc.Args, err = ec.field_Application_postgresInstances_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + if fc.Args, err = ec.field_Application_postgresBranches_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { ec.Error(ctx, err) return fc, err } @@ -5462,7 +5462,7 @@ func (ec *executionContext) _Application(ctx context.Context, sel ast.SelectionS } out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) - case "postgresInstances": + case "postgresBranches": field := field innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { @@ -5471,7 +5471,7 @@ func (ec *executionContext) _Application(ctx context.Context, sel ast.SelectionS ec.Error(ctx, ec.Recover(ctx, r)) } }() - res = ec._Application_postgresInstances(ctx, field, obj) + res = ec._Application_postgresBranches(ctx, field, obj) if res == graphql.Null { atomic.AddUint32(&fs.Invalids, 1) } diff --git a/internal/graph/gengql/complexity.go b/internal/graph/gengql/complexity.go index 9031a405c..fae59df66 100644 --- a/internal/graph/gengql/complexity.go +++ b/internal/graph/gengql/complexity.go @@ -121,7 +121,7 @@ func NewComplexityRoot() ComplexityRoot { c.OpenSearchMaintenance.Updates = func(childComplexity int, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor) int { return cursorComplexity(first, last) * childComplexity } - c.PostgresInstance.Workloads = func(childComplexity int, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor) int { + c.PostgresBranch.Workloads = func(childComplexity int, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor) int { return cursorComplexity(first, last) * childComplexity } c.Query.ActivityLog = func(childComplexity int, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, filter *activitylog.ActivityLogFilter) int { @@ -229,7 +229,7 @@ func NewComplexityRoot() ComplexityRoot { c.Team.OpenSearches = func(childComplexity int, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *opensearch.OpenSearchOrder, filter *opensearch.OpenSearchFilter) int { return cursorComplexity(first, last) * childComplexity } - c.Team.PostgresInstances = func(childComplexity int, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *postgres.PostgresInstanceOrder, filter *postgres.PostgresInstanceFilter) int { + c.Team.PostgresBranches = func(childComplexity int, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *postgres.PostgresBranchOrder, filter *postgres.PostgresBranchFilter) int { return cursorComplexity(first, last) * childComplexity } c.Team.Repositories = func(childComplexity int, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *repository.RepositoryOrder, filter *repository.TeamRepositoryFilter) int { diff --git a/internal/graph/gengql/jobs.generated.go b/internal/graph/gengql/jobs.generated.go index b78204420..c39912a92 100644 --- a/internal/graph/gengql/jobs.generated.go +++ b/internal/graph/gengql/jobs.generated.go @@ -70,7 +70,7 @@ type JobResolver interface { LogDestinations(ctx context.Context, obj *job.Job) ([]logging.LogDestination, error) NetworkPolicy(ctx context.Context, obj *job.Job) (*netpol.NetworkPolicy, error) OpenSearch(ctx context.Context, obj *job.Job) (*opensearch.OpenSearch, error) - PostgresInstances(ctx context.Context, obj *job.Job, orderBy *postgres.PostgresInstanceOrder) (*pagination.FacetableConnection[*postgres.PostgresInstance, *postgres.PostgresInstanceFilter], error) + PostgresBranches(ctx context.Context, obj *job.Job, orderBy *postgres.PostgresBranchOrder) (*pagination.FacetableConnection[*postgres.PostgresBranch, *postgres.PostgresBranchFilter], error) Secrets(ctx context.Context, obj *job.Job, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor) (*pagination.FacetableConnection[*secret.Secret, *secret.SecretFilter], error) ServiceAccount(ctx context.Context, obj *job.Job) (*serviceaccount.ServiceAccount, error) SQLInstances(ctx context.Context, obj *job.Job, orderBy *sqlinstance.SQLInstanceOrder) (*pagination.Connection[*sqlinstance.SQLInstance], error) @@ -366,12 +366,12 @@ func (ec *executionContext) field_Job_kafkaTopicAcls_args(ctx context.Context, r return args, nil } -func (ec *executionContext) field_Job_postgresInstances_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { +func (ec *executionContext) field_Job_postgresBranches_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} arg0, err := graphql.ProcessArgField(ctx, rawArgs, "orderBy", - func(ctx context.Context, v any) (*postgres.PostgresInstanceOrder, error) { - return ec.unmarshalOPostgresInstanceOrder2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceOrder(ctx, v) + func(ctx context.Context, v any) (*postgres.PostgresBranchOrder, error) { + return ec.unmarshalOPostgresBranchOrder2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresBranchOrder(ctx, v) }) if err != nil { return nil, err @@ -1435,34 +1435,34 @@ func (ec *executionContext) fieldContext_Job_openSearch(_ context.Context, field return fc, nil } -func (ec *executionContext) _Job_postgresInstances(ctx context.Context, field graphql.CollectedField, obj *job.Job) (ret graphql.Marshaler) { +func (ec *executionContext) _Job_postgresBranches(ctx context.Context, field graphql.CollectedField, obj *job.Job) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_Job_postgresInstances(ctx, field) + return ec.fieldContext_Job_postgresBranches(ctx, field) }, func(ctx context.Context) (any, error) { fc := graphql.GetFieldContext(ctx) - return ec.Resolvers.Job().PostgresInstances(ctx, obj, fc.Args["orderBy"].(*postgres.PostgresInstanceOrder)) + return ec.Resolvers.Job().PostgresBranches(ctx, obj, fc.Args["orderBy"].(*postgres.PostgresBranchOrder)) }, nil, - func(ctx context.Context, selections ast.SelectionSet, v *pagination.FacetableConnection[*postgres.PostgresInstance, *postgres.PostgresInstanceFilter]) graphql.Marshaler { - return ec.marshalNPostgresInstanceConnection2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋpaginationᚐFacetableConnection(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *pagination.FacetableConnection[*postgres.PostgresBranch, *postgres.PostgresBranchFilter]) graphql.Marshaler { + return ec.marshalNPostgresBranchConnection2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋpaginationᚐFacetableConnection(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_Job_postgresInstances(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_Job_postgresBranches(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "Job", Field: field, IsMethod: true, IsResolver: true, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_PostgresInstanceConnection(ctx, field) + return ec.childFields_PostgresBranchConnection(ctx, field) }, } defer func() { @@ -1472,7 +1472,7 @@ func (ec *executionContext) fieldContext_Job_postgresInstances(ctx context.Conte } }() ctx = graphql.WithFieldContext(ctx, fc) - if fc.Args, err = ec.field_Job_postgresInstances_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + if fc.Args, err = ec.field_Job_postgresBranches_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { ec.Error(ctx, err) return fc, err } @@ -5488,7 +5488,7 @@ func (ec *executionContext) _Job(ctx context.Context, sel ast.SelectionSet, obj } out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) - case "postgresInstances": + case "postgresBranches": field := field innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { @@ -5497,7 +5497,7 @@ func (ec *executionContext) _Job(ctx context.Context, sel ast.SelectionSet, obj ec.Error(ctx, ec.Recover(ctx, r)) } }() - res = ec._Job_postgresInstances(ctx, field, obj) + res = ec._Job_postgresBranches(ctx, field, obj) if res == graphql.Null { atomic.AddUint32(&fs.Invalids, 1) } diff --git a/internal/graph/gengql/persistence.generated.go b/internal/graph/gengql/persistence.generated.go index e8ca691e7..273558efc 100644 --- a/internal/graph/gengql/persistence.generated.go +++ b/internal/graph/gengql/persistence.generated.go @@ -72,13 +72,13 @@ func (ec *executionContext) _Persistence(ctx context.Context, sel ast.SelectionS return graphql.Null } return ec._SqlDatabase(ctx, sel, obj) - case postgres.PostgresInstance: - return ec._PostgresInstance(ctx, sel, &obj) - case *postgres.PostgresInstance: + case postgres.PostgresBranch: + return ec._PostgresBranch(ctx, sel, &obj) + case *postgres.PostgresBranch: if obj == nil { return graphql.Null } - return ec._PostgresInstance(ctx, sel, obj) + return ec._PostgresBranch(ctx, sel, obj) case kafkatopic.KafkaTopic: return ec._KafkaTopic(ctx, sel, &obj) case *kafkatopic.KafkaTopic: diff --git a/internal/graph/gengql/postgres.generated.go b/internal/graph/gengql/postgres.generated.go index 7b3d56582..bd456270f 100644 --- a/internal/graph/gengql/postgres.generated.go +++ b/internal/graph/gengql/postgres.generated.go @@ -28,25 +28,25 @@ import ( type PostgresAccessResolver interface { Team(ctx context.Context, obj *postgres.PostgresAccess) (*team.Team, error) TeamEnvironment(ctx context.Context, obj *postgres.PostgresAccess) (*team.TeamEnvironment, error) - PostgresInstance(ctx context.Context, obj *postgres.PostgresAccess) (*postgres.PostgresInstance, error) + PostgresBranch(ctx context.Context, obj *postgres.PostgresAccess) (*postgres.PostgresBranch, error) Connection(ctx context.Context, obj *postgres.PostgresAccess) (*postgres.PostgresAccessConnectionDetails, error) } -type PostgresInstanceResolver interface { - Team(ctx context.Context, obj *postgres.PostgresInstance) (*team.Team, error) - TeamEnvironment(ctx context.Context, obj *postgres.PostgresInstance) (*team.TeamEnvironment, error) - Postgres(ctx context.Context, obj *postgres.PostgresInstance) (*postgres.Postgres, error) - Workloads(ctx context.Context, obj *postgres.PostgresInstance, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor) (*pagination.Connection[workload.Workload], error) +type PostgresBranchResolver interface { + Team(ctx context.Context, obj *postgres.PostgresBranch) (*team.Team, error) + TeamEnvironment(ctx context.Context, obj *postgres.PostgresBranch) (*team.TeamEnvironment, error) + Postgres(ctx context.Context, obj *postgres.PostgresBranch) (*postgres.Postgres, error) + Workloads(ctx context.Context, obj *postgres.PostgresBranch, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor) (*pagination.Connection[workload.Workload], error) } -type PostgresInstanceConnectionResolver interface { - Facets(ctx context.Context, obj *pagination.FacetableConnection[*postgres.PostgresInstance, *postgres.PostgresInstanceFilter]) (*postgres.PostgresInstanceFacets, error) +type PostgresBranchConnectionResolver interface { + Facets(ctx context.Context, obj *pagination.FacetableConnection[*postgres.PostgresBranch, *postgres.PostgresBranchFilter]) (*postgres.PostgresBranchFacets, error) } // endregion ************************** generated!.gotpl ************************** // region ***************************** args.gotpl ***************************** -func (ec *executionContext) field_PostgresInstance_workloads_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { +func (ec *executionContext) field_PostgresBranch_workloads_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} arg0, err := graphql.ProcessArgField(ctx, rawArgs, "first", @@ -138,16 +138,16 @@ func (ec *executionContext) fieldContext_CreatePostgresAccessPayload_expiresAt(_ return graphql.NewScalarFieldContext("CreatePostgresAccessPayload", field, false, false, errors.New("field of type Time does not have child fields")) } -func (ec *executionContext) _DeletePostgresPayload_postgresDeleted(ctx context.Context, field graphql.CollectedField, obj *postgres.DeletePostgresPayload) (ret graphql.Marshaler) { +func (ec *executionContext) _DeletePostgresBranchPayload_postgresBranchDeleted(ctx context.Context, field graphql.CollectedField, obj *postgres.DeletePostgresBranchPayload) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_DeletePostgresPayload_postgresDeleted(ctx, field) + return ec.fieldContext_DeletePostgresBranchPayload_postgresBranchDeleted(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.PostgresDeleted, nil + return obj.PostgresBranchDeleted, nil }, nil, func(ctx context.Context, selections ast.SelectionSet, v *bool) graphql.Marshaler { @@ -157,8 +157,8 @@ func (ec *executionContext) _DeletePostgresPayload_postgresDeleted(ctx context.C false, ) } -func (ec *executionContext) fieldContext_DeletePostgresPayload_postgresDeleted(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("DeletePostgresPayload", field, false, false, errors.New("field of type Boolean does not have child fields")) +func (ec *executionContext) fieldContext_DeletePostgresBranchPayload_postgresBranchDeleted(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("DeletePostgresBranchPayload", field, false, false, errors.New("field of type Boolean does not have child fields")) } func (ec *executionContext) _GrantPostgresAccessPayload_error(ctx context.Context, field graphql.CollectedField, obj *postgres.GrantPostgresAccessPayload) (ret graphql.Marshaler) { @@ -308,16 +308,16 @@ func (ec *executionContext) fieldContext_Postgres_resources(_ context.Context, f return fc, nil } -func (ec *executionContext) _Postgres_activeInstance(ctx context.Context, field graphql.CollectedField, obj *postgres.Postgres) (ret graphql.Marshaler) { +func (ec *executionContext) _Postgres_activeBranch(ctx context.Context, field graphql.CollectedField, obj *postgres.Postgres) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_Postgres_activeInstance(ctx, field) + return ec.fieldContext_Postgres_activeBranch(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.ActiveInstance, nil + return obj.ActiveBranch, nil }, nil, func(ctx context.Context, selections ast.SelectionSet, v *string) graphql.Marshaler { @@ -327,7 +327,7 @@ func (ec *executionContext) _Postgres_activeInstance(ctx context.Context, field false, ) } -func (ec *executionContext) fieldContext_Postgres_activeInstance(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_Postgres_activeBranch(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { return graphql.NewScalarFieldContext("Postgres", field, false, false, errors.New("field of type String does not have child fields")) } @@ -473,33 +473,33 @@ func (ec *executionContext) fieldContext_PostgresAccess_teamEnvironment(_ contex return fc, nil } -func (ec *executionContext) _PostgresAccess_postgresInstance(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccess) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresAccess_postgresBranch(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresAccess) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresAccess_postgresInstance(ctx, field) + return ec.fieldContext_PostgresAccess_postgresBranch(ctx, field) }, func(ctx context.Context) (any, error) { - return ec.Resolvers.PostgresAccess().PostgresInstance(ctx, obj) + return ec.Resolvers.PostgresAccess().PostgresBranch(ctx, obj) }, nil, - func(ctx context.Context, selections ast.SelectionSet, v *postgres.PostgresInstance) graphql.Marshaler { - return ec.marshalNPostgresInstance2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstance(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *postgres.PostgresBranch) graphql.Marshaler { + return ec.marshalNPostgresBranch2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresBranch(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresAccess_postgresInstance(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_PostgresAccess_postgresBranch(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "PostgresAccess", Field: field, IsMethod: true, IsResolver: true, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_PostgresInstance(ctx, field) + return ec.childFields_PostgresBranch(ctx, field) }, } return fc, nil @@ -813,13 +813,13 @@ func (ec *executionContext) fieldContext_PostgresAccessConnectionDetails_relayTo return graphql.NewScalarFieldContext("PostgresAccessConnectionDetails", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresDeletedActivityLogEntry_id(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresDeletedActivityLogEntry) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresBranch_id(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresBranch) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresDeletedActivityLogEntry_id(ctx, field) + return ec.fieldContext_PostgresBranch_id(ctx, field) }, func(ctx context.Context) (any, error) { return obj.ID(), nil @@ -832,20 +832,20 @@ func (ec *executionContext) _PostgresDeletedActivityLogEntry_id(ctx context.Cont true, ) } -func (ec *executionContext) fieldContext_PostgresDeletedActivityLogEntry_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresDeletedActivityLogEntry", field, true, false, errors.New("field of type ID does not have child fields")) +func (ec *executionContext) fieldContext_PostgresBranch_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresBranch", field, true, false, errors.New("field of type ID does not have child fields")) } -func (ec *executionContext) _PostgresDeletedActivityLogEntry_actor(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresDeletedActivityLogEntry) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresBranch_name(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresBranch) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresDeletedActivityLogEntry_actor(ctx, field) + return ec.fieldContext_PostgresBranch_name(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Actor, nil + return obj.Name, nil }, nil, func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { @@ -855,1038 +855,1038 @@ func (ec *executionContext) _PostgresDeletedActivityLogEntry_actor(ctx context.C true, ) } -func (ec *executionContext) fieldContext_PostgresDeletedActivityLogEntry_actor(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresDeletedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) +func (ec *executionContext) fieldContext_PostgresBranch_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresBranch", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresDeletedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresDeletedActivityLogEntry) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresBranch_team(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresBranch) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresDeletedActivityLogEntry_gitHubActorClaims(ctx, field) + return ec.fieldContext_PostgresBranch_team(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.GitHubActorClaims, nil + return ec.Resolvers.PostgresBranch().Team(ctx, obj) }, nil, - func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { - return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *team.Team) graphql.Marshaler { + return ec.marshalNTeam2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋteamᚐTeam(ctx, selections, v) }, true, - false, + true, ) } -func (ec *executionContext) fieldContext_PostgresDeletedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_PostgresBranch_team(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "PostgresDeletedActivityLogEntry", + Object: "PostgresBranch", Field: field, - IsMethod: false, - IsResolver: false, + IsMethod: true, + IsResolver: true, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_GitHubActorClaims(ctx, field) + return ec.childFields_Team(ctx, field) }, } return fc, nil } -func (ec *executionContext) _PostgresDeletedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresDeletedActivityLogEntry) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresBranch_teamEnvironment(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresBranch) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresDeletedActivityLogEntry_createdAt(ctx, field) + return ec.fieldContext_PostgresBranch_teamEnvironment(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.CreatedAt, nil + return ec.Resolvers.PostgresBranch().TeamEnvironment(ctx, obj) }, nil, - func(ctx context.Context, selections ast.SelectionSet, v time.Time) graphql.Marshaler { - return ec.marshalNTime2timeᚐTime(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *team.TeamEnvironment) graphql.Marshaler { + return ec.marshalNTeamEnvironment2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋteamᚐTeamEnvironment(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresDeletedActivityLogEntry_createdAt(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresDeletedActivityLogEntry", field, false, false, errors.New("field of type Time does not have child fields")) +func (ec *executionContext) fieldContext_PostgresBranch_teamEnvironment(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "PostgresBranch", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_TeamEnvironment(ctx, field) + }, + } + return fc, nil } -func (ec *executionContext) _PostgresDeletedActivityLogEntry_message(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresDeletedActivityLogEntry) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresBranch_postgres(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresBranch) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresDeletedActivityLogEntry_message(ctx, field) + return ec.fieldContext_PostgresBranch_postgres(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Message, nil + return ec.Resolvers.PostgresBranch().Postgres(ctx, obj) }, nil, - func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { - return ec.marshalNString2string(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *postgres.Postgres) graphql.Marshaler { + return ec.marshalNPostgres2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgres(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresDeletedActivityLogEntry_message(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresDeletedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) +func (ec *executionContext) fieldContext_PostgresBranch_postgres(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "PostgresBranch", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_Postgres(ctx, field) + }, + } + return fc, nil } -func (ec *executionContext) _PostgresDeletedActivityLogEntry_resourceType(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresDeletedActivityLogEntry) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresBranch_workloads(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresBranch) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresDeletedActivityLogEntry_resourceType(ctx, field) + return ec.fieldContext_PostgresBranch_workloads(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.ResourceType, nil + fc := graphql.GetFieldContext(ctx) + return ec.Resolvers.PostgresBranch().Workloads(ctx, obj, fc.Args["first"].(*int), fc.Args["after"].(*pagination.Cursor), fc.Args["last"].(*int), fc.Args["before"].(*pagination.Cursor)) }, nil, - func(ctx context.Context, selections ast.SelectionSet, v activitylog.ActivityLogEntryResourceType) graphql.Marshaler { - return ec.marshalNActivityLogEntryResourceType2githubᚗcomᚋnaisᚋapiᚋinternalᚋactivitylogᚐActivityLogEntryResourceType(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *pagination.Connection[workload.Workload]) graphql.Marshaler { + return ec.marshalNWorkloadConnection2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋpaginationᚐConnection(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresDeletedActivityLogEntry_resourceType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresDeletedActivityLogEntry", field, false, false, errors.New("field of type ActivityLogEntryResourceType does not have child fields")) +func (ec *executionContext) fieldContext_PostgresBranch_workloads(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "PostgresBranch", + Field: field, + IsMethod: true, + IsResolver: true, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_WorkloadConnection(ctx, field) + }, + } + defer func() { + if r := recover(); r != nil { + err = ec.Recover(ctx, r) + ec.Error(ctx, err) + } + }() + ctx = graphql.WithFieldContext(ctx, fc) + if fc.Args, err = ec.field_PostgresBranch_workloads_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + ec.Error(ctx, err) + return fc, err + } + return fc, nil } -func (ec *executionContext) _PostgresDeletedActivityLogEntry_resourceName(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresDeletedActivityLogEntry) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresBranch_state(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresBranch) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresDeletedActivityLogEntry_resourceName(ctx, field) + return ec.fieldContext_PostgresBranch_state(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.ResourceName, nil + return obj.State, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { - return ec.marshalNString2string(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v postgres.PostgresBranchState) graphql.Marshaler { + return ec.marshalNPostgresBranchState2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresBranchState(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresDeletedActivityLogEntry_resourceName(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresDeletedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) +func (ec *executionContext) fieldContext_PostgresBranch_state(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresBranch", field, false, false, errors.New("field of type PostgresBranchState does not have child fields")) } -func (ec *executionContext) _PostgresDeletedActivityLogEntry_teamSlug(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresDeletedActivityLogEntry) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresBranch_labels(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresBranch) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresDeletedActivityLogEntry_teamSlug(ctx, field) + return ec.fieldContext_PostgresBranch_labels(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.TeamSlug, nil + return obj.Labels, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v *slug.Slug) graphql.Marshaler { - return ec.marshalNSlug2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋslugᚐSlug(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v []*model.ResourceLabel) graphql.Marshaler { + return ec.marshalNResourceLabel2ᚕᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋmodelᚐResourceLabelᚄ(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresDeletedActivityLogEntry_teamSlug(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresDeletedActivityLogEntry", field, false, false, errors.New("field of type Slug does not have child fields")) +func (ec *executionContext) fieldContext_PostgresBranch_labels(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "PostgresBranch", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_ResourceLabel(ctx, field) + }, + } + return fc, nil } -func (ec *executionContext) _PostgresDeletedActivityLogEntry_environmentName(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresDeletedActivityLogEntry) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresBranchConnection_pageInfo(ctx context.Context, field graphql.CollectedField, obj *pagination.FacetableConnection[*postgres.PostgresBranch, *postgres.PostgresBranchFilter]) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresDeletedActivityLogEntry_environmentName(ctx, field) + return ec.fieldContext_PostgresBranchConnection_pageInfo(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.EnvironmentName, nil + return obj.PageInfo, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v *string) graphql.Marshaler { - return ec.marshalOString2ᚖstring(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v pagination.PageInfo) graphql.Marshaler { + return ec.marshalNPageInfo2githubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋpaginationᚐPageInfo(ctx, selections, v) }, true, - false, + true, ) } -func (ec *executionContext) fieldContext_PostgresDeletedActivityLogEntry_environmentName(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresDeletedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) +func (ec *executionContext) fieldContext_PostgresBranchConnection_pageInfo(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "PostgresBranchConnection", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_PageInfo(ctx, field) + }, + } + return fc, nil } -func (ec *executionContext) _PostgresGrantAccessActivityLogEntry_id(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresGrantAccessActivityLogEntry) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresBranchConnection_nodes(ctx context.Context, field graphql.CollectedField, obj *pagination.FacetableConnection[*postgres.PostgresBranch, *postgres.PostgresBranchFilter]) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresGrantAccessActivityLogEntry_id(ctx, field) + return ec.fieldContext_PostgresBranchConnection_nodes(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.ID(), nil + return obj.Nodes(), nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v ident.Ident) graphql.Marshaler { - return ec.marshalNID2githubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋidentᚐIdent(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v []*postgres.PostgresBranch) graphql.Marshaler { + return ec.marshalNPostgresBranch2ᚕᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresBranchᚄ(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresGrantAccessActivityLogEntry_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresGrantAccessActivityLogEntry", field, true, false, errors.New("field of type ID does not have child fields")) +func (ec *executionContext) fieldContext_PostgresBranchConnection_nodes(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "PostgresBranchConnection", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_PostgresBranch(ctx, field) + }, + } + return fc, nil } -func (ec *executionContext) _PostgresGrantAccessActivityLogEntry_actor(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresGrantAccessActivityLogEntry) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresBranchConnection_edges(ctx context.Context, field graphql.CollectedField, obj *pagination.FacetableConnection[*postgres.PostgresBranch, *postgres.PostgresBranchFilter]) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresGrantAccessActivityLogEntry_actor(ctx, field) + return ec.fieldContext_PostgresBranchConnection_edges(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Actor, nil + return obj.Edges, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { - return ec.marshalNString2string(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v []pagination.Edge[*postgres.PostgresBranch]) graphql.Marshaler { + return ec.marshalNPostgresBranchEdge2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋpaginationᚐEdgeᚄ(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresGrantAccessActivityLogEntry_actor(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresGrantAccessActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) +func (ec *executionContext) fieldContext_PostgresBranchConnection_edges(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "PostgresBranchConnection", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_PostgresBranchEdge(ctx, field) + }, + } + return fc, nil } -func (ec *executionContext) _PostgresGrantAccessActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresGrantAccessActivityLogEntry) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresBranchConnection_facets(ctx context.Context, field graphql.CollectedField, obj *pagination.FacetableConnection[*postgres.PostgresBranch, *postgres.PostgresBranchFilter]) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresGrantAccessActivityLogEntry_gitHubActorClaims(ctx, field) + return ec.fieldContext_PostgresBranchConnection_facets(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.GitHubActorClaims, nil + return ec.Resolvers.PostgresBranchConnection().Facets(ctx, obj) }, nil, - func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { - return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *postgres.PostgresBranchFacets) graphql.Marshaler { + return ec.marshalOPostgresBranchFacets2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresBranchFacets(ctx, selections, v) }, true, false, ) } -func (ec *executionContext) fieldContext_PostgresGrantAccessActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_PostgresBranchConnection_facets(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "PostgresGrantAccessActivityLogEntry", + Object: "PostgresBranchConnection", Field: field, - IsMethod: false, - IsResolver: false, + IsMethod: true, + IsResolver: true, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_GitHubActorClaims(ctx, field) + return ec.childFields_PostgresBranchFacets(ctx, field) }, } return fc, nil } -func (ec *executionContext) _PostgresGrantAccessActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresGrantAccessActivityLogEntry) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresBranchEdge_cursor(ctx context.Context, field graphql.CollectedField, obj *pagination.Edge[*postgres.PostgresBranch]) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresGrantAccessActivityLogEntry_createdAt(ctx, field) + return ec.fieldContext_PostgresBranchEdge_cursor(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.CreatedAt, nil + return obj.Cursor, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v time.Time) graphql.Marshaler { - return ec.marshalNTime2timeᚐTime(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v pagination.Cursor) graphql.Marshaler { + return ec.marshalNCursor2githubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋpaginationᚐCursor(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresGrantAccessActivityLogEntry_createdAt(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresGrantAccessActivityLogEntry", field, false, false, errors.New("field of type Time does not have child fields")) +func (ec *executionContext) fieldContext_PostgresBranchEdge_cursor(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresBranchEdge", field, false, false, errors.New("field of type Cursor does not have child fields")) } -func (ec *executionContext) _PostgresGrantAccessActivityLogEntry_message(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresGrantAccessActivityLogEntry) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresBranchEdge_node(ctx context.Context, field graphql.CollectedField, obj *pagination.Edge[*postgres.PostgresBranch]) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresGrantAccessActivityLogEntry_message(ctx, field) + return ec.fieldContext_PostgresBranchEdge_node(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Message, nil + return obj.Node, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { - return ec.marshalNString2string(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *postgres.PostgresBranch) graphql.Marshaler { + return ec.marshalNPostgresBranch2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresBranch(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresGrantAccessActivityLogEntry_message(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresGrantAccessActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) +func (ec *executionContext) fieldContext_PostgresBranchEdge_node(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "PostgresBranchEdge", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_PostgresBranch(ctx, field) + }, + } + return fc, nil } -func (ec *executionContext) _PostgresGrantAccessActivityLogEntry_resourceType(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresGrantAccessActivityLogEntry) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresBranchFacets_environments(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresBranchFacets) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresGrantAccessActivityLogEntry_resourceType(ctx, field) + return ec.fieldContext_PostgresBranchFacets_environments(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.ResourceType, nil + return obj.Environments(ctx), nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v activitylog.ActivityLogEntryResourceType) graphql.Marshaler { - return ec.marshalNActivityLogEntryResourceType2githubᚗcomᚋnaisᚋapiᚋinternalᚋactivitylogᚐActivityLogEntryResourceType(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v []model.StringFacetItem) graphql.Marshaler { + return ec.marshalNStringFacetItem2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋmodelᚐStringFacetItemᚄ(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresGrantAccessActivityLogEntry_resourceType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresGrantAccessActivityLogEntry", field, false, false, errors.New("field of type ActivityLogEntryResourceType does not have child fields")) +func (ec *executionContext) fieldContext_PostgresBranchFacets_environments(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "PostgresBranchFacets", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_StringFacetItem(ctx, field) + }, + } + return fc, nil } -func (ec *executionContext) _PostgresGrantAccessActivityLogEntry_resourceName(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresGrantAccessActivityLogEntry) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresBranchFacets_states(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresBranchFacets) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresGrantAccessActivityLogEntry_resourceName(ctx, field) + return ec.fieldContext_PostgresBranchFacets_states(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.ResourceName, nil + return obj.States(ctx), nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { - return ec.marshalNString2string(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v []postgres.PostgresBranchStateFacetItem) graphql.Marshaler { + return ec.marshalNPostgresBranchStateFacetItem2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresBranchStateFacetItemᚄ(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresGrantAccessActivityLogEntry_resourceName(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresGrantAccessActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) +func (ec *executionContext) fieldContext_PostgresBranchFacets_states(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "PostgresBranchFacets", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_PostgresBranchStateFacetItem(ctx, field) + }, + } + return fc, nil } -func (ec *executionContext) _PostgresGrantAccessActivityLogEntry_teamSlug(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresGrantAccessActivityLogEntry) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresBranchFacets_labels(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresBranchFacets) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresGrantAccessActivityLogEntry_teamSlug(ctx, field) + return ec.fieldContext_PostgresBranchFacets_labels(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.TeamSlug, nil + return obj.Labels(ctx), nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v *slug.Slug) graphql.Marshaler { - return ec.marshalNSlug2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋslugᚐSlug(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v []model.LabelFacetItem) graphql.Marshaler { + return ec.marshalNLabelFacetItem2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋmodelᚐLabelFacetItemᚄ(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresGrantAccessActivityLogEntry_teamSlug(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresGrantAccessActivityLogEntry", field, false, false, errors.New("field of type Slug does not have child fields")) -} +func (ec *executionContext) fieldContext_PostgresBranchFacets_labels(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "PostgresBranchFacets", + Field: field, + IsMethod: true, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_LabelFacetItem(ctx, field) + }, + } + return fc, nil +} -func (ec *executionContext) _PostgresGrantAccessActivityLogEntry_environmentName(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresGrantAccessActivityLogEntry) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresBranchStateFacetItem_state(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresBranchStateFacetItem) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresGrantAccessActivityLogEntry_environmentName(ctx, field) + return ec.fieldContext_PostgresBranchStateFacetItem_state(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.EnvironmentName, nil + return obj.State, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v *string) graphql.Marshaler { - return ec.marshalOString2ᚖstring(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v postgres.PostgresBranchState) graphql.Marshaler { + return ec.marshalNPostgresBranchState2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresBranchState(ctx, selections, v) }, true, - false, + true, ) } -func (ec *executionContext) fieldContext_PostgresGrantAccessActivityLogEntry_environmentName(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresGrantAccessActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) +func (ec *executionContext) fieldContext_PostgresBranchStateFacetItem_state(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresBranchStateFacetItem", field, false, false, errors.New("field of type PostgresBranchState does not have child fields")) } -func (ec *executionContext) _PostgresGrantAccessActivityLogEntry_data(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresGrantAccessActivityLogEntry) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresBranchStateFacetItem_count(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresBranchStateFacetItem) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresGrantAccessActivityLogEntry_data(ctx, field) + return ec.fieldContext_PostgresBranchStateFacetItem_count(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Data, nil + return obj.Count, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v *postgres.PostgresGrantAccessActivityLogEntryData) graphql.Marshaler { - return ec.marshalNPostgresGrantAccessActivityLogEntryData2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresGrantAccessActivityLogEntryData(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v int) graphql.Marshaler { + return ec.marshalNInt2int(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresGrantAccessActivityLogEntry_data(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "PostgresGrantAccessActivityLogEntry", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_PostgresGrantAccessActivityLogEntryData(ctx, field) - }, - } - return fc, nil +func (ec *executionContext) fieldContext_PostgresBranchStateFacetItem_count(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresBranchStateFacetItem", field, false, false, errors.New("field of type Int does not have child fields")) } -func (ec *executionContext) _PostgresGrantAccessActivityLogEntryData_grantee(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresGrantAccessActivityLogEntryData) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresDeletedActivityLogEntry_id(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresDeletedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresGrantAccessActivityLogEntryData_grantee(ctx, field) + return ec.fieldContext_PostgresDeletedActivityLogEntry_id(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Grantee, nil + return obj.ID(), nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { - return ec.marshalNString2string(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v ident.Ident) graphql.Marshaler { + return ec.marshalNID2githubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋidentᚐIdent(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresGrantAccessActivityLogEntryData_grantee(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresGrantAccessActivityLogEntryData", field, false, false, errors.New("field of type String does not have child fields")) +func (ec *executionContext) fieldContext_PostgresDeletedActivityLogEntry_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresDeletedActivityLogEntry", field, true, false, errors.New("field of type ID does not have child fields")) } -func (ec *executionContext) _PostgresGrantAccessActivityLogEntryData_until(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresGrantAccessActivityLogEntryData) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresDeletedActivityLogEntry_actor(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresDeletedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresGrantAccessActivityLogEntryData_until(ctx, field) + return ec.fieldContext_PostgresDeletedActivityLogEntry_actor(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Until, nil + return obj.Actor, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v time.Time) graphql.Marshaler { - return ec.marshalNTime2timeᚐTime(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { + return ec.marshalNString2string(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresGrantAccessActivityLogEntryData_until(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresGrantAccessActivityLogEntryData", field, false, false, errors.New("field of type Time does not have child fields")) +func (ec *executionContext) fieldContext_PostgresDeletedActivityLogEntry_actor(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresDeletedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresInstance_id(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstance) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresDeletedActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresDeletedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstance_id(ctx, field) + return ec.fieldContext_PostgresDeletedActivityLogEntry_gitHubActorClaims(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.ID(), nil + return obj.GitHubActorClaims, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v ident.Ident) graphql.Marshaler { - return ec.marshalNID2githubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋidentᚐIdent(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) }, true, - true, + false, ) } -func (ec *executionContext) fieldContext_PostgresInstance_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresInstance", field, true, false, errors.New("field of type ID does not have child fields")) +func (ec *executionContext) fieldContext_PostgresDeletedActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + fc = &graphql.FieldContext{ + Object: "PostgresDeletedActivityLogEntry", + Field: field, + IsMethod: false, + IsResolver: false, + Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + return ec.childFields_GitHubActorClaims(ctx, field) + }, + } + return fc, nil } -func (ec *executionContext) _PostgresInstance_name(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstance) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresDeletedActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresDeletedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstance_name(ctx, field) + return ec.fieldContext_PostgresDeletedActivityLogEntry_createdAt(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Name, nil + return obj.CreatedAt, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { - return ec.marshalNString2string(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v time.Time) graphql.Marshaler { + return ec.marshalNTime2timeᚐTime(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresInstance_name(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresInstance", field, false, false, errors.New("field of type String does not have child fields")) +func (ec *executionContext) fieldContext_PostgresDeletedActivityLogEntry_createdAt(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresDeletedActivityLogEntry", field, false, false, errors.New("field of type Time does not have child fields")) } -func (ec *executionContext) _PostgresInstance_team(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstance) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresDeletedActivityLogEntry_message(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresDeletedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstance_team(ctx, field) + return ec.fieldContext_PostgresDeletedActivityLogEntry_message(ctx, field) }, func(ctx context.Context) (any, error) { - return ec.Resolvers.PostgresInstance().Team(ctx, obj) + return obj.Message, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v *team.Team) graphql.Marshaler { - return ec.marshalNTeam2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋteamᚐTeam(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { + return ec.marshalNString2string(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresInstance_team(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "PostgresInstance", - Field: field, - IsMethod: true, - IsResolver: true, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_Team(ctx, field) - }, - } - return fc, nil +func (ec *executionContext) fieldContext_PostgresDeletedActivityLogEntry_message(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresDeletedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresInstance_teamEnvironment(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstance) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresDeletedActivityLogEntry_resourceType(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresDeletedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstance_teamEnvironment(ctx, field) + return ec.fieldContext_PostgresDeletedActivityLogEntry_resourceType(ctx, field) }, func(ctx context.Context) (any, error) { - return ec.Resolvers.PostgresInstance().TeamEnvironment(ctx, obj) + return obj.ResourceType, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v *team.TeamEnvironment) graphql.Marshaler { - return ec.marshalNTeamEnvironment2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋteamᚐTeamEnvironment(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v activitylog.ActivityLogEntryResourceType) graphql.Marshaler { + return ec.marshalNActivityLogEntryResourceType2githubᚗcomᚋnaisᚋapiᚋinternalᚋactivitylogᚐActivityLogEntryResourceType(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresInstance_teamEnvironment(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "PostgresInstance", - Field: field, - IsMethod: true, - IsResolver: true, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_TeamEnvironment(ctx, field) - }, - } - return fc, nil +func (ec *executionContext) fieldContext_PostgresDeletedActivityLogEntry_resourceType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresDeletedActivityLogEntry", field, false, false, errors.New("field of type ActivityLogEntryResourceType does not have child fields")) } -func (ec *executionContext) _PostgresInstance_postgres(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstance) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresDeletedActivityLogEntry_resourceName(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresDeletedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstance_postgres(ctx, field) + return ec.fieldContext_PostgresDeletedActivityLogEntry_resourceName(ctx, field) }, func(ctx context.Context) (any, error) { - return ec.Resolvers.PostgresInstance().Postgres(ctx, obj) + return obj.ResourceName, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v *postgres.Postgres) graphql.Marshaler { - return ec.marshalNPostgres2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgres(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { + return ec.marshalNString2string(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresInstance_postgres(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "PostgresInstance", - Field: field, - IsMethod: true, - IsResolver: true, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_Postgres(ctx, field) - }, - } - return fc, nil +func (ec *executionContext) fieldContext_PostgresDeletedActivityLogEntry_resourceName(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresDeletedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresInstance_workloads(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstance) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresDeletedActivityLogEntry_teamSlug(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresDeletedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstance_workloads(ctx, field) + return ec.fieldContext_PostgresDeletedActivityLogEntry_teamSlug(ctx, field) }, func(ctx context.Context) (any, error) { - fc := graphql.GetFieldContext(ctx) - return ec.Resolvers.PostgresInstance().Workloads(ctx, obj, fc.Args["first"].(*int), fc.Args["after"].(*pagination.Cursor), fc.Args["last"].(*int), fc.Args["before"].(*pagination.Cursor)) + return obj.TeamSlug, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v *pagination.Connection[workload.Workload]) graphql.Marshaler { - return ec.marshalNWorkloadConnection2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋpaginationᚐConnection(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *slug.Slug) graphql.Marshaler { + return ec.marshalNSlug2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋslugᚐSlug(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresInstance_workloads(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "PostgresInstance", - Field: field, - IsMethod: true, - IsResolver: true, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_WorkloadConnection(ctx, field) - }, - } - defer func() { - if r := recover(); r != nil { - err = ec.Recover(ctx, r) - ec.Error(ctx, err) - } - }() - ctx = graphql.WithFieldContext(ctx, fc) - if fc.Args, err = ec.field_PostgresInstance_workloads_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { - ec.Error(ctx, err) - return fc, err - } - return fc, nil +func (ec *executionContext) fieldContext_PostgresDeletedActivityLogEntry_teamSlug(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresDeletedActivityLogEntry", field, false, false, errors.New("field of type Slug does not have child fields")) } -func (ec *executionContext) _PostgresInstance_state(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstance) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresDeletedActivityLogEntry_environmentName(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresDeletedActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstance_state(ctx, field) + return ec.fieldContext_PostgresDeletedActivityLogEntry_environmentName(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.State, nil + return obj.EnvironmentName, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v postgres.PostgresInstanceState) graphql.Marshaler { - return ec.marshalNPostgresInstanceState2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceState(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *string) graphql.Marshaler { + return ec.marshalOString2ᚖstring(ctx, selections, v) }, true, - true, + false, ) } -func (ec *executionContext) fieldContext_PostgresInstance_state(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresInstance", field, false, false, errors.New("field of type PostgresInstanceState does not have child fields")) +func (ec *executionContext) fieldContext_PostgresDeletedActivityLogEntry_environmentName(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresDeletedActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresInstance_labels(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstance) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresGrantAccessActivityLogEntry_id(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresGrantAccessActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstance_labels(ctx, field) + return ec.fieldContext_PostgresGrantAccessActivityLogEntry_id(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Labels, nil + return obj.ID(), nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v []*model.ResourceLabel) graphql.Marshaler { - return ec.marshalNResourceLabel2ᚕᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋmodelᚐResourceLabelᚄ(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v ident.Ident) graphql.Marshaler { + return ec.marshalNID2githubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋidentᚐIdent(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresInstance_labels(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "PostgresInstance", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_ResourceLabel(ctx, field) - }, - } - return fc, nil +func (ec *executionContext) fieldContext_PostgresGrantAccessActivityLogEntry_id(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresGrantAccessActivityLogEntry", field, true, false, errors.New("field of type ID does not have child fields")) } -func (ec *executionContext) _PostgresInstanceConnection_pageInfo(ctx context.Context, field graphql.CollectedField, obj *pagination.FacetableConnection[*postgres.PostgresInstance, *postgres.PostgresInstanceFilter]) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresGrantAccessActivityLogEntry_actor(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresGrantAccessActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstanceConnection_pageInfo(ctx, field) + return ec.fieldContext_PostgresGrantAccessActivityLogEntry_actor(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.PageInfo, nil + return obj.Actor, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v pagination.PageInfo) graphql.Marshaler { - return ec.marshalNPageInfo2githubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋpaginationᚐPageInfo(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { + return ec.marshalNString2string(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresInstanceConnection_pageInfo(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "PostgresInstanceConnection", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_PageInfo(ctx, field) - }, - } - return fc, nil +func (ec *executionContext) fieldContext_PostgresGrantAccessActivityLogEntry_actor(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresGrantAccessActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresInstanceConnection_nodes(ctx context.Context, field graphql.CollectedField, obj *pagination.FacetableConnection[*postgres.PostgresInstance, *postgres.PostgresInstanceFilter]) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresGrantAccessActivityLogEntry_gitHubActorClaims(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresGrantAccessActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstanceConnection_nodes(ctx, field) + return ec.fieldContext_PostgresGrantAccessActivityLogEntry_gitHubActorClaims(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Nodes(), nil + return obj.GitHubActorClaims, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v []*postgres.PostgresInstance) graphql.Marshaler { - return ec.marshalNPostgresInstance2ᚕᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceᚄ(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *github.GitHubActorClaims) graphql.Marshaler { + return ec.marshalOGitHubActorClaims2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋauthᚋmiddlewareᚋgithubᚐGitHubActorClaims(ctx, selections, v) }, true, - true, + false, ) } -func (ec *executionContext) fieldContext_PostgresInstanceConnection_nodes(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_PostgresGrantAccessActivityLogEntry_gitHubActorClaims(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "PostgresInstanceConnection", + Object: "PostgresGrantAccessActivityLogEntry", Field: field, - IsMethod: true, + IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_PostgresInstance(ctx, field) + return ec.childFields_GitHubActorClaims(ctx, field) }, } return fc, nil } -func (ec *executionContext) _PostgresInstanceConnection_edges(ctx context.Context, field graphql.CollectedField, obj *pagination.FacetableConnection[*postgres.PostgresInstance, *postgres.PostgresInstanceFilter]) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresGrantAccessActivityLogEntry_createdAt(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresGrantAccessActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstanceConnection_edges(ctx, field) + return ec.fieldContext_PostgresGrantAccessActivityLogEntry_createdAt(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Edges, nil + return obj.CreatedAt, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v []pagination.Edge[*postgres.PostgresInstance]) graphql.Marshaler { - return ec.marshalNPostgresInstanceEdge2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋpaginationᚐEdgeᚄ(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v time.Time) graphql.Marshaler { + return ec.marshalNTime2timeᚐTime(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresInstanceConnection_edges(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "PostgresInstanceConnection", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_PostgresInstanceEdge(ctx, field) - }, - } - return fc, nil +func (ec *executionContext) fieldContext_PostgresGrantAccessActivityLogEntry_createdAt(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresGrantAccessActivityLogEntry", field, false, false, errors.New("field of type Time does not have child fields")) } -func (ec *executionContext) _PostgresInstanceConnection_facets(ctx context.Context, field graphql.CollectedField, obj *pagination.FacetableConnection[*postgres.PostgresInstance, *postgres.PostgresInstanceFilter]) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresGrantAccessActivityLogEntry_message(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresGrantAccessActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstanceConnection_facets(ctx, field) + return ec.fieldContext_PostgresGrantAccessActivityLogEntry_message(ctx, field) }, func(ctx context.Context) (any, error) { - return ec.Resolvers.PostgresInstanceConnection().Facets(ctx, obj) + return obj.Message, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v *postgres.PostgresInstanceFacets) graphql.Marshaler { - return ec.marshalOPostgresInstanceFacets2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceFacets(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { + return ec.marshalNString2string(ctx, selections, v) }, true, - false, + true, ) } -func (ec *executionContext) fieldContext_PostgresInstanceConnection_facets(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "PostgresInstanceConnection", - Field: field, - IsMethod: true, - IsResolver: true, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_PostgresInstanceFacets(ctx, field) - }, - } - return fc, nil +func (ec *executionContext) fieldContext_PostgresGrantAccessActivityLogEntry_message(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresGrantAccessActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresInstanceEdge_cursor(ctx context.Context, field graphql.CollectedField, obj *pagination.Edge[*postgres.PostgresInstance]) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresGrantAccessActivityLogEntry_resourceType(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresGrantAccessActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstanceEdge_cursor(ctx, field) + return ec.fieldContext_PostgresGrantAccessActivityLogEntry_resourceType(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Cursor, nil + return obj.ResourceType, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v pagination.Cursor) graphql.Marshaler { - return ec.marshalNCursor2githubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋpaginationᚐCursor(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v activitylog.ActivityLogEntryResourceType) graphql.Marshaler { + return ec.marshalNActivityLogEntryResourceType2githubᚗcomᚋnaisᚋapiᚋinternalᚋactivitylogᚐActivityLogEntryResourceType(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresInstanceEdge_cursor(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresInstanceEdge", field, false, false, errors.New("field of type Cursor does not have child fields")) +func (ec *executionContext) fieldContext_PostgresGrantAccessActivityLogEntry_resourceType(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresGrantAccessActivityLogEntry", field, false, false, errors.New("field of type ActivityLogEntryResourceType does not have child fields")) } -func (ec *executionContext) _PostgresInstanceEdge_node(ctx context.Context, field graphql.CollectedField, obj *pagination.Edge[*postgres.PostgresInstance]) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresGrantAccessActivityLogEntry_resourceName(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresGrantAccessActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstanceEdge_node(ctx, field) + return ec.fieldContext_PostgresGrantAccessActivityLogEntry_resourceName(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Node, nil + return obj.ResourceName, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v *postgres.PostgresInstance) graphql.Marshaler { - return ec.marshalNPostgresInstance2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstance(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { + return ec.marshalNString2string(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresInstanceEdge_node(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "PostgresInstanceEdge", - Field: field, - IsMethod: false, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_PostgresInstance(ctx, field) - }, - } - return fc, nil +func (ec *executionContext) fieldContext_PostgresGrantAccessActivityLogEntry_resourceName(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresGrantAccessActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresInstanceFacets_environments(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstanceFacets) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresGrantAccessActivityLogEntry_teamSlug(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresGrantAccessActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstanceFacets_environments(ctx, field) + return ec.fieldContext_PostgresGrantAccessActivityLogEntry_teamSlug(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Environments(ctx), nil + return obj.TeamSlug, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v []model.StringFacetItem) graphql.Marshaler { - return ec.marshalNStringFacetItem2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋmodelᚐStringFacetItemᚄ(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *slug.Slug) graphql.Marshaler { + return ec.marshalNSlug2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋslugᚐSlug(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresInstanceFacets_environments(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "PostgresInstanceFacets", - Field: field, - IsMethod: true, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_StringFacetItem(ctx, field) - }, - } - return fc, nil +func (ec *executionContext) fieldContext_PostgresGrantAccessActivityLogEntry_teamSlug(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresGrantAccessActivityLogEntry", field, false, false, errors.New("field of type Slug does not have child fields")) } -func (ec *executionContext) _PostgresInstanceFacets_states(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstanceFacets) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresGrantAccessActivityLogEntry_environmentName(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresGrantAccessActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstanceFacets_states(ctx, field) + return ec.fieldContext_PostgresGrantAccessActivityLogEntry_environmentName(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.States(ctx), nil + return obj.EnvironmentName, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v []postgres.PostgresInstanceStateFacetItem) graphql.Marshaler { - return ec.marshalNPostgresInstanceStateFacetItem2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceStateFacetItemᚄ(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *string) graphql.Marshaler { + return ec.marshalOString2ᚖstring(ctx, selections, v) }, true, - true, - ) -} -func (ec *executionContext) fieldContext_PostgresInstanceFacets_states(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - fc = &graphql.FieldContext{ - Object: "PostgresInstanceFacets", - Field: field, - IsMethod: true, - IsResolver: false, - Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_PostgresInstanceStateFacetItem(ctx, field) - }, - } - return fc, nil + false, + ) +} +func (ec *executionContext) fieldContext_PostgresGrantAccessActivityLogEntry_environmentName(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresGrantAccessActivityLogEntry", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresInstanceFacets_labels(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstanceFacets) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresGrantAccessActivityLogEntry_data(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresGrantAccessActivityLogEntry) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstanceFacets_labels(ctx, field) + return ec.fieldContext_PostgresGrantAccessActivityLogEntry_data(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Labels(ctx), nil + return obj.Data, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v []model.LabelFacetItem) graphql.Marshaler { - return ec.marshalNLabelFacetItem2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋmodelᚐLabelFacetItemᚄ(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *postgres.PostgresGrantAccessActivityLogEntryData) graphql.Marshaler { + return ec.marshalNPostgresGrantAccessActivityLogEntryData2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresGrantAccessActivityLogEntryData(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresInstanceFacets_labels(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_PostgresGrantAccessActivityLogEntry_data(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ - Object: "PostgresInstanceFacets", + Object: "PostgresGrantAccessActivityLogEntry", Field: field, - IsMethod: true, + IsMethod: false, IsResolver: false, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_LabelFacetItem(ctx, field) + return ec.childFields_PostgresGrantAccessActivityLogEntryData(ctx, field) }, } return fc, nil } -func (ec *executionContext) _PostgresInstanceStateFacetItem_state(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstanceStateFacetItem) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresGrantAccessActivityLogEntryData_grantee(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresGrantAccessActivityLogEntryData) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstanceStateFacetItem_state(ctx, field) + return ec.fieldContext_PostgresGrantAccessActivityLogEntryData_grantee(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.State, nil + return obj.Grantee, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v postgres.PostgresInstanceState) graphql.Marshaler { - return ec.marshalNPostgresInstanceState2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceState(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v string) graphql.Marshaler { + return ec.marshalNString2string(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresInstanceStateFacetItem_state(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresInstanceStateFacetItem", field, false, false, errors.New("field of type PostgresInstanceState does not have child fields")) +func (ec *executionContext) fieldContext_PostgresGrantAccessActivityLogEntryData_grantee(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresGrantAccessActivityLogEntryData", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _PostgresInstanceStateFacetItem_count(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresInstanceStateFacetItem) (ret graphql.Marshaler) { +func (ec *executionContext) _PostgresGrantAccessActivityLogEntryData_until(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresGrantAccessActivityLogEntryData) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_PostgresInstanceStateFacetItem_count(ctx, field) + return ec.fieldContext_PostgresGrantAccessActivityLogEntryData_until(ctx, field) }, func(ctx context.Context) (any, error) { - return obj.Count, nil + return obj.Until, nil }, nil, - func(ctx context.Context, selections ast.SelectionSet, v int) graphql.Marshaler { - return ec.marshalNInt2int(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v time.Time) graphql.Marshaler { + return ec.marshalNTime2timeᚐTime(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_PostgresInstanceStateFacetItem_count(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("PostgresInstanceStateFacetItem", field, false, false, errors.New("field of type Int does not have child fields")) +func (ec *executionContext) fieldContext_PostgresGrantAccessActivityLogEntryData_until(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("PostgresGrantAccessActivityLogEntryData", field, false, false, errors.New("field of type Time does not have child fields")) } func (ec *executionContext) _PostgresPersonalAccessConnectionActivityLogEntry_id(ctx context.Context, field graphql.CollectedField, obj *postgres.PostgresPersonalAccessConnectionActivityLogEntry) (ret graphql.Marshaler) { @@ -2514,13 +2514,13 @@ func (ec *executionContext) fieldContext_PostgresResources_diskSize(_ context.Co return graphql.NewScalarFieldContext("PostgresResources", field, false, false, errors.New("field of type String does not have child fields")) } -func (ec *executionContext) _TeamInventoryCountPostgresInstances_total(ctx context.Context, field graphql.CollectedField, obj *postgres.TeamInventoryCountPostgresInstances) (ret graphql.Marshaler) { +func (ec *executionContext) _TeamInventoryCountPostgresBranches_total(ctx context.Context, field graphql.CollectedField, obj *postgres.TeamInventoryCountPostgresBranches) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_TeamInventoryCountPostgresInstances_total(ctx, field) + return ec.fieldContext_TeamInventoryCountPostgresBranches_total(ctx, field) }, func(ctx context.Context) (any, error) { return obj.Total, nil @@ -2533,8 +2533,8 @@ func (ec *executionContext) _TeamInventoryCountPostgresInstances_total(ctx conte true, ) } -func (ec *executionContext) fieldContext_TeamInventoryCountPostgresInstances_total(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { - return graphql.NewScalarFieldContext("TeamInventoryCountPostgresInstances", field, false, false, errors.New("field of type Int does not have child fields")) +func (ec *executionContext) fieldContext_TeamInventoryCountPostgresBranches_total(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { + return graphql.NewScalarFieldContext("TeamInventoryCountPostgresBranches", field, false, false, errors.New("field of type Int does not have child fields")) } // endregion **************************** field.gotpl ***************************** @@ -2552,20 +2552,20 @@ func (ec *executionContext) unmarshalInputCreatePostgresAccessInput(ctx context. asMap[k] = v } - fieldsInOrder := [...]string{"postgresInstance", "teamSlug", "environmentName", "accessLevel", "reason", "ttl"} + fieldsInOrder := [...]string{"postgresBranch", "teamSlug", "environmentName", "accessLevel", "reason", "ttl"} for _, k := range fieldsInOrder { v, ok := asMap[k] if !ok { continue } switch k { - case "postgresInstance": - ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("postgresInstance")) + case "postgresBranch": + ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("postgresBranch")) data, err := ec.unmarshalNString2string(ctx, v) if err != nil { return it, err } - it.PostgresInstance = data + it.PostgresBranch = data case "teamSlug": ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("teamSlug")) data, err := ec.unmarshalNSlug2githubᚗcomᚋnaisᚋapiᚋinternalᚋslugᚐSlug(ctx, v) @@ -2606,8 +2606,8 @@ func (ec *executionContext) unmarshalInputCreatePostgresAccessInput(ctx context. return it, nil } -func (ec *executionContext) unmarshalInputDeletePostgresInput(ctx context.Context, obj any) (postgres.DeletePostgresInput, error) { - var it postgres.DeletePostgresInput +func (ec *executionContext) unmarshalInputDeletePostgresBranchInput(ctx context.Context, obj any) (postgres.DeletePostgresBranchInput, error) { + var it postgres.DeletePostgresBranchInput if obj == nil { return it, nil } @@ -2708,8 +2708,8 @@ func (ec *executionContext) unmarshalInputGrantPostgresAccessInput(ctx context.C return it, nil } -func (ec *executionContext) unmarshalInputPostgresInstanceFilter(ctx context.Context, obj any) (postgres.PostgresInstanceFilter, error) { - var it postgres.PostgresInstanceFilter +func (ec *executionContext) unmarshalInputPostgresBranchFilter(ctx context.Context, obj any) (postgres.PostgresBranchFilter, error) { + var it postgres.PostgresBranchFilter if obj == nil { return it, nil } @@ -2742,7 +2742,7 @@ func (ec *executionContext) unmarshalInputPostgresInstanceFilter(ctx context.Con it.Environments = data case "states": ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("states")) - data, err := ec.unmarshalOPostgresInstanceState2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceStateᚄ(ctx, v) + data, err := ec.unmarshalOPostgresBranchState2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresBranchStateᚄ(ctx, v) if err != nil { return it, err } @@ -2759,8 +2759,8 @@ func (ec *executionContext) unmarshalInputPostgresInstanceFilter(ctx context.Con return it, nil } -func (ec *executionContext) unmarshalInputPostgresInstanceOrder(ctx context.Context, obj any) (postgres.PostgresInstanceOrder, error) { - var it postgres.PostgresInstanceOrder +func (ec *executionContext) unmarshalInputPostgresBranchOrder(ctx context.Context, obj any) (postgres.PostgresBranchOrder, error) { + var it postgres.PostgresBranchOrder if obj == nil { return it, nil } @@ -2779,7 +2779,7 @@ func (ec *executionContext) unmarshalInputPostgresInstanceOrder(ctx context.Cont switch k { case "field": ctx := graphql.WithPathContext(ctx, graphql.NewPathWithField("field")) - data, err := ec.unmarshalNPostgresInstanceOrderField2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceOrderField(ctx, v) + data, err := ec.unmarshalNPostgresBranchOrderField2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresBranchOrderField(ctx, v) if err != nil { return it, err } @@ -2848,19 +2848,19 @@ func (ec *executionContext) _CreatePostgresAccessPayload(ctx context.Context, se return out } -var deletePostgresPayloadImplementors = []string{"DeletePostgresPayload"} +var deletePostgresBranchPayloadImplementors = []string{"DeletePostgresBranchPayload"} -func (ec *executionContext) _DeletePostgresPayload(ctx context.Context, sel ast.SelectionSet, obj *postgres.DeletePostgresPayload) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, deletePostgresPayloadImplementors) +func (ec *executionContext) _DeletePostgresBranchPayload(ctx context.Context, sel ast.SelectionSet, obj *postgres.DeletePostgresBranchPayload) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, deletePostgresBranchPayloadImplementors) out := graphql.NewFieldSet(fields) deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": - out.Values[i] = graphql.MarshalString("DeletePostgresPayload") - case "postgresDeleted": - out.Values[i] = ec._DeletePostgresPayload_postgresDeleted(ctx, field, obj) + out.Values[i] = graphql.MarshalString("DeletePostgresBranchPayload") + case "postgresBranchDeleted": + out.Values[i] = ec._DeletePostgresBranchPayload_postgresBranchDeleted(ctx, field, obj) default: panic("unknown field " + strconv.Quote(field.Name)) } @@ -2956,8 +2956,8 @@ func (ec *executionContext) _Postgres(ctx context.Context, sel ast.SelectionSet, if out.Values[i] == graphql.Null { out.Invalids++ } - case "activeInstance": - out.Values[i] = ec._Postgres_activeInstance(ctx, field, obj) + case "activeBranch": + out.Values[i] = ec._Postgres_activeBranch(ctx, field, obj) case "labels": out.Values[i] = ec._Postgres_labels(ctx, field, obj) if out.Values[i] == graphql.Null { @@ -3079,7 +3079,7 @@ func (ec *executionContext) _PostgresAccess(ctx context.Context, sel ast.Selecti } out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) - case "postgresInstance": + case "postgresBranch": field := field innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { @@ -3088,7 +3088,7 @@ func (ec *executionContext) _PostgresAccess(ctx context.Context, sel ast.Selecti ec.Error(ctx, ec.Recover(ctx, r)) } }() - res = ec._PostgresAccess_postgresInstance(ctx, field, obj) + res = ec._PostgresAccess_postgresBranch(ctx, field, obj) if res == graphql.Null { atomic.AddUint32(&fs.Invalids, 1) } @@ -3190,244 +3190,49 @@ func (ec *executionContext) _PostgresAccess(ctx context.Context, sel ast.Selecti return out } -var postgresAccessConnectionDetailsImplementors = []string{"PostgresAccessConnectionDetails"} - -func (ec *executionContext) _PostgresAccessConnectionDetails(ctx context.Context, sel ast.SelectionSet, obj *postgres.PostgresAccessConnectionDetails) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, postgresAccessConnectionDetailsImplementors) - - out := graphql.NewFieldSet(fields) - deferred := make(map[string]*graphql.FieldSet) - for i, field := range fields { - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString("PostgresAccessConnectionDetails") - case "username": - out.Values[i] = ec._PostgresAccessConnectionDetails_username(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "password": - out.Values[i] = ec._PostgresAccessConnectionDetails_password(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "caCertificate": - out.Values[i] = ec._PostgresAccessConnectionDetails_caCertificate(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "serverName": - out.Values[i] = ec._PostgresAccessConnectionDetails_serverName(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "relayEndpoint": - out.Values[i] = ec._PostgresAccessConnectionDetails_relayEndpoint(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "relayAccess": - out.Values[i] = ec._PostgresAccessConnectionDetails_relayAccess(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "relayToken": - out.Values[i] = ec._PostgresAccessConnectionDetails_relayToken(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - out.Dispatch(ctx) - if out.Invalids > 0 { - return graphql.Null - } - - atomic.AddInt32(&ec.Deferred, int32(min(len(deferred), math.MaxInt32))) - - for label, dfs := range deferred { - ec.ProcessDeferredGroup(graphql.DeferredGroup{ - Label: label, - Path: graphql.GetPath(ctx), - FieldSet: dfs, - Context: ctx, - }) - } - - return out -} - -var postgresDeletedActivityLogEntryImplementors = []string{"PostgresDeletedActivityLogEntry", "ActivityLogEntry", "Node"} - -func (ec *executionContext) _PostgresDeletedActivityLogEntry(ctx context.Context, sel ast.SelectionSet, obj *postgres.PostgresDeletedActivityLogEntry) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, postgresDeletedActivityLogEntryImplementors) - - out := graphql.NewFieldSet(fields) - deferred := make(map[string]*graphql.FieldSet) - for i, field := range fields { - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString("PostgresDeletedActivityLogEntry") - case "id": - out.Values[i] = ec._PostgresDeletedActivityLogEntry_id(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "actor": - out.Values[i] = ec._PostgresDeletedActivityLogEntry_actor(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "gitHubActorClaims": - out.Values[i] = ec._PostgresDeletedActivityLogEntry_gitHubActorClaims(ctx, field, obj) - case "createdAt": - out.Values[i] = ec._PostgresDeletedActivityLogEntry_createdAt(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "message": - out.Values[i] = ec._PostgresDeletedActivityLogEntry_message(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "resourceType": - out.Values[i] = ec._PostgresDeletedActivityLogEntry_resourceType(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "resourceName": - out.Values[i] = ec._PostgresDeletedActivityLogEntry_resourceName(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "teamSlug": - out.Values[i] = ec._PostgresDeletedActivityLogEntry_teamSlug(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "environmentName": - out.Values[i] = ec._PostgresDeletedActivityLogEntry_environmentName(ctx, field, obj) - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - out.Dispatch(ctx) - if out.Invalids > 0 { - return graphql.Null - } - - atomic.AddInt32(&ec.Deferred, int32(min(len(deferred), math.MaxInt32))) - - for label, dfs := range deferred { - ec.ProcessDeferredGroup(graphql.DeferredGroup{ - Label: label, - Path: graphql.GetPath(ctx), - FieldSet: dfs, - Context: ctx, - }) - } - - return out -} - -var postgresGrantAccessActivityLogEntryImplementors = []string{"PostgresGrantAccessActivityLogEntry", "ActivityLogEntry", "Node"} - -func (ec *executionContext) _PostgresGrantAccessActivityLogEntry(ctx context.Context, sel ast.SelectionSet, obj *postgres.PostgresGrantAccessActivityLogEntry) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, postgresGrantAccessActivityLogEntryImplementors) - - out := graphql.NewFieldSet(fields) - deferred := make(map[string]*graphql.FieldSet) - for i, field := range fields { - switch field.Name { - case "__typename": - out.Values[i] = graphql.MarshalString("PostgresGrantAccessActivityLogEntry") - case "id": - out.Values[i] = ec._PostgresGrantAccessActivityLogEntry_id(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "actor": - out.Values[i] = ec._PostgresGrantAccessActivityLogEntry_actor(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "gitHubActorClaims": - out.Values[i] = ec._PostgresGrantAccessActivityLogEntry_gitHubActorClaims(ctx, field, obj) - case "createdAt": - out.Values[i] = ec._PostgresGrantAccessActivityLogEntry_createdAt(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "message": - out.Values[i] = ec._PostgresGrantAccessActivityLogEntry_message(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "resourceType": - out.Values[i] = ec._PostgresGrantAccessActivityLogEntry_resourceType(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "resourceName": - out.Values[i] = ec._PostgresGrantAccessActivityLogEntry_resourceName(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "teamSlug": - out.Values[i] = ec._PostgresGrantAccessActivityLogEntry_teamSlug(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - case "environmentName": - out.Values[i] = ec._PostgresGrantAccessActivityLogEntry_environmentName(ctx, field, obj) - case "data": - out.Values[i] = ec._PostgresGrantAccessActivityLogEntry_data(ctx, field, obj) - if out.Values[i] == graphql.Null { - out.Invalids++ - } - default: - panic("unknown field " + strconv.Quote(field.Name)) - } - } - out.Dispatch(ctx) - if out.Invalids > 0 { - return graphql.Null - } - - atomic.AddInt32(&ec.Deferred, int32(min(len(deferred), math.MaxInt32))) - - for label, dfs := range deferred { - ec.ProcessDeferredGroup(graphql.DeferredGroup{ - Label: label, - Path: graphql.GetPath(ctx), - FieldSet: dfs, - Context: ctx, - }) - } - - return out -} - -var postgresGrantAccessActivityLogEntryDataImplementors = []string{"PostgresGrantAccessActivityLogEntryData"} +var postgresAccessConnectionDetailsImplementors = []string{"PostgresAccessConnectionDetails"} -func (ec *executionContext) _PostgresGrantAccessActivityLogEntryData(ctx context.Context, sel ast.SelectionSet, obj *postgres.PostgresGrantAccessActivityLogEntryData) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, postgresGrantAccessActivityLogEntryDataImplementors) +func (ec *executionContext) _PostgresAccessConnectionDetails(ctx context.Context, sel ast.SelectionSet, obj *postgres.PostgresAccessConnectionDetails) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, postgresAccessConnectionDetailsImplementors) out := graphql.NewFieldSet(fields) deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": - out.Values[i] = graphql.MarshalString("PostgresGrantAccessActivityLogEntryData") - case "grantee": - out.Values[i] = ec._PostgresGrantAccessActivityLogEntryData_grantee(ctx, field, obj) + out.Values[i] = graphql.MarshalString("PostgresAccessConnectionDetails") + case "username": + out.Values[i] = ec._PostgresAccessConnectionDetails_username(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } - case "until": - out.Values[i] = ec._PostgresGrantAccessActivityLogEntryData_until(ctx, field, obj) + case "password": + out.Values[i] = ec._PostgresAccessConnectionDetails_password(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "caCertificate": + out.Values[i] = ec._PostgresAccessConnectionDetails_caCertificate(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "serverName": + out.Values[i] = ec._PostgresAccessConnectionDetails_serverName(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "relayEndpoint": + out.Values[i] = ec._PostgresAccessConnectionDetails_relayEndpoint(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "relayAccess": + out.Values[i] = ec._PostgresAccessConnectionDetails_relayAccess(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "relayToken": + out.Values[i] = ec._PostgresAccessConnectionDetails_relayToken(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } @@ -3454,24 +3259,24 @@ func (ec *executionContext) _PostgresGrantAccessActivityLogEntryData(ctx context return out } -var postgresInstanceImplementors = []string{"PostgresInstance", "Persistence", "Node", "SearchNode"} +var postgresBranchImplementors = []string{"PostgresBranch", "Persistence", "Node", "SearchNode"} -func (ec *executionContext) _PostgresInstance(ctx context.Context, sel ast.SelectionSet, obj *postgres.PostgresInstance) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, postgresInstanceImplementors) +func (ec *executionContext) _PostgresBranch(ctx context.Context, sel ast.SelectionSet, obj *postgres.PostgresBranch) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, postgresBranchImplementors) out := graphql.NewFieldSet(fields) deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": - out.Values[i] = graphql.MarshalString("PostgresInstance") + out.Values[i] = graphql.MarshalString("PostgresBranch") case "id": - out.Values[i] = ec._PostgresInstance_id(ctx, field, obj) + out.Values[i] = ec._PostgresBranch_id(ctx, field, obj) if out.Values[i] == graphql.Null { atomic.AddUint32(&out.Invalids, 1) } case "name": - out.Values[i] = ec._PostgresInstance_name(ctx, field, obj) + out.Values[i] = ec._PostgresBranch_name(ctx, field, obj) if out.Values[i] == graphql.Null { atomic.AddUint32(&out.Invalids, 1) } @@ -3484,7 +3289,7 @@ func (ec *executionContext) _PostgresInstance(ctx context.Context, sel ast.Selec ec.Error(ctx, ec.Recover(ctx, r)) } }() - res = ec._PostgresInstance_team(ctx, field, obj) + res = ec._PostgresBranch_team(ctx, field, obj) if res == graphql.Null { atomic.AddUint32(&fs.Invalids, 1) } @@ -3520,7 +3325,7 @@ func (ec *executionContext) _PostgresInstance(ctx context.Context, sel ast.Selec ec.Error(ctx, ec.Recover(ctx, r)) } }() - res = ec._PostgresInstance_teamEnvironment(ctx, field, obj) + res = ec._PostgresBranch_teamEnvironment(ctx, field, obj) if res == graphql.Null { atomic.AddUint32(&fs.Invalids, 1) } @@ -3556,7 +3361,7 @@ func (ec *executionContext) _PostgresInstance(ctx context.Context, sel ast.Selec ec.Error(ctx, ec.Recover(ctx, r)) } }() - res = ec._PostgresInstance_postgres(ctx, field, obj) + res = ec._PostgresBranch_postgres(ctx, field, obj) if res == graphql.Null { atomic.AddUint32(&fs.Invalids, 1) } @@ -3592,7 +3397,7 @@ func (ec *executionContext) _PostgresInstance(ctx context.Context, sel ast.Selec ec.Error(ctx, ec.Recover(ctx, r)) } }() - res = ec._PostgresInstance_workloads(ctx, field, obj) + res = ec._PostgresBranch_workloads(ctx, field, obj) if res == graphql.Null { atomic.AddUint32(&fs.Invalids, 1) } @@ -3620,12 +3425,12 @@ func (ec *executionContext) _PostgresInstance(ctx context.Context, sel ast.Selec out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) case "state": - out.Values[i] = ec._PostgresInstance_state(ctx, field, obj) + out.Values[i] = ec._PostgresBranch_state(ctx, field, obj) if out.Values[i] == graphql.Null { atomic.AddUint32(&out.Invalids, 1) } case "labels": - out.Values[i] = ec._PostgresInstance_labels(ctx, field, obj) + out.Values[i] = ec._PostgresBranch_labels(ctx, field, obj) if out.Values[i] == graphql.Null { atomic.AddUint32(&out.Invalids, 1) } @@ -3652,29 +3457,29 @@ func (ec *executionContext) _PostgresInstance(ctx context.Context, sel ast.Selec return out } -var postgresInstanceConnectionImplementors = []string{"PostgresInstanceConnection"} +var postgresBranchConnectionImplementors = []string{"PostgresBranchConnection"} -func (ec *executionContext) _PostgresInstanceConnection(ctx context.Context, sel ast.SelectionSet, obj *pagination.FacetableConnection[*postgres.PostgresInstance, *postgres.PostgresInstanceFilter]) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, postgresInstanceConnectionImplementors) +func (ec *executionContext) _PostgresBranchConnection(ctx context.Context, sel ast.SelectionSet, obj *pagination.FacetableConnection[*postgres.PostgresBranch, *postgres.PostgresBranchFilter]) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, postgresBranchConnectionImplementors) out := graphql.NewFieldSet(fields) deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": - out.Values[i] = graphql.MarshalString("PostgresInstanceConnection") + out.Values[i] = graphql.MarshalString("PostgresBranchConnection") case "pageInfo": - out.Values[i] = ec._PostgresInstanceConnection_pageInfo(ctx, field, obj) + out.Values[i] = ec._PostgresBranchConnection_pageInfo(ctx, field, obj) if out.Values[i] == graphql.Null { atomic.AddUint32(&out.Invalids, 1) } case "nodes": - out.Values[i] = ec._PostgresInstanceConnection_nodes(ctx, field, obj) + out.Values[i] = ec._PostgresBranchConnection_nodes(ctx, field, obj) if out.Values[i] == graphql.Null { atomic.AddUint32(&out.Invalids, 1) } case "edges": - out.Values[i] = ec._PostgresInstanceConnection_edges(ctx, field, obj) + out.Values[i] = ec._PostgresBranchConnection_edges(ctx, field, obj) if out.Values[i] == graphql.Null { atomic.AddUint32(&out.Invalids, 1) } @@ -3687,7 +3492,7 @@ func (ec *executionContext) _PostgresInstanceConnection(ctx context.Context, sel ec.Error(ctx, ec.Recover(ctx, r)) } }() - res = ec._PostgresInstanceConnection_facets(ctx, field, obj) + res = ec._PostgresBranchConnection_facets(ctx, field, obj) return res } @@ -3734,24 +3539,24 @@ func (ec *executionContext) _PostgresInstanceConnection(ctx context.Context, sel return out } -var postgresInstanceEdgeImplementors = []string{"PostgresInstanceEdge"} +var postgresBranchEdgeImplementors = []string{"PostgresBranchEdge"} -func (ec *executionContext) _PostgresInstanceEdge(ctx context.Context, sel ast.SelectionSet, obj *pagination.Edge[*postgres.PostgresInstance]) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, postgresInstanceEdgeImplementors) +func (ec *executionContext) _PostgresBranchEdge(ctx context.Context, sel ast.SelectionSet, obj *pagination.Edge[*postgres.PostgresBranch]) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, postgresBranchEdgeImplementors) out := graphql.NewFieldSet(fields) deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": - out.Values[i] = graphql.MarshalString("PostgresInstanceEdge") + out.Values[i] = graphql.MarshalString("PostgresBranchEdge") case "cursor": - out.Values[i] = ec._PostgresInstanceEdge_cursor(ctx, field, obj) + out.Values[i] = ec._PostgresBranchEdge_cursor(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } case "node": - out.Values[i] = ec._PostgresInstanceEdge_node(ctx, field, obj) + out.Values[i] = ec._PostgresBranchEdge_node(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } @@ -3778,17 +3583,17 @@ func (ec *executionContext) _PostgresInstanceEdge(ctx context.Context, sel ast.S return out } -var postgresInstanceFacetsImplementors = []string{"PostgresInstanceFacets"} +var postgresBranchFacetsImplementors = []string{"PostgresBranchFacets"} -func (ec *executionContext) _PostgresInstanceFacets(ctx context.Context, sel ast.SelectionSet, obj *postgres.PostgresInstanceFacets) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, postgresInstanceFacetsImplementors) +func (ec *executionContext) _PostgresBranchFacets(ctx context.Context, sel ast.SelectionSet, obj *postgres.PostgresBranchFacets) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, postgresBranchFacetsImplementors) out := graphql.NewFieldSet(fields) deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": - out.Values[i] = graphql.MarshalString("PostgresInstanceFacets") + out.Values[i] = graphql.MarshalString("PostgresBranchFacets") case "environments": field := field @@ -3798,7 +3603,7 @@ func (ec *executionContext) _PostgresInstanceFacets(ctx context.Context, sel ast ec.Error(ctx, ec.Recover(ctx, r)) } }() - res = ec._PostgresInstanceFacets_environments(ctx, field, obj) + res = ec._PostgresBranchFacets_environments(ctx, field, obj) if res == graphql.Null { atomic.AddUint32(&fs.Invalids, 1) } @@ -3834,7 +3639,7 @@ func (ec *executionContext) _PostgresInstanceFacets(ctx context.Context, sel ast ec.Error(ctx, ec.Recover(ctx, r)) } }() - res = ec._PostgresInstanceFacets_states(ctx, field, obj) + res = ec._PostgresBranchFacets_states(ctx, field, obj) if res == graphql.Null { atomic.AddUint32(&fs.Invalids, 1) } @@ -3870,7 +3675,7 @@ func (ec *executionContext) _PostgresInstanceFacets(ctx context.Context, sel ast ec.Error(ctx, ec.Recover(ctx, r)) } }() - res = ec._PostgresInstanceFacets_labels(ctx, field, obj) + res = ec._PostgresBranchFacets_labels(ctx, field, obj) if res == graphql.Null { atomic.AddUint32(&fs.Invalids, 1) } @@ -3920,24 +3725,219 @@ func (ec *executionContext) _PostgresInstanceFacets(ctx context.Context, sel ast return out } -var postgresInstanceStateFacetItemImplementors = []string{"PostgresInstanceStateFacetItem"} +var postgresBranchStateFacetItemImplementors = []string{"PostgresBranchStateFacetItem"} -func (ec *executionContext) _PostgresInstanceStateFacetItem(ctx context.Context, sel ast.SelectionSet, obj *postgres.PostgresInstanceStateFacetItem) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, postgresInstanceStateFacetItemImplementors) +func (ec *executionContext) _PostgresBranchStateFacetItem(ctx context.Context, sel ast.SelectionSet, obj *postgres.PostgresBranchStateFacetItem) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, postgresBranchStateFacetItemImplementors) out := graphql.NewFieldSet(fields) deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": - out.Values[i] = graphql.MarshalString("PostgresInstanceStateFacetItem") + out.Values[i] = graphql.MarshalString("PostgresBranchStateFacetItem") case "state": - out.Values[i] = ec._PostgresInstanceStateFacetItem_state(ctx, field, obj) + out.Values[i] = ec._PostgresBranchStateFacetItem_state(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } case "count": - out.Values[i] = ec._PostgresInstanceStateFacetItem_count(ctx, field, obj) + out.Values[i] = ec._PostgresBranchStateFacetItem_count(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.Deferred, int32(min(len(deferred), math.MaxInt32))) + + for label, dfs := range deferred { + ec.ProcessDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var postgresDeletedActivityLogEntryImplementors = []string{"PostgresDeletedActivityLogEntry", "ActivityLogEntry", "Node"} + +func (ec *executionContext) _PostgresDeletedActivityLogEntry(ctx context.Context, sel ast.SelectionSet, obj *postgres.PostgresDeletedActivityLogEntry) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, postgresDeletedActivityLogEntryImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("PostgresDeletedActivityLogEntry") + case "id": + out.Values[i] = ec._PostgresDeletedActivityLogEntry_id(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "actor": + out.Values[i] = ec._PostgresDeletedActivityLogEntry_actor(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "gitHubActorClaims": + out.Values[i] = ec._PostgresDeletedActivityLogEntry_gitHubActorClaims(ctx, field, obj) + case "createdAt": + out.Values[i] = ec._PostgresDeletedActivityLogEntry_createdAt(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "message": + out.Values[i] = ec._PostgresDeletedActivityLogEntry_message(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "resourceType": + out.Values[i] = ec._PostgresDeletedActivityLogEntry_resourceType(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "resourceName": + out.Values[i] = ec._PostgresDeletedActivityLogEntry_resourceName(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "teamSlug": + out.Values[i] = ec._PostgresDeletedActivityLogEntry_teamSlug(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "environmentName": + out.Values[i] = ec._PostgresDeletedActivityLogEntry_environmentName(ctx, field, obj) + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.Deferred, int32(min(len(deferred), math.MaxInt32))) + + for label, dfs := range deferred { + ec.ProcessDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var postgresGrantAccessActivityLogEntryImplementors = []string{"PostgresGrantAccessActivityLogEntry", "ActivityLogEntry", "Node"} + +func (ec *executionContext) _PostgresGrantAccessActivityLogEntry(ctx context.Context, sel ast.SelectionSet, obj *postgres.PostgresGrantAccessActivityLogEntry) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, postgresGrantAccessActivityLogEntryImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("PostgresGrantAccessActivityLogEntry") + case "id": + out.Values[i] = ec._PostgresGrantAccessActivityLogEntry_id(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "actor": + out.Values[i] = ec._PostgresGrantAccessActivityLogEntry_actor(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "gitHubActorClaims": + out.Values[i] = ec._PostgresGrantAccessActivityLogEntry_gitHubActorClaims(ctx, field, obj) + case "createdAt": + out.Values[i] = ec._PostgresGrantAccessActivityLogEntry_createdAt(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "message": + out.Values[i] = ec._PostgresGrantAccessActivityLogEntry_message(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "resourceType": + out.Values[i] = ec._PostgresGrantAccessActivityLogEntry_resourceType(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "resourceName": + out.Values[i] = ec._PostgresGrantAccessActivityLogEntry_resourceName(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "teamSlug": + out.Values[i] = ec._PostgresGrantAccessActivityLogEntry_teamSlug(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "environmentName": + out.Values[i] = ec._PostgresGrantAccessActivityLogEntry_environmentName(ctx, field, obj) + case "data": + out.Values[i] = ec._PostgresGrantAccessActivityLogEntry_data(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + default: + panic("unknown field " + strconv.Quote(field.Name)) + } + } + out.Dispatch(ctx) + if out.Invalids > 0 { + return graphql.Null + } + + atomic.AddInt32(&ec.Deferred, int32(min(len(deferred), math.MaxInt32))) + + for label, dfs := range deferred { + ec.ProcessDeferredGroup(graphql.DeferredGroup{ + Label: label, + Path: graphql.GetPath(ctx), + FieldSet: dfs, + Context: ctx, + }) + } + + return out +} + +var postgresGrantAccessActivityLogEntryDataImplementors = []string{"PostgresGrantAccessActivityLogEntryData"} + +func (ec *executionContext) _PostgresGrantAccessActivityLogEntryData(ctx context.Context, sel ast.SelectionSet, obj *postgres.PostgresGrantAccessActivityLogEntryData) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, postgresGrantAccessActivityLogEntryDataImplementors) + + out := graphql.NewFieldSet(fields) + deferred := make(map[string]*graphql.FieldSet) + for i, field := range fields { + switch field.Name { + case "__typename": + out.Values[i] = graphql.MarshalString("PostgresGrantAccessActivityLogEntryData") + case "grantee": + out.Values[i] = ec._PostgresGrantAccessActivityLogEntryData_grantee(ctx, field, obj) + if out.Values[i] == graphql.Null { + out.Invalids++ + } + case "until": + out.Values[i] = ec._PostgresGrantAccessActivityLogEntryData_until(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } @@ -4206,19 +4206,19 @@ func (ec *executionContext) _PostgresResources(ctx context.Context, sel ast.Sele return out } -var teamInventoryCountPostgresInstancesImplementors = []string{"TeamInventoryCountPostgresInstances"} +var teamInventoryCountPostgresBranchesImplementors = []string{"TeamInventoryCountPostgresBranches"} -func (ec *executionContext) _TeamInventoryCountPostgresInstances(ctx context.Context, sel ast.SelectionSet, obj *postgres.TeamInventoryCountPostgresInstances) graphql.Marshaler { - fields := graphql.CollectFields(ec.OperationContext, sel, teamInventoryCountPostgresInstancesImplementors) +func (ec *executionContext) _TeamInventoryCountPostgresBranches(ctx context.Context, sel ast.SelectionSet, obj *postgres.TeamInventoryCountPostgresBranches) graphql.Marshaler { + fields := graphql.CollectFields(ec.OperationContext, sel, teamInventoryCountPostgresBranchesImplementors) out := graphql.NewFieldSet(fields) deferred := make(map[string]*graphql.FieldSet) for i, field := range fields { switch field.Name { case "__typename": - out.Values[i] = graphql.MarshalString("TeamInventoryCountPostgresInstances") + out.Values[i] = graphql.MarshalString("TeamInventoryCountPostgresBranches") case "total": - out.Values[i] = ec._TeamInventoryCountPostgresInstances_total(ctx, field, obj) + out.Values[i] = ec._TeamInventoryCountPostgresBranches_total(ctx, field, obj) if out.Values[i] == graphql.Null { out.Invalids++ } @@ -4268,23 +4268,23 @@ func (ec *executionContext) marshalNCreatePostgresAccessPayload2ᚖgithubᚗcom return ec._CreatePostgresAccessPayload(ctx, sel, v) } -func (ec *executionContext) unmarshalNDeletePostgresInput2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐDeletePostgresInput(ctx context.Context, v any) (postgres.DeletePostgresInput, error) { - res, err := ec.unmarshalInputDeletePostgresInput(ctx, v) +func (ec *executionContext) unmarshalNDeletePostgresBranchInput2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐDeletePostgresBranchInput(ctx context.Context, v any) (postgres.DeletePostgresBranchInput, error) { + res, err := ec.unmarshalInputDeletePostgresBranchInput(ctx, v) return res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) marshalNDeletePostgresPayload2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐDeletePostgresPayload(ctx context.Context, sel ast.SelectionSet, v postgres.DeletePostgresPayload) graphql.Marshaler { - return ec._DeletePostgresPayload(ctx, sel, &v) +func (ec *executionContext) marshalNDeletePostgresBranchPayload2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐDeletePostgresBranchPayload(ctx context.Context, sel ast.SelectionSet, v postgres.DeletePostgresBranchPayload) graphql.Marshaler { + return ec._DeletePostgresBranchPayload(ctx, sel, &v) } -func (ec *executionContext) marshalNDeletePostgresPayload2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐDeletePostgresPayload(ctx context.Context, sel ast.SelectionSet, v *postgres.DeletePostgresPayload) graphql.Marshaler { +func (ec *executionContext) marshalNDeletePostgresBranchPayload2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐDeletePostgresBranchPayload(ctx context.Context, sel ast.SelectionSet, v *postgres.DeletePostgresBranchPayload) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { graphql.AddErrorf(ctx, "the requested element is null which the schema does not allow") } return graphql.Null } - return ec._DeletePostgresPayload(ctx, sel, v) + return ec._DeletePostgresBranchPayload(ctx, sel, v) } func (ec *executionContext) unmarshalNGrantPostgresAccessInput2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐGrantPostgresAccessInput(ctx context.Context, v any) (postgres.GrantPostgresAccessInput, error) { @@ -4354,25 +4354,15 @@ func (ec *executionContext) marshalNPostgresAccessState2githubᚗcomᚋnaisᚋap return v } -func (ec *executionContext) marshalNPostgresGrantAccessActivityLogEntryData2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresGrantAccessActivityLogEntryData(ctx context.Context, sel ast.SelectionSet, v *postgres.PostgresGrantAccessActivityLogEntryData) graphql.Marshaler { - if v == nil { - if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { - graphql.AddErrorf(ctx, "the requested element is null which the schema does not allow") - } - return graphql.Null - } - return ec._PostgresGrantAccessActivityLogEntryData(ctx, sel, v) -} - -func (ec *executionContext) marshalNPostgresInstance2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstance(ctx context.Context, sel ast.SelectionSet, v postgres.PostgresInstance) graphql.Marshaler { - return ec._PostgresInstance(ctx, sel, &v) +func (ec *executionContext) marshalNPostgresBranch2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresBranch(ctx context.Context, sel ast.SelectionSet, v postgres.PostgresBranch) graphql.Marshaler { + return ec._PostgresBranch(ctx, sel, &v) } -func (ec *executionContext) marshalNPostgresInstance2ᚕᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceᚄ(ctx context.Context, sel ast.SelectionSet, v []*postgres.PostgresInstance) graphql.Marshaler { +func (ec *executionContext) marshalNPostgresBranch2ᚕᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresBranchᚄ(ctx context.Context, sel ast.SelectionSet, v []*postgres.PostgresBranch) graphql.Marshaler { ret := graphql.MarshalSliceConcurrently(ctx, len(v), 0, false, func(ctx context.Context, i int) graphql.Marshaler { fc := graphql.GetFieldContext(ctx) fc.Result = &v[i] - return ec.marshalNPostgresInstance2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstance(ctx, sel, v[i]) + return ec.marshalNPostgresBranch2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresBranch(ctx, sel, v[i]) }) for _, e := range ret { @@ -4384,39 +4374,39 @@ func (ec *executionContext) marshalNPostgresInstance2ᚕᚖgithubᚗcomᚋnais return ret } -func (ec *executionContext) marshalNPostgresInstance2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstance(ctx context.Context, sel ast.SelectionSet, v *postgres.PostgresInstance) graphql.Marshaler { +func (ec *executionContext) marshalNPostgresBranch2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresBranch(ctx context.Context, sel ast.SelectionSet, v *postgres.PostgresBranch) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { graphql.AddErrorf(ctx, "the requested element is null which the schema does not allow") } return graphql.Null } - return ec._PostgresInstance(ctx, sel, v) + return ec._PostgresBranch(ctx, sel, v) } -func (ec *executionContext) marshalNPostgresInstanceConnection2githubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋpaginationᚐFacetableConnection(ctx context.Context, sel ast.SelectionSet, v pagination.FacetableConnection[*postgres.PostgresInstance, *postgres.PostgresInstanceFilter]) graphql.Marshaler { - return ec._PostgresInstanceConnection(ctx, sel, &v) +func (ec *executionContext) marshalNPostgresBranchConnection2githubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋpaginationᚐFacetableConnection(ctx context.Context, sel ast.SelectionSet, v pagination.FacetableConnection[*postgres.PostgresBranch, *postgres.PostgresBranchFilter]) graphql.Marshaler { + return ec._PostgresBranchConnection(ctx, sel, &v) } -func (ec *executionContext) marshalNPostgresInstanceConnection2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋpaginationᚐFacetableConnection(ctx context.Context, sel ast.SelectionSet, v *pagination.FacetableConnection[*postgres.PostgresInstance, *postgres.PostgresInstanceFilter]) graphql.Marshaler { +func (ec *executionContext) marshalNPostgresBranchConnection2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋpaginationᚐFacetableConnection(ctx context.Context, sel ast.SelectionSet, v *pagination.FacetableConnection[*postgres.PostgresBranch, *postgres.PostgresBranchFilter]) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { graphql.AddErrorf(ctx, "the requested element is null which the schema does not allow") } return graphql.Null } - return ec._PostgresInstanceConnection(ctx, sel, v) + return ec._PostgresBranchConnection(ctx, sel, v) } -func (ec *executionContext) marshalNPostgresInstanceEdge2githubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋpaginationᚐEdge(ctx context.Context, sel ast.SelectionSet, v pagination.Edge[*postgres.PostgresInstance]) graphql.Marshaler { - return ec._PostgresInstanceEdge(ctx, sel, &v) +func (ec *executionContext) marshalNPostgresBranchEdge2githubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋpaginationᚐEdge(ctx context.Context, sel ast.SelectionSet, v pagination.Edge[*postgres.PostgresBranch]) graphql.Marshaler { + return ec._PostgresBranchEdge(ctx, sel, &v) } -func (ec *executionContext) marshalNPostgresInstanceEdge2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋpaginationᚐEdgeᚄ(ctx context.Context, sel ast.SelectionSet, v []pagination.Edge[*postgres.PostgresInstance]) graphql.Marshaler { +func (ec *executionContext) marshalNPostgresBranchEdge2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋpaginationᚐEdgeᚄ(ctx context.Context, sel ast.SelectionSet, v []pagination.Edge[*postgres.PostgresBranch]) graphql.Marshaler { ret := graphql.MarshalSliceConcurrently(ctx, len(v), 0, false, func(ctx context.Context, i int) graphql.Marshaler { fc := graphql.GetFieldContext(ctx) fc.Result = &v[i] - return ec.marshalNPostgresInstanceEdge2githubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋpaginationᚐEdge(ctx, sel, v[i]) + return ec.marshalNPostgresBranchEdge2githubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋpaginationᚐEdge(ctx, sel, v[i]) }) for _, e := range ret { @@ -4428,35 +4418,35 @@ func (ec *executionContext) marshalNPostgresInstanceEdge2ᚕgithubᚗcomᚋnais return ret } -func (ec *executionContext) unmarshalNPostgresInstanceOrderField2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceOrderField(ctx context.Context, v any) (postgres.PostgresInstanceOrderField, error) { - var res postgres.PostgresInstanceOrderField +func (ec *executionContext) unmarshalNPostgresBranchOrderField2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresBranchOrderField(ctx context.Context, v any) (postgres.PostgresBranchOrderField, error) { + var res postgres.PostgresBranchOrderField err := res.UnmarshalGQL(v) return res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) marshalNPostgresInstanceOrderField2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceOrderField(ctx context.Context, sel ast.SelectionSet, v postgres.PostgresInstanceOrderField) graphql.Marshaler { +func (ec *executionContext) marshalNPostgresBranchOrderField2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresBranchOrderField(ctx context.Context, sel ast.SelectionSet, v postgres.PostgresBranchOrderField) graphql.Marshaler { return v } -func (ec *executionContext) unmarshalNPostgresInstanceState2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceState(ctx context.Context, v any) (postgres.PostgresInstanceState, error) { - var res postgres.PostgresInstanceState +func (ec *executionContext) unmarshalNPostgresBranchState2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresBranchState(ctx context.Context, v any) (postgres.PostgresBranchState, error) { + var res postgres.PostgresBranchState err := res.UnmarshalGQL(v) return res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) marshalNPostgresInstanceState2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceState(ctx context.Context, sel ast.SelectionSet, v postgres.PostgresInstanceState) graphql.Marshaler { +func (ec *executionContext) marshalNPostgresBranchState2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresBranchState(ctx context.Context, sel ast.SelectionSet, v postgres.PostgresBranchState) graphql.Marshaler { return v } -func (ec *executionContext) marshalNPostgresInstanceStateFacetItem2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceStateFacetItem(ctx context.Context, sel ast.SelectionSet, v postgres.PostgresInstanceStateFacetItem) graphql.Marshaler { - return ec._PostgresInstanceStateFacetItem(ctx, sel, &v) +func (ec *executionContext) marshalNPostgresBranchStateFacetItem2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresBranchStateFacetItem(ctx context.Context, sel ast.SelectionSet, v postgres.PostgresBranchStateFacetItem) graphql.Marshaler { + return ec._PostgresBranchStateFacetItem(ctx, sel, &v) } -func (ec *executionContext) marshalNPostgresInstanceStateFacetItem2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceStateFacetItemᚄ(ctx context.Context, sel ast.SelectionSet, v []postgres.PostgresInstanceStateFacetItem) graphql.Marshaler { +func (ec *executionContext) marshalNPostgresBranchStateFacetItem2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresBranchStateFacetItemᚄ(ctx context.Context, sel ast.SelectionSet, v []postgres.PostgresBranchStateFacetItem) graphql.Marshaler { ret := graphql.MarshalSliceConcurrently(ctx, len(v), 0, false, func(ctx context.Context, i int) graphql.Marshaler { fc := graphql.GetFieldContext(ctx) fc.Result = &v[i] - return ec.marshalNPostgresInstanceStateFacetItem2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceStateFacetItem(ctx, sel, v[i]) + return ec.marshalNPostgresBranchStateFacetItem2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresBranchStateFacetItem(ctx, sel, v[i]) }) for _, e := range ret { @@ -4468,6 +4458,16 @@ func (ec *executionContext) marshalNPostgresInstanceStateFacetItem2ᚕgithubᚗc return ret } +func (ec *executionContext) marshalNPostgresGrantAccessActivityLogEntryData2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresGrantAccessActivityLogEntryData(ctx context.Context, sel ast.SelectionSet, v *postgres.PostgresGrantAccessActivityLogEntryData) graphql.Marshaler { + if v == nil { + if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { + graphql.AddErrorf(ctx, "the requested element is null which the schema does not allow") + } + return graphql.Null + } + return ec._PostgresGrantAccessActivityLogEntryData(ctx, sel, v) +} + func (ec *executionContext) marshalNPostgresPersonalAccessCreatedActivityLogEntryData2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresPersonalAccessCreatedActivityLogEntryData(ctx context.Context, sel ast.SelectionSet, v *postgres.PostgresPersonalAccessCreatedActivityLogEntryData) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { @@ -4482,18 +4482,18 @@ func (ec *executionContext) marshalNPostgresResources2githubᚗcomᚋnaisᚋapi return ec._PostgresResources(ctx, sel, &v) } -func (ec *executionContext) marshalNTeamInventoryCountPostgresInstances2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐTeamInventoryCountPostgresInstances(ctx context.Context, sel ast.SelectionSet, v postgres.TeamInventoryCountPostgresInstances) graphql.Marshaler { - return ec._TeamInventoryCountPostgresInstances(ctx, sel, &v) +func (ec *executionContext) marshalNTeamInventoryCountPostgresBranches2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐTeamInventoryCountPostgresBranches(ctx context.Context, sel ast.SelectionSet, v postgres.TeamInventoryCountPostgresBranches) graphql.Marshaler { + return ec._TeamInventoryCountPostgresBranches(ctx, sel, &v) } -func (ec *executionContext) marshalNTeamInventoryCountPostgresInstances2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐTeamInventoryCountPostgresInstances(ctx context.Context, sel ast.SelectionSet, v *postgres.TeamInventoryCountPostgresInstances) graphql.Marshaler { +func (ec *executionContext) marshalNTeamInventoryCountPostgresBranches2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐTeamInventoryCountPostgresBranches(ctx context.Context, sel ast.SelectionSet, v *postgres.TeamInventoryCountPostgresBranches) graphql.Marshaler { if v == nil { if !graphql.HasFieldError(ctx, graphql.GetFieldContext(ctx)) { graphql.AddErrorf(ctx, "the requested element is null which the schema does not allow") } return graphql.Null } - return ec._TeamInventoryCountPostgresInstances(ctx, sel, v) + return ec._TeamInventoryCountPostgresBranches(ctx, sel, v) } func (ec *executionContext) marshalOPostgresAccessConnectionDetails2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresAccessConnectionDetails(ctx context.Context, sel ast.SelectionSet, v *postgres.PostgresAccessConnectionDetails) graphql.Marshaler { @@ -4519,40 +4519,40 @@ func (ec *executionContext) marshalOPostgresAccessLevel2ᚖgithubᚗcomᚋnais return v } -func (ec *executionContext) marshalOPostgresInstanceFacets2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceFacets(ctx context.Context, sel ast.SelectionSet, v *postgres.PostgresInstanceFacets) graphql.Marshaler { +func (ec *executionContext) marshalOPostgresBranchFacets2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresBranchFacets(ctx context.Context, sel ast.SelectionSet, v *postgres.PostgresBranchFacets) graphql.Marshaler { if v == nil { return graphql.Null } - return ec._PostgresInstanceFacets(ctx, sel, v) + return ec._PostgresBranchFacets(ctx, sel, v) } -func (ec *executionContext) unmarshalOPostgresInstanceFilter2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceFilter(ctx context.Context, v any) (*postgres.PostgresInstanceFilter, error) { +func (ec *executionContext) unmarshalOPostgresBranchFilter2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresBranchFilter(ctx context.Context, v any) (*postgres.PostgresBranchFilter, error) { if v == nil { return nil, nil } - res, err := ec.unmarshalInputPostgresInstanceFilter(ctx, v) + res, err := ec.unmarshalInputPostgresBranchFilter(ctx, v) return &res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) unmarshalOPostgresInstanceOrder2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceOrder(ctx context.Context, v any) (*postgres.PostgresInstanceOrder, error) { +func (ec *executionContext) unmarshalOPostgresBranchOrder2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresBranchOrder(ctx context.Context, v any) (*postgres.PostgresBranchOrder, error) { if v == nil { return nil, nil } - res, err := ec.unmarshalInputPostgresInstanceOrder(ctx, v) + res, err := ec.unmarshalInputPostgresBranchOrder(ctx, v) return &res, graphql.ErrorOnPath(ctx, err) } -func (ec *executionContext) unmarshalOPostgresInstanceState2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceStateᚄ(ctx context.Context, v any) ([]postgres.PostgresInstanceState, error) { +func (ec *executionContext) unmarshalOPostgresBranchState2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresBranchStateᚄ(ctx context.Context, v any) ([]postgres.PostgresBranchState, error) { if v == nil { return nil, nil } var vSlice []any vSlice = graphql.CoerceList(v) var err error - res := make([]postgres.PostgresInstanceState, len(vSlice)) + res := make([]postgres.PostgresBranchState, len(vSlice)) for i := range vSlice { ctx := graphql.WithPathContext(ctx, graphql.NewPathWithIndex(i)) - res[i], err = ec.unmarshalNPostgresInstanceState2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceState(ctx, vSlice[i]) + res[i], err = ec.unmarshalNPostgresBranchState2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresBranchState(ctx, vSlice[i]) if err != nil { return nil, err } @@ -4560,14 +4560,14 @@ func (ec *executionContext) unmarshalOPostgresInstanceState2ᚕgithubᚗcomᚋna return res, nil } -func (ec *executionContext) marshalOPostgresInstanceState2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceStateᚄ(ctx context.Context, sel ast.SelectionSet, v []postgres.PostgresInstanceState) graphql.Marshaler { +func (ec *executionContext) marshalOPostgresBranchState2ᚕgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresBranchStateᚄ(ctx context.Context, sel ast.SelectionSet, v []postgres.PostgresBranchState) graphql.Marshaler { if v == nil { return graphql.Null } ret := graphql.MarshalSliceConcurrently(ctx, len(v), 0, false, func(ctx context.Context, i int) graphql.Marshaler { fc := graphql.GetFieldContext(ctx) fc.Result = &v[i] - return ec.marshalNPostgresInstanceState2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceState(ctx, sel, v[i]) + return ec.marshalNPostgresBranchState2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresBranchState(ctx, sel, v[i]) }) for _, e := range ret { diff --git a/internal/graph/gengql/root_.generated.go b/internal/graph/gengql/root_.generated.go index 6c2ee5bd3..4ed64b99e 100644 --- a/internal/graph/gengql/root_.generated.go +++ b/internal/graph/gengql/root_.generated.go @@ -106,8 +106,8 @@ type ResolverRoot interface { OpenSearchIssue() OpenSearchIssueResolver OpenSearchMaintenance() OpenSearchMaintenanceResolver PostgresAccess() PostgresAccessResolver - PostgresInstance() PostgresInstanceResolver - PostgresInstanceConnection() PostgresInstanceConnectionResolver + PostgresBranch() PostgresBranchResolver + PostgresBranchConnection() PostgresBranchConnectionResolver PrometheusAlert() PrometheusAlertResolver Query() QueryResolver Reconciler() ReconcilerResolver @@ -261,7 +261,7 @@ type ComplexityRoot struct { Name func(childComplexity int) int NetworkPolicy func(childComplexity int) int OpenSearch func(childComplexity int) int - PostgresInstances func(childComplexity int, orderBy *postgres.PostgresInstanceOrder) int + PostgresBranches func(childComplexity int, orderBy *postgres.PostgresBranchOrder) int Resources func(childComplexity int) int SQLInstances func(childComplexity int, orderBy *sqlinstance.SQLInstanceOrder) int Secrets func(childComplexity int, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor) int @@ -798,8 +798,8 @@ type ComplexityRoot struct { OpenSearchDeleted func(childComplexity int) int } - DeletePostgresPayload struct { - PostgresDeleted func(childComplexity int) int + DeletePostgresBranchPayload struct { + PostgresBranchDeleted func(childComplexity int) int } DeleteSecretPayload struct { @@ -1245,7 +1245,7 @@ type ComplexityRoot struct { Name func(childComplexity int) int NetworkPolicy func(childComplexity int) int OpenSearch func(childComplexity int) int - PostgresInstances func(childComplexity int, orderBy *postgres.PostgresInstanceOrder) int + PostgresBranches func(childComplexity int, orderBy *postgres.PostgresBranchOrder) int Resources func(childComplexity int) int Runs func(childComplexity int, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor) int SQLInstances func(childComplexity int, orderBy *sqlinstance.SQLInstanceOrder) int @@ -1639,7 +1639,7 @@ type ComplexityRoot struct { DeleteJob func(childComplexity int, input job.DeleteJobInput) int DeleteJobRun func(childComplexity int, input job.DeleteJobRunInput) int DeleteOpenSearch func(childComplexity int, input opensearch.DeleteOpenSearchInput) int - DeletePostgres func(childComplexity int, input postgres.DeletePostgresInput) int + DeletePostgresBranch func(childComplexity int, input postgres.DeletePostgresBranchInput) int DeleteSecret func(childComplexity int, input secret.DeleteSecretInput) int DeleteServiceAccount func(childComplexity int, input serviceaccount.DeleteServiceAccountInput) int DeleteServiceAccountToken func(childComplexity int, input serviceaccount.DeleteServiceAccountTokenInput) int @@ -1894,7 +1894,7 @@ type ComplexityRoot struct { } Postgres struct { - ActiveInstance func(childComplexity int) int + ActiveBranch func(childComplexity int) int HighAvailability func(childComplexity int) int ID func(childComplexity int) int Labels func(childComplexity int) int @@ -1904,17 +1904,17 @@ type ComplexityRoot struct { } PostgresAccess struct { - AccessLevel func(childComplexity int) int - Connection func(childComplexity int) int - ExpiresAt func(childComplexity int) int - ID func(childComplexity int) int - Message func(childComplexity int) int - Name func(childComplexity int) int - PostgresInstance func(childComplexity int) int - RelayAccess func(childComplexity int) int - State func(childComplexity int) int - Team func(childComplexity int) int - TeamEnvironment func(childComplexity int) int + AccessLevel func(childComplexity int) int + Connection func(childComplexity int) int + ExpiresAt func(childComplexity int) int + ID func(childComplexity int) int + Message func(childComplexity int) int + Name func(childComplexity int) int + PostgresBranch func(childComplexity int) int + RelayAccess func(childComplexity int) int + State func(childComplexity int) int + Team func(childComplexity int) int + TeamEnvironment func(childComplexity int) int } PostgresAccessConnectionDetails struct { @@ -1927,6 +1927,40 @@ type ComplexityRoot struct { Username func(childComplexity int) int } + PostgresBranch struct { + ID func(childComplexity int) int + Labels func(childComplexity int) int + Name func(childComplexity int) int + Postgres func(childComplexity int) int + State func(childComplexity int) int + Team func(childComplexity int) int + TeamEnvironment func(childComplexity int) int + Workloads func(childComplexity int, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor) int + } + + PostgresBranchConnection struct { + Edges func(childComplexity int) int + Facets func(childComplexity int) int + Nodes func(childComplexity int) int + PageInfo func(childComplexity int) int + } + + PostgresBranchEdge struct { + Cursor func(childComplexity int) int + Node func(childComplexity int) int + } + + PostgresBranchFacets struct { + Environments func(childComplexity int) int + Labels func(childComplexity int) int + States func(childComplexity int) int + } + + PostgresBranchStateFacetItem struct { + Count func(childComplexity int) int + State func(childComplexity int) int + } + PostgresDeletedActivityLogEntry struct { Actor func(childComplexity int) int CreatedAt func(childComplexity int) int @@ -1957,40 +1991,6 @@ type ComplexityRoot struct { Until func(childComplexity int) int } - PostgresInstance struct { - ID func(childComplexity int) int - Labels func(childComplexity int) int - Name func(childComplexity int) int - Postgres func(childComplexity int) int - State func(childComplexity int) int - Team func(childComplexity int) int - TeamEnvironment func(childComplexity int) int - Workloads func(childComplexity int, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor) int - } - - PostgresInstanceConnection struct { - Edges func(childComplexity int) int - Facets func(childComplexity int) int - Nodes func(childComplexity int) int - PageInfo func(childComplexity int) int - } - - PostgresInstanceEdge struct { - Cursor func(childComplexity int) int - Node func(childComplexity int) int - } - - PostgresInstanceFacets struct { - Environments func(childComplexity int) int - Labels func(childComplexity int) int - States func(childComplexity int) int - } - - PostgresInstanceStateFacetItem struct { - Count func(childComplexity int) int - State func(childComplexity int) int - } - PostgresPersonalAccessConnectionActivityLogEntry struct { Actor func(childComplexity int) int CreatedAt func(childComplexity int) int @@ -2928,7 +2928,7 @@ type ComplexityRoot struct { Member func(childComplexity int, email string) int Members func(childComplexity int, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *team.TeamMemberOrder) int OpenSearches func(childComplexity int, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *opensearch.OpenSearchOrder, filter *opensearch.OpenSearchFilter) int - PostgresInstances func(childComplexity int, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *postgres.PostgresInstanceOrder, filter *postgres.PostgresInstanceFilter) int + PostgresBranches func(childComplexity int, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *postgres.PostgresBranchOrder, filter *postgres.PostgresBranchFilter) int Purpose func(childComplexity int) int Repositories func(childComplexity int, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *repository.RepositoryOrder, filter *repository.TeamRepositoryFilter) int SQLInstances func(childComplexity int, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *sqlinstance.SQLInstanceOrder, filter *sqlinstance.SQLInstanceFilter) int @@ -3059,7 +3059,7 @@ type ComplexityRoot struct { OpenSearch func(childComplexity int, name string) int Postgres func(childComplexity int, name string) int PostgresAccess func(childComplexity int, name string) int - PostgresInstance func(childComplexity int, name string) int + PostgresBranch func(childComplexity int, name string) int SQLInstance func(childComplexity int, name string) int Secret func(childComplexity int, name string) int SlackAlertsChannel func(childComplexity int) int @@ -3156,7 +3156,7 @@ type ComplexityRoot struct { Total func(childComplexity int) int } - TeamInventoryCountPostgresInstances struct { + TeamInventoryCountPostgresBranches struct { Total func(childComplexity int) int } @@ -3173,17 +3173,17 @@ type ComplexityRoot struct { } TeamInventoryCounts struct { - Applications func(childComplexity int) int - BigQueryDatasets func(childComplexity int) int - Buckets func(childComplexity int) int - Configs func(childComplexity int) int - Jobs func(childComplexity int) int - KafkaTopics func(childComplexity int) int - OpenSearches func(childComplexity int) int - PostgresInstances func(childComplexity int) int - SQLInstances func(childComplexity int) int - Secrets func(childComplexity int) int - Valkeys func(childComplexity int) int + Applications func(childComplexity int) int + BigQueryDatasets func(childComplexity int) int + Buckets func(childComplexity int) int + Configs func(childComplexity int) int + Jobs func(childComplexity int) int + KafkaTopics func(childComplexity int) int + OpenSearches func(childComplexity int) int + PostgresBranches func(childComplexity int) int + SQLInstances func(childComplexity int) int + Secrets func(childComplexity int) int + Valkeys func(childComplexity int) int } TeamMember struct { @@ -4385,17 +4385,17 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.Application.OpenSearch(childComplexity), true - case "Application.postgresInstances": - if e.ComplexityRoot.Application.PostgresInstances == nil { + case "Application.postgresBranches": + if e.ComplexityRoot.Application.PostgresBranches == nil { break } - args, err := ec.field_Application_postgresInstances_args(ctx, rawArgs) + args, err := ec.field_Application_postgresBranches_args(ctx, rawArgs) if err != nil { return 0, false } - return e.ComplexityRoot.Application.PostgresInstances(childComplexity, args["orderBy"].(*postgres.PostgresInstanceOrder)), true + return e.ComplexityRoot.Application.PostgresBranches(childComplexity, args["orderBy"].(*postgres.PostgresBranchOrder)), true case "Application.resources": if e.ComplexityRoot.Application.Resources == nil { @@ -6525,12 +6525,12 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.DeleteOpenSearchPayload.OpenSearchDeleted(childComplexity), true - case "DeletePostgresPayload.postgresDeleted": - if e.ComplexityRoot.DeletePostgresPayload.PostgresDeleted == nil { + case "DeletePostgresBranchPayload.postgresBranchDeleted": + if e.ComplexityRoot.DeletePostgresBranchPayload.PostgresBranchDeleted == nil { break } - return e.ComplexityRoot.DeletePostgresPayload.PostgresDeleted(childComplexity), true + return e.ComplexityRoot.DeletePostgresBranchPayload.PostgresBranchDeleted(childComplexity), true case "DeleteSecretPayload.secretDeleted": if e.ComplexityRoot.DeleteSecretPayload.SecretDeleted == nil { @@ -8405,17 +8405,17 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.Job.OpenSearch(childComplexity), true - case "Job.postgresInstances": - if e.ComplexityRoot.Job.PostgresInstances == nil { + case "Job.postgresBranches": + if e.ComplexityRoot.Job.PostgresBranches == nil { break } - args, err := ec.field_Job_postgresInstances_args(ctx, rawArgs) + args, err := ec.field_Job_postgresBranches_args(ctx, rawArgs) if err != nil { return 0, false } - return e.ComplexityRoot.Job.PostgresInstances(childComplexity, args["orderBy"].(*postgres.PostgresInstanceOrder)), true + return e.ComplexityRoot.Job.PostgresBranches(childComplexity, args["orderBy"].(*postgres.PostgresBranchOrder)), true case "Job.resources": if e.ComplexityRoot.Job.Resources == nil { @@ -10251,17 +10251,17 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.Mutation.DeleteOpenSearch(childComplexity, args["input"].(opensearch.DeleteOpenSearchInput)), true - case "Mutation.deletePostgres": - if e.ComplexityRoot.Mutation.DeletePostgres == nil { + case "Mutation.deletePostgresBranch": + if e.ComplexityRoot.Mutation.DeletePostgresBranch == nil { break } - args, err := ec.field_Mutation_deletePostgres_args(ctx, rawArgs) + args, err := ec.field_Mutation_deletePostgresBranch_args(ctx, rawArgs) if err != nil { return 0, false } - return e.ComplexityRoot.Mutation.DeletePostgres(childComplexity, args["input"].(postgres.DeletePostgresInput)), true + return e.ComplexityRoot.Mutation.DeletePostgresBranch(childComplexity, args["input"].(postgres.DeletePostgresBranchInput)), true case "Mutation.deleteSecret": if e.ComplexityRoot.Mutation.DeleteSecret == nil { @@ -11642,12 +11642,12 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.PageInfo.TotalCount(childComplexity), true - case "Postgres.activeInstance": - if e.ComplexityRoot.Postgres.ActiveInstance == nil { + case "Postgres.activeBranch": + if e.ComplexityRoot.Postgres.ActiveBranch == nil { break } - return e.ComplexityRoot.Postgres.ActiveInstance(childComplexity), true + return e.ComplexityRoot.Postgres.ActiveBranch(childComplexity), true case "Postgres.highAvailability": if e.ComplexityRoot.Postgres.HighAvailability == nil { @@ -11733,12 +11733,12 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.PostgresAccess.Name(childComplexity), true - case "PostgresAccess.postgresInstance": - if e.ComplexityRoot.PostgresAccess.PostgresInstance == nil { + case "PostgresAccess.postgresBranch": + if e.ComplexityRoot.PostgresAccess.PostgresBranch == nil { break } - return e.ComplexityRoot.PostgresAccess.PostgresInstance(childComplexity), true + return e.ComplexityRoot.PostgresAccess.PostgresBranch(childComplexity), true case "PostgresAccess.relayAccess": if e.ComplexityRoot.PostgresAccess.RelayAccess == nil { @@ -11817,290 +11817,290 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.PostgresAccessConnectionDetails.Username(childComplexity), true - case "PostgresDeletedActivityLogEntry.actor": - if e.ComplexityRoot.PostgresDeletedActivityLogEntry.Actor == nil { + case "PostgresBranch.id": + if e.ComplexityRoot.PostgresBranch.ID == nil { break } - return e.ComplexityRoot.PostgresDeletedActivityLogEntry.Actor(childComplexity), true + return e.ComplexityRoot.PostgresBranch.ID(childComplexity), true - case "PostgresDeletedActivityLogEntry.createdAt": - if e.ComplexityRoot.PostgresDeletedActivityLogEntry.CreatedAt == nil { + case "PostgresBranch.labels": + if e.ComplexityRoot.PostgresBranch.Labels == nil { break } - return e.ComplexityRoot.PostgresDeletedActivityLogEntry.CreatedAt(childComplexity), true + return e.ComplexityRoot.PostgresBranch.Labels(childComplexity), true - case "PostgresDeletedActivityLogEntry.environmentName": - if e.ComplexityRoot.PostgresDeletedActivityLogEntry.EnvironmentName == nil { + case "PostgresBranch.name": + if e.ComplexityRoot.PostgresBranch.Name == nil { break } - return e.ComplexityRoot.PostgresDeletedActivityLogEntry.EnvironmentName(childComplexity), true + return e.ComplexityRoot.PostgresBranch.Name(childComplexity), true - case "PostgresDeletedActivityLogEntry.gitHubActorClaims": - if e.ComplexityRoot.PostgresDeletedActivityLogEntry.GitHubActorClaims == nil { + case "PostgresBranch.postgres": + if e.ComplexityRoot.PostgresBranch.Postgres == nil { break } - return e.ComplexityRoot.PostgresDeletedActivityLogEntry.GitHubActorClaims(childComplexity), true + return e.ComplexityRoot.PostgresBranch.Postgres(childComplexity), true - case "PostgresDeletedActivityLogEntry.id": - if e.ComplexityRoot.PostgresDeletedActivityLogEntry.ID == nil { + case "PostgresBranch.state": + if e.ComplexityRoot.PostgresBranch.State == nil { break } - return e.ComplexityRoot.PostgresDeletedActivityLogEntry.ID(childComplexity), true + return e.ComplexityRoot.PostgresBranch.State(childComplexity), true - case "PostgresDeletedActivityLogEntry.message": - if e.ComplexityRoot.PostgresDeletedActivityLogEntry.Message == nil { + case "PostgresBranch.team": + if e.ComplexityRoot.PostgresBranch.Team == nil { break } - return e.ComplexityRoot.PostgresDeletedActivityLogEntry.Message(childComplexity), true + return e.ComplexityRoot.PostgresBranch.Team(childComplexity), true - case "PostgresDeletedActivityLogEntry.resourceName": - if e.ComplexityRoot.PostgresDeletedActivityLogEntry.ResourceName == nil { + case "PostgresBranch.teamEnvironment": + if e.ComplexityRoot.PostgresBranch.TeamEnvironment == nil { break } - return e.ComplexityRoot.PostgresDeletedActivityLogEntry.ResourceName(childComplexity), true + return e.ComplexityRoot.PostgresBranch.TeamEnvironment(childComplexity), true - case "PostgresDeletedActivityLogEntry.resourceType": - if e.ComplexityRoot.PostgresDeletedActivityLogEntry.ResourceType == nil { + case "PostgresBranch.workloads": + if e.ComplexityRoot.PostgresBranch.Workloads == nil { break } - return e.ComplexityRoot.PostgresDeletedActivityLogEntry.ResourceType(childComplexity), true - - case "PostgresDeletedActivityLogEntry.teamSlug": - if e.ComplexityRoot.PostgresDeletedActivityLogEntry.TeamSlug == nil { - break + args, err := ec.field_PostgresBranch_workloads_args(ctx, rawArgs) + if err != nil { + return 0, false } - return e.ComplexityRoot.PostgresDeletedActivityLogEntry.TeamSlug(childComplexity), true + return e.ComplexityRoot.PostgresBranch.Workloads(childComplexity, args["first"].(*int), args["after"].(*pagination.Cursor), args["last"].(*int), args["before"].(*pagination.Cursor)), true - case "PostgresGrantAccessActivityLogEntry.actor": - if e.ComplexityRoot.PostgresGrantAccessActivityLogEntry.Actor == nil { + case "PostgresBranchConnection.edges": + if e.ComplexityRoot.PostgresBranchConnection.Edges == nil { break } - return e.ComplexityRoot.PostgresGrantAccessActivityLogEntry.Actor(childComplexity), true + return e.ComplexityRoot.PostgresBranchConnection.Edges(childComplexity), true - case "PostgresGrantAccessActivityLogEntry.createdAt": - if e.ComplexityRoot.PostgresGrantAccessActivityLogEntry.CreatedAt == nil { + case "PostgresBranchConnection.facets": + if e.ComplexityRoot.PostgresBranchConnection.Facets == nil { break } - return e.ComplexityRoot.PostgresGrantAccessActivityLogEntry.CreatedAt(childComplexity), true + return e.ComplexityRoot.PostgresBranchConnection.Facets(childComplexity), true - case "PostgresGrantAccessActivityLogEntry.data": - if e.ComplexityRoot.PostgresGrantAccessActivityLogEntry.Data == nil { + case "PostgresBranchConnection.nodes": + if e.ComplexityRoot.PostgresBranchConnection.Nodes == nil { break } - return e.ComplexityRoot.PostgresGrantAccessActivityLogEntry.Data(childComplexity), true + return e.ComplexityRoot.PostgresBranchConnection.Nodes(childComplexity), true - case "PostgresGrantAccessActivityLogEntry.environmentName": - if e.ComplexityRoot.PostgresGrantAccessActivityLogEntry.EnvironmentName == nil { + case "PostgresBranchConnection.pageInfo": + if e.ComplexityRoot.PostgresBranchConnection.PageInfo == nil { break } - return e.ComplexityRoot.PostgresGrantAccessActivityLogEntry.EnvironmentName(childComplexity), true + return e.ComplexityRoot.PostgresBranchConnection.PageInfo(childComplexity), true - case "PostgresGrantAccessActivityLogEntry.gitHubActorClaims": - if e.ComplexityRoot.PostgresGrantAccessActivityLogEntry.GitHubActorClaims == nil { + case "PostgresBranchEdge.cursor": + if e.ComplexityRoot.PostgresBranchEdge.Cursor == nil { break } - return e.ComplexityRoot.PostgresGrantAccessActivityLogEntry.GitHubActorClaims(childComplexity), true + return e.ComplexityRoot.PostgresBranchEdge.Cursor(childComplexity), true - case "PostgresGrantAccessActivityLogEntry.id": - if e.ComplexityRoot.PostgresGrantAccessActivityLogEntry.ID == nil { + case "PostgresBranchEdge.node": + if e.ComplexityRoot.PostgresBranchEdge.Node == nil { break } - return e.ComplexityRoot.PostgresGrantAccessActivityLogEntry.ID(childComplexity), true + return e.ComplexityRoot.PostgresBranchEdge.Node(childComplexity), true - case "PostgresGrantAccessActivityLogEntry.message": - if e.ComplexityRoot.PostgresGrantAccessActivityLogEntry.Message == nil { + case "PostgresBranchFacets.environments": + if e.ComplexityRoot.PostgresBranchFacets.Environments == nil { break } - return e.ComplexityRoot.PostgresGrantAccessActivityLogEntry.Message(childComplexity), true + return e.ComplexityRoot.PostgresBranchFacets.Environments(childComplexity), true - case "PostgresGrantAccessActivityLogEntry.resourceName": - if e.ComplexityRoot.PostgresGrantAccessActivityLogEntry.ResourceName == nil { + case "PostgresBranchFacets.labels": + if e.ComplexityRoot.PostgresBranchFacets.Labels == nil { break } - return e.ComplexityRoot.PostgresGrantAccessActivityLogEntry.ResourceName(childComplexity), true + return e.ComplexityRoot.PostgresBranchFacets.Labels(childComplexity), true - case "PostgresGrantAccessActivityLogEntry.resourceType": - if e.ComplexityRoot.PostgresGrantAccessActivityLogEntry.ResourceType == nil { + case "PostgresBranchFacets.states": + if e.ComplexityRoot.PostgresBranchFacets.States == nil { break } - return e.ComplexityRoot.PostgresGrantAccessActivityLogEntry.ResourceType(childComplexity), true + return e.ComplexityRoot.PostgresBranchFacets.States(childComplexity), true - case "PostgresGrantAccessActivityLogEntry.teamSlug": - if e.ComplexityRoot.PostgresGrantAccessActivityLogEntry.TeamSlug == nil { + case "PostgresBranchStateFacetItem.count": + if e.ComplexityRoot.PostgresBranchStateFacetItem.Count == nil { break } - return e.ComplexityRoot.PostgresGrantAccessActivityLogEntry.TeamSlug(childComplexity), true + return e.ComplexityRoot.PostgresBranchStateFacetItem.Count(childComplexity), true - case "PostgresGrantAccessActivityLogEntryData.grantee": - if e.ComplexityRoot.PostgresGrantAccessActivityLogEntryData.Grantee == nil { + case "PostgresBranchStateFacetItem.state": + if e.ComplexityRoot.PostgresBranchStateFacetItem.State == nil { break } - return e.ComplexityRoot.PostgresGrantAccessActivityLogEntryData.Grantee(childComplexity), true + return e.ComplexityRoot.PostgresBranchStateFacetItem.State(childComplexity), true - case "PostgresGrantAccessActivityLogEntryData.until": - if e.ComplexityRoot.PostgresGrantAccessActivityLogEntryData.Until == nil { + case "PostgresDeletedActivityLogEntry.actor": + if e.ComplexityRoot.PostgresDeletedActivityLogEntry.Actor == nil { break } - return e.ComplexityRoot.PostgresGrantAccessActivityLogEntryData.Until(childComplexity), true + return e.ComplexityRoot.PostgresDeletedActivityLogEntry.Actor(childComplexity), true - case "PostgresInstance.id": - if e.ComplexityRoot.PostgresInstance.ID == nil { + case "PostgresDeletedActivityLogEntry.createdAt": + if e.ComplexityRoot.PostgresDeletedActivityLogEntry.CreatedAt == nil { break } - return e.ComplexityRoot.PostgresInstance.ID(childComplexity), true + return e.ComplexityRoot.PostgresDeletedActivityLogEntry.CreatedAt(childComplexity), true - case "PostgresInstance.labels": - if e.ComplexityRoot.PostgresInstance.Labels == nil { + case "PostgresDeletedActivityLogEntry.environmentName": + if e.ComplexityRoot.PostgresDeletedActivityLogEntry.EnvironmentName == nil { break } - return e.ComplexityRoot.PostgresInstance.Labels(childComplexity), true + return e.ComplexityRoot.PostgresDeletedActivityLogEntry.EnvironmentName(childComplexity), true - case "PostgresInstance.name": - if e.ComplexityRoot.PostgresInstance.Name == nil { + case "PostgresDeletedActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.PostgresDeletedActivityLogEntry.GitHubActorClaims == nil { break } - return e.ComplexityRoot.PostgresInstance.Name(childComplexity), true + return e.ComplexityRoot.PostgresDeletedActivityLogEntry.GitHubActorClaims(childComplexity), true - case "PostgresInstance.postgres": - if e.ComplexityRoot.PostgresInstance.Postgres == nil { + case "PostgresDeletedActivityLogEntry.id": + if e.ComplexityRoot.PostgresDeletedActivityLogEntry.ID == nil { break } - return e.ComplexityRoot.PostgresInstance.Postgres(childComplexity), true + return e.ComplexityRoot.PostgresDeletedActivityLogEntry.ID(childComplexity), true - case "PostgresInstance.state": - if e.ComplexityRoot.PostgresInstance.State == nil { + case "PostgresDeletedActivityLogEntry.message": + if e.ComplexityRoot.PostgresDeletedActivityLogEntry.Message == nil { break } - return e.ComplexityRoot.PostgresInstance.State(childComplexity), true + return e.ComplexityRoot.PostgresDeletedActivityLogEntry.Message(childComplexity), true - case "PostgresInstance.team": - if e.ComplexityRoot.PostgresInstance.Team == nil { + case "PostgresDeletedActivityLogEntry.resourceName": + if e.ComplexityRoot.PostgresDeletedActivityLogEntry.ResourceName == nil { break } - return e.ComplexityRoot.PostgresInstance.Team(childComplexity), true + return e.ComplexityRoot.PostgresDeletedActivityLogEntry.ResourceName(childComplexity), true - case "PostgresInstance.teamEnvironment": - if e.ComplexityRoot.PostgresInstance.TeamEnvironment == nil { + case "PostgresDeletedActivityLogEntry.resourceType": + if e.ComplexityRoot.PostgresDeletedActivityLogEntry.ResourceType == nil { break } - return e.ComplexityRoot.PostgresInstance.TeamEnvironment(childComplexity), true + return e.ComplexityRoot.PostgresDeletedActivityLogEntry.ResourceType(childComplexity), true - case "PostgresInstance.workloads": - if e.ComplexityRoot.PostgresInstance.Workloads == nil { + case "PostgresDeletedActivityLogEntry.teamSlug": + if e.ComplexityRoot.PostgresDeletedActivityLogEntry.TeamSlug == nil { break } - args, err := ec.field_PostgresInstance_workloads_args(ctx, rawArgs) - if err != nil { - return 0, false + return e.ComplexityRoot.PostgresDeletedActivityLogEntry.TeamSlug(childComplexity), true + + case "PostgresGrantAccessActivityLogEntry.actor": + if e.ComplexityRoot.PostgresGrantAccessActivityLogEntry.Actor == nil { + break } - return e.ComplexityRoot.PostgresInstance.Workloads(childComplexity, args["first"].(*int), args["after"].(*pagination.Cursor), args["last"].(*int), args["before"].(*pagination.Cursor)), true + return e.ComplexityRoot.PostgresGrantAccessActivityLogEntry.Actor(childComplexity), true - case "PostgresInstanceConnection.edges": - if e.ComplexityRoot.PostgresInstanceConnection.Edges == nil { + case "PostgresGrantAccessActivityLogEntry.createdAt": + if e.ComplexityRoot.PostgresGrantAccessActivityLogEntry.CreatedAt == nil { break } - return e.ComplexityRoot.PostgresInstanceConnection.Edges(childComplexity), true + return e.ComplexityRoot.PostgresGrantAccessActivityLogEntry.CreatedAt(childComplexity), true - case "PostgresInstanceConnection.facets": - if e.ComplexityRoot.PostgresInstanceConnection.Facets == nil { + case "PostgresGrantAccessActivityLogEntry.data": + if e.ComplexityRoot.PostgresGrantAccessActivityLogEntry.Data == nil { break } - return e.ComplexityRoot.PostgresInstanceConnection.Facets(childComplexity), true + return e.ComplexityRoot.PostgresGrantAccessActivityLogEntry.Data(childComplexity), true - case "PostgresInstanceConnection.nodes": - if e.ComplexityRoot.PostgresInstanceConnection.Nodes == nil { + case "PostgresGrantAccessActivityLogEntry.environmentName": + if e.ComplexityRoot.PostgresGrantAccessActivityLogEntry.EnvironmentName == nil { break } - return e.ComplexityRoot.PostgresInstanceConnection.Nodes(childComplexity), true + return e.ComplexityRoot.PostgresGrantAccessActivityLogEntry.EnvironmentName(childComplexity), true - case "PostgresInstanceConnection.pageInfo": - if e.ComplexityRoot.PostgresInstanceConnection.PageInfo == nil { + case "PostgresGrantAccessActivityLogEntry.gitHubActorClaims": + if e.ComplexityRoot.PostgresGrantAccessActivityLogEntry.GitHubActorClaims == nil { break } - return e.ComplexityRoot.PostgresInstanceConnection.PageInfo(childComplexity), true + return e.ComplexityRoot.PostgresGrantAccessActivityLogEntry.GitHubActorClaims(childComplexity), true - case "PostgresInstanceEdge.cursor": - if e.ComplexityRoot.PostgresInstanceEdge.Cursor == nil { + case "PostgresGrantAccessActivityLogEntry.id": + if e.ComplexityRoot.PostgresGrantAccessActivityLogEntry.ID == nil { break } - return e.ComplexityRoot.PostgresInstanceEdge.Cursor(childComplexity), true + return e.ComplexityRoot.PostgresGrantAccessActivityLogEntry.ID(childComplexity), true - case "PostgresInstanceEdge.node": - if e.ComplexityRoot.PostgresInstanceEdge.Node == nil { + case "PostgresGrantAccessActivityLogEntry.message": + if e.ComplexityRoot.PostgresGrantAccessActivityLogEntry.Message == nil { break } - return e.ComplexityRoot.PostgresInstanceEdge.Node(childComplexity), true + return e.ComplexityRoot.PostgresGrantAccessActivityLogEntry.Message(childComplexity), true - case "PostgresInstanceFacets.environments": - if e.ComplexityRoot.PostgresInstanceFacets.Environments == nil { + case "PostgresGrantAccessActivityLogEntry.resourceName": + if e.ComplexityRoot.PostgresGrantAccessActivityLogEntry.ResourceName == nil { break } - return e.ComplexityRoot.PostgresInstanceFacets.Environments(childComplexity), true + return e.ComplexityRoot.PostgresGrantAccessActivityLogEntry.ResourceName(childComplexity), true - case "PostgresInstanceFacets.labels": - if e.ComplexityRoot.PostgresInstanceFacets.Labels == nil { + case "PostgresGrantAccessActivityLogEntry.resourceType": + if e.ComplexityRoot.PostgresGrantAccessActivityLogEntry.ResourceType == nil { break } - return e.ComplexityRoot.PostgresInstanceFacets.Labels(childComplexity), true + return e.ComplexityRoot.PostgresGrantAccessActivityLogEntry.ResourceType(childComplexity), true - case "PostgresInstanceFacets.states": - if e.ComplexityRoot.PostgresInstanceFacets.States == nil { + case "PostgresGrantAccessActivityLogEntry.teamSlug": + if e.ComplexityRoot.PostgresGrantAccessActivityLogEntry.TeamSlug == nil { break } - return e.ComplexityRoot.PostgresInstanceFacets.States(childComplexity), true + return e.ComplexityRoot.PostgresGrantAccessActivityLogEntry.TeamSlug(childComplexity), true - case "PostgresInstanceStateFacetItem.count": - if e.ComplexityRoot.PostgresInstanceStateFacetItem.Count == nil { + case "PostgresGrantAccessActivityLogEntryData.grantee": + if e.ComplexityRoot.PostgresGrantAccessActivityLogEntryData.Grantee == nil { break } - return e.ComplexityRoot.PostgresInstanceStateFacetItem.Count(childComplexity), true + return e.ComplexityRoot.PostgresGrantAccessActivityLogEntryData.Grantee(childComplexity), true - case "PostgresInstanceStateFacetItem.state": - if e.ComplexityRoot.PostgresInstanceStateFacetItem.State == nil { + case "PostgresGrantAccessActivityLogEntryData.until": + if e.ComplexityRoot.PostgresGrantAccessActivityLogEntryData.Until == nil { break } - return e.ComplexityRoot.PostgresInstanceStateFacetItem.State(childComplexity), true + return e.ComplexityRoot.PostgresGrantAccessActivityLogEntryData.Until(childComplexity), true case "PostgresPersonalAccessConnectionActivityLogEntry.actor": if e.ComplexityRoot.PostgresPersonalAccessConnectionActivityLogEntry.Actor == nil { @@ -16457,17 +16457,17 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.Team.OpenSearches(childComplexity, args["first"].(*int), args["after"].(*pagination.Cursor), args["last"].(*int), args["before"].(*pagination.Cursor), args["orderBy"].(*opensearch.OpenSearchOrder), args["filter"].(*opensearch.OpenSearchFilter)), true - case "Team.postgresInstances": - if e.ComplexityRoot.Team.PostgresInstances == nil { + case "Team.postgresBranches": + if e.ComplexityRoot.Team.PostgresBranches == nil { break } - args, err := ec.field_Team_postgresInstances_args(ctx, rawArgs) + args, err := ec.field_Team_postgresBranches_args(ctx, rawArgs) if err != nil { return 0, false } - return e.ComplexityRoot.Team.PostgresInstances(childComplexity, args["first"].(*int), args["after"].(*pagination.Cursor), args["last"].(*int), args["before"].(*pagination.Cursor), args["orderBy"].(*postgres.PostgresInstanceOrder), args["filter"].(*postgres.PostgresInstanceFilter)), true + return e.ComplexityRoot.Team.PostgresBranches(childComplexity, args["first"].(*int), args["after"].(*pagination.Cursor), args["last"].(*int), args["before"].(*pagination.Cursor), args["orderBy"].(*postgres.PostgresBranchOrder), args["filter"].(*postgres.PostgresBranchFilter)), true case "Team.purpose": if e.ComplexityRoot.Team.Purpose == nil { @@ -17190,17 +17190,17 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.TeamEnvironment.PostgresAccess(childComplexity, args["name"].(string)), true - case "TeamEnvironment.postgresInstance": - if e.ComplexityRoot.TeamEnvironment.PostgresInstance == nil { + case "TeamEnvironment.postgresBranch": + if e.ComplexityRoot.TeamEnvironment.PostgresBranch == nil { break } - args, err := ec.field_TeamEnvironment_postgresInstance_args(ctx, rawArgs) + args, err := ec.field_TeamEnvironment_postgresBranch_args(ctx, rawArgs) if err != nil { return 0, false } - return e.ComplexityRoot.TeamEnvironment.PostgresInstance(childComplexity, args["name"].(string)), true + return e.ComplexityRoot.TeamEnvironment.PostgresBranch(childComplexity, args["name"].(string)), true case "TeamEnvironment.sqlInstance": if e.ComplexityRoot.TeamEnvironment.SQLInstance == nil { @@ -17554,12 +17554,12 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.TeamInventoryCountOpenSearches.Total(childComplexity), true - case "TeamInventoryCountPostgresInstances.total": - if e.ComplexityRoot.TeamInventoryCountPostgresInstances.Total == nil { + case "TeamInventoryCountPostgresBranches.total": + if e.ComplexityRoot.TeamInventoryCountPostgresBranches.Total == nil { break } - return e.ComplexityRoot.TeamInventoryCountPostgresInstances.Total(childComplexity), true + return e.ComplexityRoot.TeamInventoryCountPostgresBranches.Total(childComplexity), true case "TeamInventoryCountSecrets.total": if e.ComplexityRoot.TeamInventoryCountSecrets.Total == nil { @@ -17631,12 +17631,12 @@ func (e *executableSchema) Complexity(ctx context.Context, typeName, field strin return e.ComplexityRoot.TeamInventoryCounts.OpenSearches(childComplexity), true - case "TeamInventoryCounts.postgresInstances": - if e.ComplexityRoot.TeamInventoryCounts.PostgresInstances == nil { + case "TeamInventoryCounts.postgresBranches": + if e.ComplexityRoot.TeamInventoryCounts.PostgresBranches == nil { break } - return e.ComplexityRoot.TeamInventoryCounts.PostgresInstances(childComplexity), true + return e.ComplexityRoot.TeamInventoryCounts.PostgresBranches(childComplexity), true case "TeamInventoryCounts.sqlInstances": if e.ComplexityRoot.TeamInventoryCounts.SQLInstances == nil { @@ -20902,7 +20902,7 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { ec.unmarshalInputDeleteJobInput, ec.unmarshalInputDeleteJobRunInput, ec.unmarshalInputDeleteOpenSearchInput, - ec.unmarshalInputDeletePostgresInput, + ec.unmarshalInputDeletePostgresBranchInput, ec.unmarshalInputDeleteSecretInput, ec.unmarshalInputDeleteServiceAccountInput, ec.unmarshalInputDeleteServiceAccountTokenInput, @@ -20934,8 +20934,8 @@ func (e *executableSchema) Exec(ctx context.Context) graphql.ResponseHandler { ec.unmarshalInputOpenSearchAccessOrder, ec.unmarshalInputOpenSearchFilter, ec.unmarshalInputOpenSearchOrder, - ec.unmarshalInputPostgresInstanceFilter, - ec.unmarshalInputPostgresInstanceOrder, + ec.unmarshalInputPostgresBranchFilter, + ec.unmarshalInputPostgresBranchOrder, ec.unmarshalInputReconcilerConfigInput, ec.unmarshalInputRemoveConfigValueInput, ec.unmarshalInputRemoveRepositoryFromTeamInput, @@ -27404,8 +27404,8 @@ type WorkloadLogLine { } `, BuiltIn: false}, {Name: "../schema/postgres.graphqls", Input: `extend type Team { - "Postgres instances owned by the team." - postgresInstances( + "Postgres branches owned by the team." + postgresBranches( "Get the first n items in the connection. This can be used in combination with the after parameter." first: Int @@ -27419,21 +27419,21 @@ type WorkloadLogLine { before: Cursor "Ordering options for items returned from the connection." - orderBy: PostgresInstanceOrder + orderBy: PostgresBranchOrder "Filtering options for items returned from the connection." - filter: PostgresInstanceFilter - ): PostgresInstanceConnection! + filter: PostgresBranchFilter + ): PostgresBranchConnection! } extend type TeamEnvironment { "Postgres in the team environment." postgres("Name of the Postgres in this team environment." name: String!): Postgres! - "Named PostgresInstance in the team environment." - postgresInstance( - "Name of the PostgresInstance in this team environment." + "Named PostgresBranch in the team environment." + postgresBranch( + "Name of the PostgresBranch in this team environment." name: String! - ): PostgresInstance! + ): PostgresBranch! """ EXPERIMENTAL: DO NOT USE Get a PostgresAccess and its state. Available to authorized team members. @@ -27445,65 +27445,65 @@ extend type TeamEnvironment { } extend interface Workload { - "Active PostgresInstances for all Postgres entries in uses.postgres." - postgresInstances( + "Active PostgresBranches for all Postgres entries in uses.postgres." + postgresBranches( "Ordering options for items returned from the connection." - orderBy: PostgresInstanceOrder - ): PostgresInstanceConnection! + orderBy: PostgresBranchOrder + ): PostgresBranchConnection! } extend type Application { - "Active PostgresInstances for all Postgres entries in uses.postgres." - postgresInstances( + "Active PostgresBranches for all Postgres entries in uses.postgres." + postgresBranches( "Ordering options for items returned from the connection." - orderBy: PostgresInstanceOrder - ): PostgresInstanceConnection! + orderBy: PostgresBranchOrder + ): PostgresBranchConnection! } extend type Job { - "Active PostgresInstances for all Postgres entries in uses.postgres." - postgresInstances( + "Active PostgresBranches for all Postgres entries in uses.postgres." + postgresBranches( "Ordering options for items returned from the connection." - orderBy: PostgresInstanceOrder - ): PostgresInstanceConnection! + orderBy: PostgresBranchOrder + ): PostgresBranchConnection! } -input PostgresInstanceOrder { - field: PostgresInstanceOrderField! +input PostgresBranchOrder { + field: PostgresBranchOrderField! direction: OrderDirection! } """ -Input for filtering Postgres instances. +Input for filtering Postgres branches. """ -input PostgresInstanceFilter { - "Filter by the name of the instance." +input PostgresBranchFilter { + "Filter by the name of the branch." name: String "Filter by environments." environments: [String!] - "Filter by instance state." - states: [PostgresInstanceState!] + "Filter by branch state." + states: [PostgresBranchState!] "Filter by user-defined labels. All listed labels must match." labels: [LabelFilter!] } -enum PostgresInstanceOrderField { +enum PostgresBranchOrderField { NAME ENVIRONMENT } -"A named PostgresInstance belonging to a Postgres." -type PostgresInstance implements Persistence & Node { +"A named PostgresBranch belonging to a Postgres." +type PostgresBranch implements Persistence & Node { id: ID! name: String! team: Team! teamEnvironment: TeamEnvironment! - "Postgres owning this PostgresInstance." + "Postgres owning this PostgresBranch." postgres: Postgres! - "Workloads using this instance while it is active." + "Workloads using this branch while it is active." workloads( "Get the first n items in the connection. This can be used in combination with the after parameter." first: Int @@ -27517,13 +27517,13 @@ type PostgresInstance implements Persistence & Node { "Get items before this cursor." before: Cursor ): WorkloadConnection! - "Current observed state of the instance." - state: PostgresInstanceState! - "User-defined labels on this instance." + "Current observed state of the branch." + state: PostgresBranchState! + "User-defined labels on this branch." labels: [ResourceLabel!]! } -"A Postgres whose active instance can change." +"A Postgres whose active branch can change." type Postgres implements Node { "Opaque identifier for this Postgres." id: ID! @@ -27535,8 +27535,8 @@ type Postgres implements Node { highAvailability: Boolean! "Requested CPU, memory and disk size, when present on this Postgres." resources: PostgresResources! - "Name of the currently active PostgresInstance, if selected." - activeInstance: String + "Name of the currently active PostgresBranch, if selected." + activeBranch: String "User-defined labels on this Postgres." labels: [ResourceLabel!]! } @@ -27551,62 +27551,62 @@ type PostgresResources { diskSize: String } -"Reconciliation and observed health of a PostgresInstance." -enum PostgresInstanceState { - "The instance is healthy and ready." +"Reconciliation and observed health of a PostgresBranch." +enum PostgresBranchState { + "The branch is healthy and ready." AVAILABLE - "The instance is provisioning or its state has not been observed yet." + "The branch is provisioning or its state has not been observed yet." PROGRESSING - "The instance has reported a failure." + "The branch has reported a failure." DEGRADED } -type PostgresInstanceConnection { +type PostgresBranchConnection { pageInfo: PageInfo! - nodes: [PostgresInstance!]! - edges: [PostgresInstanceEdge!]! + nodes: [PostgresBranch!]! + edges: [PostgresBranchEdge!]! """ - Facets for Postgres instances. Provides distribution counts to help narrow down results. + Facets for Postgres branches. Provides distribution counts to help narrow down results. Facet counts are computed over the full result set (ignoring pagination) but respect the current filter. """ - facets: PostgresInstanceFacets + facets: PostgresBranchFacets } -type PostgresInstanceEdge { +type PostgresBranchEdge { cursor: Cursor! - node: PostgresInstance! + node: PostgresBranch! } """ -Facets for Postgres instances, providing distribution counts across different dimensions. +Facets for Postgres branches, providing distribution counts across different dimensions. """ -type PostgresInstanceFacets { - "Distribution of instances by environment." +type PostgresBranchFacets { + "Distribution of branches by environment." environments: [StringFacetItem!]! - "Distribution of instances by state." - states: [PostgresInstanceStateFacetItem!]! + "Distribution of branches by state." + states: [PostgresBranchStateFacetItem!]! - "Distribution of instances by user-defined labels." + "Distribution of branches by user-defined labels." labels: [LabelFacetItem!]! } """ -A single facet item for Postgres instance states. +A single facet item for Postgres branch states. """ -type PostgresInstanceStateFacetItem { - "The Postgres instance state." - state: PostgresInstanceState! +type PostgresBranchStateFacetItem { + "The Postgres branch state." + state: PostgresBranchState! - "Number of matching instances." + "Number of matching branches." count: Int! } -extend union SearchNode = PostgresInstance +extend union SearchNode = PostgresBranch extend enum SearchType { - POSTGRES + POSTGRES_BRANCH } extend enum ActivityLogEntryResourceType { @@ -27667,7 +27667,7 @@ type PostgresPersonalAccessCreatedActivityLogEntry implements ActivityLogEntry & message: String! "Type of the affected resource." resourceType: ActivityLogEntryResourceType! - "Name of the affected Postgres instance." + "Name of the affected Postgres branch." resourceName: String! "The team slug that the entry belongs to." teamSlug: Slug! @@ -27754,7 +27754,7 @@ extend enum ActivityLogActivityType { """ POSTGRES_PERSONAL_ACCESS_CONNECTION """ - A Postgres instance was deleted + A Postgres branch was deleted """ POSTGRES_DELETED } @@ -27764,12 +27764,12 @@ extend type Mutation { grantPostgresAccess(input: GrantPostgresAccessInput!): GrantPostgresAccessPayload! """ EXPERIMENTAL: DO NOT USE - Create time-limited personal access to a NAIS Postgres instance through the brokered PostgresAccess and relay flow. + Create time-limited personal access to a NAIS Postgres branch through the brokered PostgresAccess and relay flow. When the access is ready, retrieve its connection materials through PostgresAccess.connection. """ createPostgresAccess(input: CreatePostgresAccessInput!): CreatePostgresAccessPayload! - "Delete a PostgresInstance that is not active on its Postgres." - deletePostgres(input: DeletePostgresInput!): DeletePostgresPayload! + "Delete a PostgresBranch that is not active on its Postgres." + deletePostgresBranch(input: DeletePostgresBranchInput!): DeletePostgresBranchPayload! } type GrantPostgresAccessPayload { @@ -27795,11 +27795,11 @@ type CreatePostgresAccessPayload { "Input for creating a time-limited personal Postgres access." input CreatePostgresAccessInput { - "Name of the PostgresInstance to access." - postgresInstance: String! - "Team that owns the Postgres instance." + "Name of the PostgresBranch to access." + postgresBranch: String! + "Team that owns the Postgres branch." teamSlug: Slug! - "Environment containing the Postgres instance." + "Environment containing the Postgres branch." environmentName: String! "Privileges requested for the personal database role." accessLevel: PostgresAccessLevel! @@ -27819,30 +27819,30 @@ enum PostgresAccessLevel { READWRITECREATE } -input DeletePostgresInput { - "Name of the Postgres instance." +input DeletePostgresBranchInput { + "Name of the PostgresBranch." name: String! - "The environment name that the Postgres instance belongs to." + "The environment containing the PostgresBranch." environmentName: String! - "The team that owns the Postgres instance." + "The team that owns the PostgresBranch." teamSlug: Slug! } -type DeletePostgresPayload { - "Whether or not the Postgres instance was deleted." - postgresDeleted: Boolean +type DeletePostgresBranchPayload { + "Whether the PostgresBranch was deleted." + postgresBranchDeleted: Boolean } extend type TeamInventoryCounts { - postgresInstances: TeamInventoryCountPostgresInstances! + postgresBranches: TeamInventoryCountPostgresBranches! } -type TeamInventoryCountPostgresInstances { - "Total number of Postgres instances." +type TeamInventoryCountPostgresBranches { + "Total number of Postgres branches." total: Int! } -"A time-limited personal access request for a Postgres instance." +"A time-limited personal access request for a Postgres branch." type PostgresAccess implements Node { "Opaque ID for this PostgresAccess resource." id: ID! @@ -27852,8 +27852,8 @@ type PostgresAccess implements Node { team: Team! "Environment for the access." teamEnvironment: TeamEnvironment! - "PostgresInstance selected by this access." - postgresInstance: PostgresInstance! + "PostgresBranch selected by this access." + postgresBranch: PostgresBranch! "Requested access level." accessLevel: PostgresAccessLevel! "Server-controlled expiry for this personal access." @@ -35440,8 +35440,8 @@ func (ec *executionContext) childFields_Application(ctx context.Context, field g return ec.fieldContext_Application_networkPolicy(ctx, field) case "openSearch": return ec.fieldContext_Application_openSearch(ctx, field) - case "postgresInstances": - return ec.fieldContext_Application_postgresInstances(ctx, field) + case "postgresBranches": + return ec.fieldContext_Application_postgresBranches(ctx, field) case "secrets": return ec.fieldContext_Application_secrets(ctx, field) case "serviceAccount": @@ -36252,12 +36252,12 @@ func (ec *executionContext) childFields_DeleteOpenSearchPayload(ctx context.Cont return nil, fmt.Errorf("no field named %q was found under type DeleteOpenSearchPayload", field.Name) } -func (ec *executionContext) childFields_DeletePostgresPayload(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { +func (ec *executionContext) childFields_DeletePostgresBranchPayload(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { switch field.Name { - case "postgresDeleted": - return ec.fieldContext_DeletePostgresPayload_postgresDeleted(ctx, field) + case "postgresBranchDeleted": + return ec.fieldContext_DeletePostgresBranchPayload_postgresBranchDeleted(ctx, field) } - return nil, fmt.Errorf("no field named %q was found under type DeletePostgresPayload", field.Name) + return nil, fmt.Errorf("no field named %q was found under type DeletePostgresBranchPayload", field.Name) } func (ec *executionContext) childFields_DeleteSecretPayload(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { @@ -36962,8 +36962,8 @@ func (ec *executionContext) childFields_Job(ctx context.Context, field graphql.C return ec.fieldContext_Job_networkPolicy(ctx, field) case "openSearch": return ec.fieldContext_Job_openSearch(ctx, field) - case "postgresInstances": - return ec.fieldContext_Job_postgresInstances(ctx, field) + case "postgresBranches": + return ec.fieldContext_Job_postgresBranches(ctx, field) case "secrets": return ec.fieldContext_Job_secrets(ctx, field) case "serviceAccount": @@ -37728,8 +37728,8 @@ func (ec *executionContext) childFields_Postgres(ctx context.Context, field grap return ec.fieldContext_Postgres_highAvailability(ctx, field) case "resources": return ec.fieldContext_Postgres_resources(ctx, field) - case "activeInstance": - return ec.fieldContext_Postgres_activeInstance(ctx, field) + case "activeBranch": + return ec.fieldContext_Postgres_activeBranch(ctx, field) case "labels": return ec.fieldContext_Postgres_labels(ctx, field) } @@ -37746,8 +37746,8 @@ func (ec *executionContext) childFields_PostgresAccess(ctx context.Context, fiel return ec.fieldContext_PostgresAccess_team(ctx, field) case "teamEnvironment": return ec.fieldContext_PostgresAccess_teamEnvironment(ctx, field) - case "postgresInstance": - return ec.fieldContext_PostgresAccess_postgresInstance(ctx, field) + case "postgresBranch": + return ec.fieldContext_PostgresAccess_postgresBranch(ctx, field) case "accessLevel": return ec.fieldContext_PostgresAccess_accessLevel(ctx, field) case "expiresAt": @@ -37784,82 +37784,82 @@ func (ec *executionContext) childFields_PostgresAccessConnectionDetails(ctx cont return nil, fmt.Errorf("no field named %q was found under type PostgresAccessConnectionDetails", field.Name) } -func (ec *executionContext) childFields_PostgresGrantAccessActivityLogEntryData(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - switch field.Name { - case "grantee": - return ec.fieldContext_PostgresGrantAccessActivityLogEntryData_grantee(ctx, field) - case "until": - return ec.fieldContext_PostgresGrantAccessActivityLogEntryData_until(ctx, field) - } - return nil, fmt.Errorf("no field named %q was found under type PostgresGrantAccessActivityLogEntryData", field.Name) -} - -func (ec *executionContext) childFields_PostgresInstance(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { +func (ec *executionContext) childFields_PostgresBranch(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { switch field.Name { case "id": - return ec.fieldContext_PostgresInstance_id(ctx, field) + return ec.fieldContext_PostgresBranch_id(ctx, field) case "name": - return ec.fieldContext_PostgresInstance_name(ctx, field) + return ec.fieldContext_PostgresBranch_name(ctx, field) case "team": - return ec.fieldContext_PostgresInstance_team(ctx, field) + return ec.fieldContext_PostgresBranch_team(ctx, field) case "teamEnvironment": - return ec.fieldContext_PostgresInstance_teamEnvironment(ctx, field) + return ec.fieldContext_PostgresBranch_teamEnvironment(ctx, field) case "postgres": - return ec.fieldContext_PostgresInstance_postgres(ctx, field) + return ec.fieldContext_PostgresBranch_postgres(ctx, field) case "workloads": - return ec.fieldContext_PostgresInstance_workloads(ctx, field) + return ec.fieldContext_PostgresBranch_workloads(ctx, field) case "state": - return ec.fieldContext_PostgresInstance_state(ctx, field) + return ec.fieldContext_PostgresBranch_state(ctx, field) case "labels": - return ec.fieldContext_PostgresInstance_labels(ctx, field) + return ec.fieldContext_PostgresBranch_labels(ctx, field) } - return nil, fmt.Errorf("no field named %q was found under type PostgresInstance", field.Name) + return nil, fmt.Errorf("no field named %q was found under type PostgresBranch", field.Name) } -func (ec *executionContext) childFields_PostgresInstanceConnection(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { +func (ec *executionContext) childFields_PostgresBranchConnection(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { switch field.Name { case "pageInfo": - return ec.fieldContext_PostgresInstanceConnection_pageInfo(ctx, field) + return ec.fieldContext_PostgresBranchConnection_pageInfo(ctx, field) case "nodes": - return ec.fieldContext_PostgresInstanceConnection_nodes(ctx, field) + return ec.fieldContext_PostgresBranchConnection_nodes(ctx, field) case "edges": - return ec.fieldContext_PostgresInstanceConnection_edges(ctx, field) + return ec.fieldContext_PostgresBranchConnection_edges(ctx, field) case "facets": - return ec.fieldContext_PostgresInstanceConnection_facets(ctx, field) + return ec.fieldContext_PostgresBranchConnection_facets(ctx, field) } - return nil, fmt.Errorf("no field named %q was found under type PostgresInstanceConnection", field.Name) + return nil, fmt.Errorf("no field named %q was found under type PostgresBranchConnection", field.Name) } -func (ec *executionContext) childFields_PostgresInstanceEdge(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { +func (ec *executionContext) childFields_PostgresBranchEdge(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { switch field.Name { case "cursor": - return ec.fieldContext_PostgresInstanceEdge_cursor(ctx, field) + return ec.fieldContext_PostgresBranchEdge_cursor(ctx, field) case "node": - return ec.fieldContext_PostgresInstanceEdge_node(ctx, field) + return ec.fieldContext_PostgresBranchEdge_node(ctx, field) } - return nil, fmt.Errorf("no field named %q was found under type PostgresInstanceEdge", field.Name) + return nil, fmt.Errorf("no field named %q was found under type PostgresBranchEdge", field.Name) } -func (ec *executionContext) childFields_PostgresInstanceFacets(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { +func (ec *executionContext) childFields_PostgresBranchFacets(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { switch field.Name { case "environments": - return ec.fieldContext_PostgresInstanceFacets_environments(ctx, field) + return ec.fieldContext_PostgresBranchFacets_environments(ctx, field) case "states": - return ec.fieldContext_PostgresInstanceFacets_states(ctx, field) + return ec.fieldContext_PostgresBranchFacets_states(ctx, field) case "labels": - return ec.fieldContext_PostgresInstanceFacets_labels(ctx, field) + return ec.fieldContext_PostgresBranchFacets_labels(ctx, field) } - return nil, fmt.Errorf("no field named %q was found under type PostgresInstanceFacets", field.Name) + return nil, fmt.Errorf("no field named %q was found under type PostgresBranchFacets", field.Name) } -func (ec *executionContext) childFields_PostgresInstanceStateFacetItem(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { +func (ec *executionContext) childFields_PostgresBranchStateFacetItem(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { switch field.Name { case "state": - return ec.fieldContext_PostgresInstanceStateFacetItem_state(ctx, field) + return ec.fieldContext_PostgresBranchStateFacetItem_state(ctx, field) case "count": - return ec.fieldContext_PostgresInstanceStateFacetItem_count(ctx, field) + return ec.fieldContext_PostgresBranchStateFacetItem_count(ctx, field) + } + return nil, fmt.Errorf("no field named %q was found under type PostgresBranchStateFacetItem", field.Name) +} + +func (ec *executionContext) childFields_PostgresGrantAccessActivityLogEntryData(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { + switch field.Name { + case "grantee": + return ec.fieldContext_PostgresGrantAccessActivityLogEntryData_grantee(ctx, field) + case "until": + return ec.fieldContext_PostgresGrantAccessActivityLogEntryData_until(ctx, field) } - return nil, fmt.Errorf("no field named %q was found under type PostgresInstanceStateFacetItem", field.Name) + return nil, fmt.Errorf("no field named %q was found under type PostgresGrantAccessActivityLogEntryData", field.Name) } func (ec *executionContext) childFields_PostgresPersonalAccessCreatedActivityLogEntryData(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { @@ -38948,8 +38948,8 @@ func (ec *executionContext) childFields_Team(ctx context.Context, field graphql. return ec.fieldContext_Team_kafkaTopics(ctx, field) case "openSearches": return ec.fieldContext_Team_openSearches(ctx, field) - case "postgresInstances": - return ec.fieldContext_Team_postgresInstances(ctx, field) + case "postgresBranches": + return ec.fieldContext_Team_postgresBranches(ctx, field) case "repositories": return ec.fieldContext_Team_repositories(ctx, field) case "secrets": @@ -39108,8 +39108,8 @@ func (ec *executionContext) childFields_TeamEnvironment(ctx context.Context, fie return ec.fieldContext_TeamEnvironment_openSearch(ctx, field) case "postgres": return ec.fieldContext_TeamEnvironment_postgres(ctx, field) - case "postgresInstance": - return ec.fieldContext_TeamEnvironment_postgresInstance(ctx, field) + case "postgresBranch": + return ec.fieldContext_TeamEnvironment_postgresBranch(ctx, field) case "postgresAccess": return ec.fieldContext_TeamEnvironment_postgresAccess(ctx, field) case "secret": @@ -39274,12 +39274,12 @@ func (ec *executionContext) childFields_TeamInventoryCountOpenSearches(ctx conte return nil, fmt.Errorf("no field named %q was found under type TeamInventoryCountOpenSearches", field.Name) } -func (ec *executionContext) childFields_TeamInventoryCountPostgresInstances(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { +func (ec *executionContext) childFields_TeamInventoryCountPostgresBranches(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { switch field.Name { case "total": - return ec.fieldContext_TeamInventoryCountPostgresInstances_total(ctx, field) + return ec.fieldContext_TeamInventoryCountPostgresBranches_total(ctx, field) } - return nil, fmt.Errorf("no field named %q was found under type TeamInventoryCountPostgresInstances", field.Name) + return nil, fmt.Errorf("no field named %q was found under type TeamInventoryCountPostgresBranches", field.Name) } func (ec *executionContext) childFields_TeamInventoryCountSecrets(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { @@ -39322,8 +39322,8 @@ func (ec *executionContext) childFields_TeamInventoryCounts(ctx context.Context, return ec.fieldContext_TeamInventoryCounts_kafkaTopics(ctx, field) case "openSearches": return ec.fieldContext_TeamInventoryCounts_openSearches(ctx, field) - case "postgresInstances": - return ec.fieldContext_TeamInventoryCounts_postgresInstances(ctx, field) + case "postgresBranches": + return ec.fieldContext_TeamInventoryCounts_postgresBranches(ctx, field) case "secrets": return ec.fieldContext_TeamInventoryCounts_secrets(ctx, field) case "sqlInstances": diff --git a/internal/graph/gengql/schema.generated.go b/internal/graph/gengql/schema.generated.go index 0a4737879..be77e6e4e 100644 --- a/internal/graph/gengql/schema.generated.go +++ b/internal/graph/gengql/schema.generated.go @@ -86,7 +86,7 @@ type MutationResolver interface { CreateOpenSearchCredentials(ctx context.Context, input opensearch.CreateOpenSearchCredentialsInput) (*opensearch.CreateOpenSearchCredentialsPayload, error) GrantPostgresAccess(ctx context.Context, input postgres.GrantPostgresAccessInput) (*postgres.GrantPostgresAccessPayload, error) CreatePostgresAccess(ctx context.Context, input postgres.CreatePostgresAccessInput) (*postgres.CreatePostgresAccessPayload, error) - DeletePostgres(ctx context.Context, input postgres.DeletePostgresInput) (*postgres.DeletePostgresPayload, error) + DeletePostgresBranch(ctx context.Context, input postgres.DeletePostgresBranchInput) (*postgres.DeletePostgresBranchPayload, error) EnableReconciler(ctx context.Context, input reconciler.EnableReconcilerInput) (*reconciler.Reconciler, error) DisableReconciler(ctx context.Context, input reconciler.DisableReconcilerInput) (*reconciler.Reconciler, error) ConfigureReconciler(ctx context.Context, input reconciler.ConfigureReconcilerInput) (*reconciler.Reconciler, error) @@ -561,12 +561,12 @@ func (ec *executionContext) field_Mutation_deleteOpenSearch_args(ctx context.Con return args, nil } -func (ec *executionContext) field_Mutation_deletePostgres_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { +func (ec *executionContext) field_Mutation_deletePostgresBranch_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} arg0, err := graphql.ProcessArgField(ctx, rawArgs, "input", - func(ctx context.Context, v any) (postgres.DeletePostgresInput, error) { - return ec.unmarshalNDeletePostgresInput2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐDeletePostgresInput(ctx, v) + func(ctx context.Context, v any) (postgres.DeletePostgresBranchInput, error) { + return ec.unmarshalNDeletePostgresBranchInput2githubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐDeletePostgresBranchInput(ctx, v) }) if err != nil { return nil, err @@ -2739,34 +2739,34 @@ func (ec *executionContext) fieldContext_Mutation_createPostgresAccess(ctx conte return fc, nil } -func (ec *executionContext) _Mutation_deletePostgres(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { +func (ec *executionContext) _Mutation_deletePostgresBranch(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_Mutation_deletePostgres(ctx, field) + return ec.fieldContext_Mutation_deletePostgresBranch(ctx, field) }, func(ctx context.Context) (any, error) { fc := graphql.GetFieldContext(ctx) - return ec.Resolvers.Mutation().DeletePostgres(ctx, fc.Args["input"].(postgres.DeletePostgresInput)) + return ec.Resolvers.Mutation().DeletePostgresBranch(ctx, fc.Args["input"].(postgres.DeletePostgresBranchInput)) }, nil, - func(ctx context.Context, selections ast.SelectionSet, v *postgres.DeletePostgresPayload) graphql.Marshaler { - return ec.marshalNDeletePostgresPayload2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐDeletePostgresPayload(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *postgres.DeletePostgresBranchPayload) graphql.Marshaler { + return ec.marshalNDeletePostgresBranchPayload2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐDeletePostgresBranchPayload(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_Mutation_deletePostgres(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_Mutation_deletePostgresBranch(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "Mutation", Field: field, IsMethod: true, IsResolver: true, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_DeletePostgresPayload(ctx, field) + return ec.childFields_DeletePostgresBranchPayload(ctx, field) }, } defer func() { @@ -2776,7 +2776,7 @@ func (ec *executionContext) fieldContext_Mutation_deletePostgres(ctx context.Con } }() ctx = graphql.WithFieldContext(ctx, fc) - if fc.Args, err = ec.field_Mutation_deletePostgres_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + if fc.Args, err = ec.field_Mutation_deletePostgresBranch_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { ec.Error(ctx, err) return fc, err } @@ -6598,13 +6598,6 @@ func (ec *executionContext) _Node(ctx context.Context, sel ast.SelectionSet, obj return graphql.Null } return ec._PostgresPersonalAccessConnectionActivityLogEntry(ctx, sel, obj) - case postgres.PostgresInstance: - return ec._PostgresInstance(ctx, sel, &obj) - case *postgres.PostgresInstance: - if obj == nil { - return graphql.Null - } - return ec._PostgresInstance(ctx, sel, obj) case postgres.PostgresGrantAccessActivityLogEntry: return ec._PostgresGrantAccessActivityLogEntry(ctx, sel, &obj) case *postgres.PostgresGrantAccessActivityLogEntry: @@ -6619,6 +6612,13 @@ func (ec *executionContext) _Node(ctx context.Context, sel ast.SelectionSet, obj return graphql.Null } return ec._PostgresDeletedActivityLogEntry(ctx, sel, obj) + case postgres.PostgresBranch: + return ec._PostgresBranch(ctx, sel, &obj) + case *postgres.PostgresBranch: + if obj == nil { + return graphql.Null + } + return ec._PostgresBranch(ctx, sel, obj) case opensearch.OpenSearchUpdatedActivityLogEntry: return ec._OpenSearchUpdatedActivityLogEntry(ctx, sel, &obj) case *opensearch.OpenSearchUpdatedActivityLogEntry: @@ -7335,9 +7335,9 @@ func (ec *executionContext) _Mutation(ctx context.Context, sel ast.SelectionSet) if out.Values[i] == graphql.Null { out.Invalids++ } - case "deletePostgres": + case "deletePostgresBranch": out.Values[i] = ec.OperationContext.RootResolverMiddleware(innerCtx, func(ctx context.Context) (res graphql.Marshaler) { - return ec._Mutation_deletePostgres(ctx, field) + return ec._Mutation_deletePostgresBranch(ctx, field) }) if out.Values[i] == graphql.Null { out.Invalids++ diff --git a/internal/graph/gengql/search.generated.go b/internal/graph/gengql/search.generated.go index d845b9660..60e696125 100644 --- a/internal/graph/gengql/search.generated.go +++ b/internal/graph/gengql/search.generated.go @@ -271,11 +271,11 @@ func (ec *executionContext) _SearchNode(ctx context.Context, sel ast.SelectionSe return graphql.Null } return ec._SqlInstance(ctx, sel, obj) - case *postgres.PostgresInstance: + case *postgres.PostgresBranch: if obj == nil { return graphql.Null } - return ec._PostgresInstance(ctx, sel, obj) + return ec._PostgresBranch(ctx, sel, obj) case kafkatopic.KafkaTopic: return ec._KafkaTopic(ctx, sel, &obj) case *kafkatopic.KafkaTopic: diff --git a/internal/graph/gengql/teams.generated.go b/internal/graph/gengql/teams.generated.go index a27b260b6..c9f53deb1 100644 --- a/internal/graph/gengql/teams.generated.go +++ b/internal/graph/gengql/teams.generated.go @@ -74,7 +74,7 @@ type TeamResolver interface { Jobs(ctx context.Context, obj *team.Team, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *job.JobOrder, filter *job.TeamJobsFilter) (*pagination.FacetableConnection[*job.Job, *job.TeamJobsFilter], error) KafkaTopics(ctx context.Context, obj *team.Team, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *kafkatopic.KafkaTopicOrder, filter *kafkatopic.KafkaTopicFilter) (*pagination.FacetableConnection[*kafkatopic.KafkaTopic, *kafkatopic.KafkaTopicFilter], error) OpenSearches(ctx context.Context, obj *team.Team, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *opensearch.OpenSearchOrder, filter *opensearch.OpenSearchFilter) (*pagination.FacetableConnection[*opensearch.OpenSearch, *opensearch.OpenSearchFilter], error) - PostgresInstances(ctx context.Context, obj *team.Team, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *postgres.PostgresInstanceOrder, filter *postgres.PostgresInstanceFilter) (*pagination.FacetableConnection[*postgres.PostgresInstance, *postgres.PostgresInstanceFilter], error) + PostgresBranches(ctx context.Context, obj *team.Team, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *postgres.PostgresBranchOrder, filter *postgres.PostgresBranchFilter) (*pagination.FacetableConnection[*postgres.PostgresBranch, *postgres.PostgresBranchFilter], error) Repositories(ctx context.Context, obj *team.Team, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *repository.RepositoryOrder, filter *repository.TeamRepositoryFilter) (*pagination.Connection[*repository.Repository], error) Secrets(ctx context.Context, obj *team.Team, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *secret.SecretOrder, filter *secret.SecretFilter) (*pagination.FacetableConnection[*secret.Secret, *secret.SecretFilter], error) ServiceAccounts(ctx context.Context, obj *team.Team, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor) (*pagination.Connection[*serviceaccount.ServiceAccount], error) @@ -106,7 +106,7 @@ type TeamEnvironmentResolver interface { KafkaTopic(ctx context.Context, obj *team.TeamEnvironment, name string) (*kafkatopic.KafkaTopic, error) OpenSearch(ctx context.Context, obj *team.TeamEnvironment, name string) (*opensearch.OpenSearch, error) Postgres(ctx context.Context, obj *team.TeamEnvironment, name string) (*postgres.Postgres, error) - PostgresInstance(ctx context.Context, obj *team.TeamEnvironment, name string) (*postgres.PostgresInstance, error) + PostgresBranch(ctx context.Context, obj *team.TeamEnvironment, name string) (*postgres.PostgresBranch, error) PostgresAccess(ctx context.Context, obj *team.TeamEnvironment, name string) (*postgres.PostgresAccess, error) Secret(ctx context.Context, obj *team.TeamEnvironment, name string) (*secret.Secret, error) SQLInstance(ctx context.Context, obj *team.TeamEnvironment, name string) (*sqlinstance.SQLInstance, error) @@ -122,7 +122,7 @@ type TeamInventoryCountsResolver interface { Jobs(ctx context.Context, obj *team.TeamInventoryCounts) (*job.TeamInventoryCountJobs, error) KafkaTopics(ctx context.Context, obj *team.TeamInventoryCounts) (*kafkatopic.TeamInventoryCountKafkaTopics, error) OpenSearches(ctx context.Context, obj *team.TeamInventoryCounts) (*opensearch.TeamInventoryCountOpenSearches, error) - PostgresInstances(ctx context.Context, obj *team.TeamInventoryCounts) (*postgres.TeamInventoryCountPostgresInstances, error) + PostgresBranches(ctx context.Context, obj *team.TeamInventoryCounts) (*postgres.TeamInventoryCountPostgresBranches, error) Secrets(ctx context.Context, obj *team.TeamInventoryCounts) (*secret.TeamInventoryCountSecrets, error) SQLInstances(ctx context.Context, obj *team.TeamInventoryCounts) (*sqlinstance.TeamInventoryCountSQLInstances, error) Valkeys(ctx context.Context, obj *team.TeamInventoryCounts) (*valkey.TeamInventoryCountValkeys, error) @@ -305,7 +305,7 @@ func (ec *executionContext) field_TeamEnvironment_postgresAccess_args(ctx contex return args, nil } -func (ec *executionContext) field_TeamEnvironment_postgresInstance_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { +func (ec *executionContext) field_TeamEnvironment_postgresBranch_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} arg0, err := graphql.ProcessArgField(ctx, rawArgs, "name", @@ -1075,7 +1075,7 @@ func (ec *executionContext) field_Team_openSearches_args(ctx context.Context, ra return args, nil } -func (ec *executionContext) field_Team_postgresInstances_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { +func (ec *executionContext) field_Team_postgresBranches_args(ctx context.Context, rawArgs map[string]any) (map[string]any, error) { var err error args := map[string]any{} arg0, err := graphql.ProcessArgField(ctx, rawArgs, "first", @@ -1111,16 +1111,16 @@ func (ec *executionContext) field_Team_postgresInstances_args(ctx context.Contex } args["before"] = arg3 arg4, err := graphql.ProcessArgField(ctx, rawArgs, "orderBy", - func(ctx context.Context, v any) (*postgres.PostgresInstanceOrder, error) { - return ec.unmarshalOPostgresInstanceOrder2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceOrder(ctx, v) + func(ctx context.Context, v any) (*postgres.PostgresBranchOrder, error) { + return ec.unmarshalOPostgresBranchOrder2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresBranchOrder(ctx, v) }) if err != nil { return nil, err } args["orderBy"] = arg4 arg5, err := graphql.ProcessArgField(ctx, rawArgs, "filter", - func(ctx context.Context, v any) (*postgres.PostgresInstanceFilter, error) { - return ec.unmarshalOPostgresInstanceFilter2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstanceFilter(ctx, v) + func(ctx context.Context, v any) (*postgres.PostgresBranchFilter, error) { + return ec.unmarshalOPostgresBranchFilter2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresBranchFilter(ctx, v) }) if err != nil { return nil, err @@ -2760,34 +2760,34 @@ func (ec *executionContext) fieldContext_Team_openSearches(ctx context.Context, return fc, nil } -func (ec *executionContext) _Team_postgresInstances(ctx context.Context, field graphql.CollectedField, obj *team.Team) (ret graphql.Marshaler) { +func (ec *executionContext) _Team_postgresBranches(ctx context.Context, field graphql.CollectedField, obj *team.Team) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_Team_postgresInstances(ctx, field) + return ec.fieldContext_Team_postgresBranches(ctx, field) }, func(ctx context.Context) (any, error) { fc := graphql.GetFieldContext(ctx) - return ec.Resolvers.Team().PostgresInstances(ctx, obj, fc.Args["first"].(*int), fc.Args["after"].(*pagination.Cursor), fc.Args["last"].(*int), fc.Args["before"].(*pagination.Cursor), fc.Args["orderBy"].(*postgres.PostgresInstanceOrder), fc.Args["filter"].(*postgres.PostgresInstanceFilter)) + return ec.Resolvers.Team().PostgresBranches(ctx, obj, fc.Args["first"].(*int), fc.Args["after"].(*pagination.Cursor), fc.Args["last"].(*int), fc.Args["before"].(*pagination.Cursor), fc.Args["orderBy"].(*postgres.PostgresBranchOrder), fc.Args["filter"].(*postgres.PostgresBranchFilter)) }, nil, - func(ctx context.Context, selections ast.SelectionSet, v *pagination.FacetableConnection[*postgres.PostgresInstance, *postgres.PostgresInstanceFilter]) graphql.Marshaler { - return ec.marshalNPostgresInstanceConnection2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋpaginationᚐFacetableConnection(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *pagination.FacetableConnection[*postgres.PostgresBranch, *postgres.PostgresBranchFilter]) graphql.Marshaler { + return ec.marshalNPostgresBranchConnection2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋgraphᚋpaginationᚐFacetableConnection(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_Team_postgresInstances(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_Team_postgresBranches(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "Team", Field: field, IsMethod: true, IsResolver: true, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_PostgresInstanceConnection(ctx, field) + return ec.childFields_PostgresBranchConnection(ctx, field) }, } defer func() { @@ -2797,7 +2797,7 @@ func (ec *executionContext) fieldContext_Team_postgresInstances(ctx context.Cont } }() ctx = graphql.WithFieldContext(ctx, fc) - if fc.Args, err = ec.field_Team_postgresInstances_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + if fc.Args, err = ec.field_Team_postgresBranches_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { ec.Error(ctx, err) return fc, err } @@ -4914,34 +4914,34 @@ func (ec *executionContext) fieldContext_TeamEnvironment_postgres(ctx context.Co return fc, nil } -func (ec *executionContext) _TeamEnvironment_postgresInstance(ctx context.Context, field graphql.CollectedField, obj *team.TeamEnvironment) (ret graphql.Marshaler) { +func (ec *executionContext) _TeamEnvironment_postgresBranch(ctx context.Context, field graphql.CollectedField, obj *team.TeamEnvironment) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_TeamEnvironment_postgresInstance(ctx, field) + return ec.fieldContext_TeamEnvironment_postgresBranch(ctx, field) }, func(ctx context.Context) (any, error) { fc := graphql.GetFieldContext(ctx) - return ec.Resolvers.TeamEnvironment().PostgresInstance(ctx, obj, fc.Args["name"].(string)) + return ec.Resolvers.TeamEnvironment().PostgresBranch(ctx, obj, fc.Args["name"].(string)) }, nil, - func(ctx context.Context, selections ast.SelectionSet, v *postgres.PostgresInstance) graphql.Marshaler { - return ec.marshalNPostgresInstance2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresInstance(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *postgres.PostgresBranch) graphql.Marshaler { + return ec.marshalNPostgresBranch2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐPostgresBranch(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_TeamEnvironment_postgresInstance(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_TeamEnvironment_postgresBranch(ctx context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "TeamEnvironment", Field: field, IsMethod: true, IsResolver: true, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_PostgresInstance(ctx, field) + return ec.childFields_PostgresBranch(ctx, field) }, } defer func() { @@ -4951,7 +4951,7 @@ func (ec *executionContext) fieldContext_TeamEnvironment_postgresInstance(ctx co } }() ctx = graphql.WithFieldContext(ctx, fc) - if fc.Args, err = ec.field_TeamEnvironment_postgresInstance_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { + if fc.Args, err = ec.field_TeamEnvironment_postgresBranch_args(ctx, field.ArgumentMap(ec.Variables)); err != nil { ec.Error(ctx, err) return fc, err } @@ -6024,33 +6024,33 @@ func (ec *executionContext) fieldContext_TeamInventoryCounts_openSearches(_ cont return fc, nil } -func (ec *executionContext) _TeamInventoryCounts_postgresInstances(ctx context.Context, field graphql.CollectedField, obj *team.TeamInventoryCounts) (ret graphql.Marshaler) { +func (ec *executionContext) _TeamInventoryCounts_postgresBranches(ctx context.Context, field graphql.CollectedField, obj *team.TeamInventoryCounts) (ret graphql.Marshaler) { return graphql.ResolveField( ctx, ec.OperationContext, field, func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.fieldContext_TeamInventoryCounts_postgresInstances(ctx, field) + return ec.fieldContext_TeamInventoryCounts_postgresBranches(ctx, field) }, func(ctx context.Context) (any, error) { - return ec.Resolvers.TeamInventoryCounts().PostgresInstances(ctx, obj) + return ec.Resolvers.TeamInventoryCounts().PostgresBranches(ctx, obj) }, nil, - func(ctx context.Context, selections ast.SelectionSet, v *postgres.TeamInventoryCountPostgresInstances) graphql.Marshaler { - return ec.marshalNTeamInventoryCountPostgresInstances2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐTeamInventoryCountPostgresInstances(ctx, selections, v) + func(ctx context.Context, selections ast.SelectionSet, v *postgres.TeamInventoryCountPostgresBranches) graphql.Marshaler { + return ec.marshalNTeamInventoryCountPostgresBranches2ᚖgithubᚗcomᚋnaisᚋapiᚋinternalᚋpersistenceᚋpostgresᚐTeamInventoryCountPostgresBranches(ctx, selections, v) }, true, true, ) } -func (ec *executionContext) fieldContext_TeamInventoryCounts_postgresInstances(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { +func (ec *executionContext) fieldContext_TeamInventoryCounts_postgresBranches(_ context.Context, field graphql.CollectedField) (fc *graphql.FieldContext, err error) { fc = &graphql.FieldContext{ Object: "TeamInventoryCounts", Field: field, IsMethod: true, IsResolver: true, Child: func(ctx context.Context, field graphql.CollectedField) (*graphql.FieldContext, error) { - return ec.childFields_TeamInventoryCountPostgresInstances(ctx, field) + return ec.childFields_TeamInventoryCountPostgresBranches(ctx, field) }, } return fc, nil @@ -9279,7 +9279,7 @@ func (ec *executionContext) _Team(ctx context.Context, sel ast.SelectionSet, obj } out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) - case "postgresInstances": + case "postgresBranches": field := field innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { @@ -9288,7 +9288,7 @@ func (ec *executionContext) _Team(ctx context.Context, sel ast.SelectionSet, obj ec.Error(ctx, ec.Recover(ctx, r)) } }() - res = ec._Team_postgresInstances(ctx, field, obj) + res = ec._Team_postgresBranches(ctx, field, obj) if res == graphql.Null { atomic.AddUint32(&fs.Invalids, 1) } @@ -10774,7 +10774,7 @@ func (ec *executionContext) _TeamEnvironment(ctx context.Context, sel ast.Select } out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) - case "postgresInstance": + case "postgresBranch": field := field innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { @@ -10783,7 +10783,7 @@ func (ec *executionContext) _TeamEnvironment(ctx context.Context, sel ast.Select ec.Error(ctx, ec.Recover(ctx, r)) } }() - res = ec._TeamEnvironment_postgresInstance(ctx, field, obj) + res = ec._TeamEnvironment_postgresBranch(ctx, field, obj) if res == graphql.Null { atomic.AddUint32(&fs.Invalids, 1) } @@ -11630,7 +11630,7 @@ func (ec *executionContext) _TeamInventoryCounts(ctx context.Context, sel ast.Se } out.Concurrently(i, func(ctx context.Context) graphql.Marshaler { return innerFunc(ctx, out) }) - case "postgresInstances": + case "postgresBranches": field := field innerFunc := func(ctx context.Context, fs *graphql.FieldSet) (res graphql.Marshaler) { @@ -11639,7 +11639,7 @@ func (ec *executionContext) _TeamInventoryCounts(ctx context.Context, sel ast.Se ec.Error(ctx, ec.Recover(ctx, r)) } }() - res = ec._TeamInventoryCounts_postgresInstances(ctx, field, obj) + res = ec._TeamInventoryCounts_postgresBranches(ctx, field, obj) if res == graphql.Null { atomic.AddUint32(&fs.Invalids, 1) } diff --git a/internal/graph/postgres.resolvers.go b/internal/graph/postgres.resolvers.go index 393a8535c..f108e7475 100644 --- a/internal/graph/postgres.resolvers.go +++ b/internal/graph/postgres.resolvers.go @@ -13,26 +13,26 @@ import ( "github.com/nais/api/internal/workload/job" ) -func (r *applicationResolver) PostgresInstances(ctx context.Context, obj *application.Application, orderBy *postgres.PostgresInstanceOrder) (*pagination.FacetableConnection[*postgres.PostgresInstance, *postgres.PostgresInstanceFilter], error) { +func (r *applicationResolver) PostgresBranches(ctx context.Context, obj *application.Application, orderBy *postgres.PostgresBranchOrder) (*pagination.FacetableConnection[*postgres.PostgresBranch, *postgres.PostgresBranchFilter], error) { if obj.Spec == nil || obj.Spec.Uses == nil { - return pagination.NewFacetableConnection(pagination.EmptyConnection[*postgres.PostgresInstance](), nil, (*postgres.PostgresInstanceFilter)(nil)), nil + return pagination.NewFacetableConnection(pagination.EmptyConnection[*postgres.PostgresBranch](), nil, (*postgres.PostgresBranchFilter)(nil)), nil } instances, err := postgres.ListForWorkload(ctx, obj.TeamSlug, obj.EnvironmentName, obj.Spec.Uses.Postgres) if err != nil { return nil, err } - return pagination.NewFacetableConnection(pagination.NewConnectionWithoutPagination(instances), instances, (*postgres.PostgresInstanceFilter)(nil)), nil + return pagination.NewFacetableConnection(pagination.NewConnectionWithoutPagination(instances), instances, (*postgres.PostgresBranchFilter)(nil)), nil } -func (r *jobResolver) PostgresInstances(ctx context.Context, obj *job.Job, orderBy *postgres.PostgresInstanceOrder) (*pagination.FacetableConnection[*postgres.PostgresInstance, *postgres.PostgresInstanceFilter], error) { +func (r *jobResolver) PostgresBranches(ctx context.Context, obj *job.Job, orderBy *postgres.PostgresBranchOrder) (*pagination.FacetableConnection[*postgres.PostgresBranch, *postgres.PostgresBranchFilter], error) { if obj.Spec == nil || obj.Spec.Uses == nil { - return pagination.NewFacetableConnection(pagination.EmptyConnection[*postgres.PostgresInstance](), nil, (*postgres.PostgresInstanceFilter)(nil)), nil + return pagination.NewFacetableConnection(pagination.EmptyConnection[*postgres.PostgresBranch](), nil, (*postgres.PostgresBranchFilter)(nil)), nil } instances, err := postgres.ListForWorkload(ctx, obj.TeamSlug, obj.EnvironmentName, obj.Spec.Uses.Postgres) if err != nil { return nil, err } - return pagination.NewFacetableConnection(pagination.NewConnectionWithoutPagination(instances), instances, (*postgres.PostgresInstanceFilter)(nil)), nil + return pagination.NewFacetableConnection(pagination.NewConnectionWithoutPagination(instances), instances, (*postgres.PostgresBranchFilter)(nil)), nil } func (r *mutationResolver) GrantPostgresAccess(ctx context.Context, input postgres.GrantPostgresAccessInput) (*postgres.GrantPostgresAccessPayload, error) { @@ -53,7 +53,7 @@ func (r *mutationResolver) CreatePostgresAccess(ctx context.Context, input postg return postgres.CreatePostgresAccess(ctx, input) } -func (r *mutationResolver) DeletePostgres(ctx context.Context, input postgres.DeletePostgresInput) (*postgres.DeletePostgresPayload, error) { +func (r *mutationResolver) DeletePostgresBranch(ctx context.Context, input postgres.DeletePostgresBranchInput) (*postgres.DeletePostgresBranchPayload, error) { if err := authz.CanDeletePostgres(ctx, input.TeamSlug); err != nil { return nil, err } @@ -68,8 +68,8 @@ func (r *postgresAccessResolver) TeamEnvironment(ctx context.Context, obj *postg return team.GetTeamEnvironment(ctx, obj.TeamSlug, obj.EnvironmentName) } -func (r *postgresAccessResolver) PostgresInstance(ctx context.Context, obj *postgres.PostgresAccess) (*postgres.PostgresInstance, error) { - return postgres.GetPostgresInstance(ctx, obj.TeamSlug, obj.EnvironmentName, obj.PostgresInstanceName) +func (r *postgresAccessResolver) PostgresBranch(ctx context.Context, obj *postgres.PostgresAccess) (*postgres.PostgresBranch, error) { + return postgres.GetPostgresBranch(ctx, obj.TeamSlug, obj.EnvironmentName, obj.PostgresBranchName) } func (r *postgresAccessResolver) Connection(ctx context.Context, obj *postgres.PostgresAccess) (*postgres.PostgresAccessConnectionDetails, error) { @@ -78,19 +78,19 @@ func (r *postgresAccessResolver) Connection(ctx context.Context, obj *postgres.P }) } -func (r *postgresInstanceResolver) Team(ctx context.Context, obj *postgres.PostgresInstance) (*team.Team, error) { +func (r *postgresBranchResolver) Team(ctx context.Context, obj *postgres.PostgresBranch) (*team.Team, error) { return team.Get(ctx, obj.TeamSlug) } -func (r *postgresInstanceResolver) TeamEnvironment(ctx context.Context, obj *postgres.PostgresInstance) (*team.TeamEnvironment, error) { +func (r *postgresBranchResolver) TeamEnvironment(ctx context.Context, obj *postgres.PostgresBranch) (*team.TeamEnvironment, error) { return team.GetTeamEnvironment(ctx, obj.TeamSlug, obj.EnvironmentName) } -func (r *postgresInstanceResolver) Postgres(ctx context.Context, obj *postgres.PostgresInstance) (*postgres.Postgres, error) { +func (r *postgresBranchResolver) Postgres(ctx context.Context, obj *postgres.PostgresBranch) (*postgres.Postgres, error) { return postgres.GetPostgres(ctx, obj.TeamSlug, obj.EnvironmentName, obj.PostgresName) } -func (r *postgresInstanceResolver) Workloads(ctx context.Context, obj *postgres.PostgresInstance, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor) (*pagination.Connection[workload.Workload], error) { +func (r *postgresBranchResolver) Workloads(ctx context.Context, obj *postgres.PostgresBranch, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor) (*pagination.Connection[workload.Workload], error) { page, err := pagination.ParsePage(first, after, last, before) if err != nil { return nil, err @@ -101,14 +101,14 @@ func (r *postgresInstanceResolver) Workloads(ctx context.Context, obj *postgres. return pagination.NewConnection(pagination.Slice(workloads, page), page, len(workloads)), nil } -func (r *postgresInstanceConnectionResolver) Facets(ctx context.Context, obj *pagination.FacetableConnection[*postgres.PostgresInstance, *postgres.PostgresInstanceFilter]) (*postgres.PostgresInstanceFacets, error) { - return &postgres.PostgresInstanceFacets{ +func (r *postgresBranchConnectionResolver) Facets(ctx context.Context, obj *pagination.FacetableConnection[*postgres.PostgresBranch, *postgres.PostgresBranchFilter]) (*postgres.PostgresBranchFacets, error) { + return &postgres.PostgresBranchFacets{ AllInstances: obj.GetAllItems(), Filter: obj.GetFilter(), }, nil } -func (r *teamResolver) PostgresInstances(ctx context.Context, obj *team.Team, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *postgres.PostgresInstanceOrder, filter *postgres.PostgresInstanceFilter) (*pagination.FacetableConnection[*postgres.PostgresInstance, *postgres.PostgresInstanceFilter], error) { +func (r *teamResolver) PostgresBranches(ctx context.Context, obj *team.Team, first *int, after *pagination.Cursor, last *int, before *pagination.Cursor, orderBy *postgres.PostgresBranchOrder, filter *postgres.PostgresBranchFilter) (*pagination.FacetableConnection[*postgres.PostgresBranch, *postgres.PostgresBranchFilter], error) { page, err := pagination.ParsePage(first, after, last, before) if err != nil { return nil, err @@ -121,32 +121,30 @@ func (r *teamEnvironmentResolver) Postgres(ctx context.Context, obj *team.TeamEn return postgres.GetPostgres(ctx, obj.TeamSlug, obj.EnvironmentName, name) } -func (r *teamEnvironmentResolver) PostgresInstance(ctx context.Context, obj *team.TeamEnvironment, name string) (*postgres.PostgresInstance, error) { - return postgres.GetPostgresInstance(ctx, obj.TeamSlug, obj.EnvironmentName, name) +func (r *teamEnvironmentResolver) PostgresBranch(ctx context.Context, obj *team.TeamEnvironment, name string) (*postgres.PostgresBranch, error) { + return postgres.GetPostgresBranch(ctx, obj.TeamSlug, obj.EnvironmentName, name) } func (r *teamEnvironmentResolver) PostgresAccess(ctx context.Context, obj *team.TeamEnvironment, name string) (*postgres.PostgresAccess, error) { return postgres.GetPostgresAccess(ctx, name, obj.TeamSlug, obj.EnvironmentName) } -func (r *teamInventoryCountsResolver) PostgresInstances(ctx context.Context, obj *team.TeamInventoryCounts) (*postgres.TeamInventoryCountPostgresInstances, error) { - return &postgres.TeamInventoryCountPostgresInstances{ +func (r *teamInventoryCountsResolver) PostgresBranches(ctx context.Context, obj *team.TeamInventoryCounts) (*postgres.TeamInventoryCountPostgresBranches, error) { + return &postgres.TeamInventoryCountPostgresBranches{ Total: postgres.CountForTeam(ctx, obj.TeamSlug), }, nil } func (r *Resolver) PostgresAccess() gengql.PostgresAccessResolver { return &postgresAccessResolver{r} } -func (r *Resolver) PostgresInstance() gengql.PostgresInstanceResolver { - return &postgresInstanceResolver{r} -} +func (r *Resolver) PostgresBranch() gengql.PostgresBranchResolver { return &postgresBranchResolver{r} } -func (r *Resolver) PostgresInstanceConnection() gengql.PostgresInstanceConnectionResolver { - return &postgresInstanceConnectionResolver{r} +func (r *Resolver) PostgresBranchConnection() gengql.PostgresBranchConnectionResolver { + return &postgresBranchConnectionResolver{r} } type ( - postgresAccessResolver struct{ *Resolver } - postgresInstanceResolver struct{ *Resolver } - postgresInstanceConnectionResolver struct{ *Resolver } + postgresAccessResolver struct{ *Resolver } + postgresBranchResolver struct{ *Resolver } + postgresBranchConnectionResolver struct{ *Resolver } ) diff --git a/internal/graph/schema/postgres.graphqls b/internal/graph/schema/postgres.graphqls index 5dca4920f..78f8898c8 100644 --- a/internal/graph/schema/postgres.graphqls +++ b/internal/graph/schema/postgres.graphqls @@ -1,6 +1,6 @@ extend type Team { - "Postgres instances owned by the team." - postgresInstances( + "Postgres branches owned by the team." + postgresBranches( "Get the first n items in the connection. This can be used in combination with the after parameter." first: Int @@ -14,21 +14,21 @@ extend type Team { before: Cursor "Ordering options for items returned from the connection." - orderBy: PostgresInstanceOrder + orderBy: PostgresBranchOrder "Filtering options for items returned from the connection." - filter: PostgresInstanceFilter - ): PostgresInstanceConnection! + filter: PostgresBranchFilter + ): PostgresBranchConnection! } extend type TeamEnvironment { "Postgres in the team environment." postgres("Name of the Postgres in this team environment." name: String!): Postgres! - "Named PostgresInstance in the team environment." - postgresInstance( - "Name of the PostgresInstance in this team environment." + "Named PostgresBranch in the team environment." + postgresBranch( + "Name of the PostgresBranch in this team environment." name: String! - ): PostgresInstance! + ): PostgresBranch! """ EXPERIMENTAL: DO NOT USE Get a PostgresAccess and its state. Available to authorized team members. @@ -40,65 +40,65 @@ extend type TeamEnvironment { } extend interface Workload { - "Active PostgresInstances for all Postgres entries in uses.postgres." - postgresInstances( + "Active PostgresBranches for all Postgres entries in uses.postgres." + postgresBranches( "Ordering options for items returned from the connection." - orderBy: PostgresInstanceOrder - ): PostgresInstanceConnection! + orderBy: PostgresBranchOrder + ): PostgresBranchConnection! } extend type Application { - "Active PostgresInstances for all Postgres entries in uses.postgres." - postgresInstances( + "Active PostgresBranches for all Postgres entries in uses.postgres." + postgresBranches( "Ordering options for items returned from the connection." - orderBy: PostgresInstanceOrder - ): PostgresInstanceConnection! + orderBy: PostgresBranchOrder + ): PostgresBranchConnection! } extend type Job { - "Active PostgresInstances for all Postgres entries in uses.postgres." - postgresInstances( + "Active PostgresBranches for all Postgres entries in uses.postgres." + postgresBranches( "Ordering options for items returned from the connection." - orderBy: PostgresInstanceOrder - ): PostgresInstanceConnection! + orderBy: PostgresBranchOrder + ): PostgresBranchConnection! } -input PostgresInstanceOrder { - field: PostgresInstanceOrderField! +input PostgresBranchOrder { + field: PostgresBranchOrderField! direction: OrderDirection! } """ -Input for filtering Postgres instances. +Input for filtering Postgres branches. """ -input PostgresInstanceFilter { - "Filter by the name of the instance." +input PostgresBranchFilter { + "Filter by the name of the branch." name: String "Filter by environments." environments: [String!] - "Filter by instance state." - states: [PostgresInstanceState!] + "Filter by branch state." + states: [PostgresBranchState!] "Filter by user-defined labels. All listed labels must match." labels: [LabelFilter!] } -enum PostgresInstanceOrderField { +enum PostgresBranchOrderField { NAME ENVIRONMENT } -"A named PostgresInstance belonging to a Postgres." -type PostgresInstance implements Persistence & Node { +"A named PostgresBranch belonging to a Postgres." +type PostgresBranch implements Persistence & Node { id: ID! name: String! team: Team! teamEnvironment: TeamEnvironment! - "Postgres owning this PostgresInstance." + "Postgres owning this PostgresBranch." postgres: Postgres! - "Workloads using this instance while it is active." + "Workloads using this branch while it is active." workloads( "Get the first n items in the connection. This can be used in combination with the after parameter." first: Int @@ -112,13 +112,13 @@ type PostgresInstance implements Persistence & Node { "Get items before this cursor." before: Cursor ): WorkloadConnection! - "Current observed state of the instance." - state: PostgresInstanceState! - "User-defined labels on this instance." + "Current observed state of the branch." + state: PostgresBranchState! + "User-defined labels on this branch." labels: [ResourceLabel!]! } -"A Postgres whose active instance can change." +"A Postgres whose active branch can change." type Postgres implements Node { "Opaque identifier for this Postgres." id: ID! @@ -130,8 +130,8 @@ type Postgres implements Node { highAvailability: Boolean! "Requested CPU, memory and disk size, when present on this Postgres." resources: PostgresResources! - "Name of the currently active PostgresInstance, if selected." - activeInstance: String + "Name of the currently active PostgresBranch, if selected." + activeBranch: String "User-defined labels on this Postgres." labels: [ResourceLabel!]! } @@ -146,62 +146,62 @@ type PostgresResources { diskSize: String } -"Reconciliation and observed health of a PostgresInstance." -enum PostgresInstanceState { - "The instance is healthy and ready." +"Reconciliation and observed health of a PostgresBranch." +enum PostgresBranchState { + "The branch is healthy and ready." AVAILABLE - "The instance is provisioning or its state has not been observed yet." + "The branch is provisioning or its state has not been observed yet." PROGRESSING - "The instance has reported a failure." + "The branch has reported a failure." DEGRADED } -type PostgresInstanceConnection { +type PostgresBranchConnection { pageInfo: PageInfo! - nodes: [PostgresInstance!]! - edges: [PostgresInstanceEdge!]! + nodes: [PostgresBranch!]! + edges: [PostgresBranchEdge!]! """ - Facets for Postgres instances. Provides distribution counts to help narrow down results. + Facets for Postgres branches. Provides distribution counts to help narrow down results. Facet counts are computed over the full result set (ignoring pagination) but respect the current filter. """ - facets: PostgresInstanceFacets + facets: PostgresBranchFacets } -type PostgresInstanceEdge { +type PostgresBranchEdge { cursor: Cursor! - node: PostgresInstance! + node: PostgresBranch! } """ -Facets for Postgres instances, providing distribution counts across different dimensions. +Facets for Postgres branches, providing distribution counts across different dimensions. """ -type PostgresInstanceFacets { - "Distribution of instances by environment." +type PostgresBranchFacets { + "Distribution of branches by environment." environments: [StringFacetItem!]! - "Distribution of instances by state." - states: [PostgresInstanceStateFacetItem!]! + "Distribution of branches by state." + states: [PostgresBranchStateFacetItem!]! - "Distribution of instances by user-defined labels." + "Distribution of branches by user-defined labels." labels: [LabelFacetItem!]! } """ -A single facet item for Postgres instance states. +A single facet item for Postgres branch states. """ -type PostgresInstanceStateFacetItem { - "The Postgres instance state." - state: PostgresInstanceState! +type PostgresBranchStateFacetItem { + "The Postgres branch state." + state: PostgresBranchState! - "Number of matching instances." + "Number of matching branches." count: Int! } -extend union SearchNode = PostgresInstance +extend union SearchNode = PostgresBranch extend enum SearchType { - POSTGRES + POSTGRES_BRANCH } extend enum ActivityLogEntryResourceType { @@ -262,7 +262,7 @@ type PostgresPersonalAccessCreatedActivityLogEntry implements ActivityLogEntry & message: String! "Type of the affected resource." resourceType: ActivityLogEntryResourceType! - "Name of the affected Postgres instance." + "Name of the affected Postgres branch." resourceName: String! "The team slug that the entry belongs to." teamSlug: Slug! @@ -349,7 +349,7 @@ extend enum ActivityLogActivityType { """ POSTGRES_PERSONAL_ACCESS_CONNECTION """ - A Postgres instance was deleted + A Postgres branch was deleted """ POSTGRES_DELETED } @@ -359,12 +359,12 @@ extend type Mutation { grantPostgresAccess(input: GrantPostgresAccessInput!): GrantPostgresAccessPayload! """ EXPERIMENTAL: DO NOT USE - Create time-limited personal access to a NAIS Postgres instance through the brokered PostgresAccess and relay flow. + Create time-limited personal access to a NAIS Postgres branch through the brokered PostgresAccess and relay flow. When the access is ready, retrieve its connection materials through PostgresAccess.connection. """ createPostgresAccess(input: CreatePostgresAccessInput!): CreatePostgresAccessPayload! - "Delete a PostgresInstance that is not active on its Postgres." - deletePostgres(input: DeletePostgresInput!): DeletePostgresPayload! + "Delete a PostgresBranch that is not active on its Postgres." + deletePostgresBranch(input: DeletePostgresBranchInput!): DeletePostgresBranchPayload! } type GrantPostgresAccessPayload { @@ -390,11 +390,11 @@ type CreatePostgresAccessPayload { "Input for creating a time-limited personal Postgres access." input CreatePostgresAccessInput { - "Name of the PostgresInstance to access." - postgresInstance: String! - "Team that owns the Postgres instance." + "Name of the PostgresBranch to access." + postgresBranch: String! + "Team that owns the Postgres branch." teamSlug: Slug! - "Environment containing the Postgres instance." + "Environment containing the Postgres branch." environmentName: String! "Privileges requested for the personal database role." accessLevel: PostgresAccessLevel! @@ -414,30 +414,30 @@ enum PostgresAccessLevel { READWRITECREATE } -input DeletePostgresInput { - "Name of the Postgres instance." +input DeletePostgresBranchInput { + "Name of the PostgresBranch." name: String! - "The environment name that the Postgres instance belongs to." + "The environment containing the PostgresBranch." environmentName: String! - "The team that owns the Postgres instance." + "The team that owns the PostgresBranch." teamSlug: Slug! } -type DeletePostgresPayload { - "Whether or not the Postgres instance was deleted." - postgresDeleted: Boolean +type DeletePostgresBranchPayload { + "Whether the PostgresBranch was deleted." + postgresBranchDeleted: Boolean } extend type TeamInventoryCounts { - postgresInstances: TeamInventoryCountPostgresInstances! + postgresBranches: TeamInventoryCountPostgresBranches! } -type TeamInventoryCountPostgresInstances { - "Total number of Postgres instances." +type TeamInventoryCountPostgresBranches { + "Total number of Postgres branches." total: Int! } -"A time-limited personal access request for a Postgres instance." +"A time-limited personal access request for a Postgres branch." type PostgresAccess implements Node { "Opaque ID for this PostgresAccess resource." id: ID! @@ -447,8 +447,8 @@ type PostgresAccess implements Node { team: Team! "Environment for the access." teamEnvironment: TeamEnvironment! - "PostgresInstance selected by this access." - postgresInstance: PostgresInstance! + "PostgresBranch selected by this access." + postgresBranch: PostgresBranch! "Requested access level." accessLevel: PostgresAccessLevel! "Server-controlled expiry for this personal access." diff --git a/internal/grpc/grpc.go b/internal/grpc/grpc.go index 566a61bf9..f3df1ef3c 100644 --- a/internal/grpc/grpc.go +++ b/internal/grpc/grpc.go @@ -20,7 +20,7 @@ import ( "google.golang.org/grpc" ) -func Run(ctx context.Context, listenAddress string, pool *pgxpool.Pool, sqlDatabaseWatcher *watchers.SqlDatabaseWatcher, postgresWatcher *watchers.PostgresWatcher, log logrus.FieldLogger) error { +func Run(ctx context.Context, listenAddress string, pool *pgxpool.Pool, sqlDatabaseWatcher *watchers.SqlDatabaseWatcher, postgresBranchWatcher *watchers.PostgresBranchWatcher, log logrus.FieldLogger) error { log.Info("GRPC serving on ", listenAddress) lis, err := net.Listen("tcp", listenAddress) if err != nil { @@ -36,7 +36,7 @@ func Run(ctx context.Context, listenAddress string, pool *pgxpool.Pool, sqlDatab protoapi.RegisterUsersServer(s, grpcuser.NewServer(pool)) protoapi.RegisterReconcilersServer(s, grpcreconciler.NewServer(pool)) protoapi.RegisterDeploymentsServer(s, grpcdeployment.NewServer(pool)) - protoapi.RegisterDatabasesServer(s, grpcdatabase.NewServer(sqlDatabaseWatcher, postgresWatcher)) + protoapi.RegisterDatabasesServer(s, grpcdatabase.NewServer(sqlDatabaseWatcher, postgresBranchWatcher)) g, ctx := errgroup.WithContext(ctx) g.Go(func() error { return s.Serve(lis) }) diff --git a/internal/grpc/grpcdatabase/server.go b/internal/grpc/grpcdatabase/server.go index bd1a71ffd..a372d8d4b 100644 --- a/internal/grpc/grpcdatabase/server.go +++ b/internal/grpc/grpcdatabase/server.go @@ -14,28 +14,28 @@ import ( ) type Server struct { - sqlDatabaseWatcher *watchers.SqlDatabaseWatcher - postgresWatcher *watchers.PostgresWatcher + sqlDatabaseWatcher *watchers.SqlDatabaseWatcher + postgresBranchWatcher *watchers.PostgresBranchWatcher protoapi.UnimplementedDatabasesServer } -func NewServer(sqlDatabaseWatcher *watchers.SqlDatabaseWatcher, postgresWatcher *watchers.PostgresWatcher) *Server { +func NewServer(sqlDatabaseWatcher *watchers.SqlDatabaseWatcher, postgresBranchWatcher *watchers.PostgresBranchWatcher) *Server { return &Server{ - sqlDatabaseWatcher: sqlDatabaseWatcher, - postgresWatcher: postgresWatcher, + sqlDatabaseWatcher: sqlDatabaseWatcher, + postgresBranchWatcher: postgresBranchWatcher, } } func (s *Server) List(_ context.Context, r *protoapi.ListDatabasesRequest) (*protoapi.ListDatabasesResponse, error) { sqlDatabases := watcher.Objects(s.sqlDatabaseWatcher.GetByNamespace(r.TeamSlug)) - postgresInstances := watcher.Objects(s.postgresWatcher.GetByNamespace(r.TeamSlug)) + postgresBranches := watcher.Objects(s.postgresBranchWatcher.GetByNamespace(r.TeamSlug)) - all := make([]*protoapi.Database, 0, len(sqlDatabases)+len(postgresInstances)) + all := make([]*protoapi.Database, 0, len(sqlDatabases)+len(postgresBranches)) for _, d := range sqlDatabases { all = append(all, sqlDatabaseToProto(d)) } - for _, p := range postgresInstances { - all = append(all, postgresInstanceToProto(p)) + for _, p := range postgresBranches { + all = append(all, postgresBranchToProto(p)) } // Sort by (type, environment, name, database) for deterministic pagination. @@ -77,7 +77,7 @@ func sqlDatabaseToProto(d *sqlinstance.SQLDatabase) *protoapi.Database { } } -func postgresInstanceToProto(p *postgres.PostgresInstance) *protoapi.Database { +func postgresBranchToProto(p *postgres.PostgresBranch) *protoapi.Database { return &protoapi.Database{ Name: p.Name, Database: "app", diff --git a/internal/grpc/grpcdatabase/server_test.go b/internal/grpc/grpcdatabase/server_test.go index 319860134..2c075af51 100644 --- a/internal/grpc/grpcdatabase/server_test.go +++ b/internal/grpc/grpcdatabase/server_test.go @@ -203,7 +203,7 @@ func newServer(t *testing.T, ctx context.Context) *grpcdatabase.Server { t.Cleanup(mgr.Stop) sqlDatabaseWatcher := sqlinstance.NewDatabaseWatcher(ctx, mgr) - postgresWatcher := postgres.NewPostgresWatcher(ctx, mgr) + postgresBranchWatcher := postgres.NewPostgresBranchWatcher(ctx, mgr) ctxWait, cancel := context.WithTimeout(ctx, 5*time.Second) defer cancel() @@ -213,6 +213,6 @@ func newServer(t *testing.T, ctx context.Context) *grpcdatabase.Server { return grpcdatabase.NewServer( (*watchers.SqlDatabaseWatcher)(sqlDatabaseWatcher), - (*watchers.PostgresWatcher)(postgresWatcher), + (*watchers.PostgresBranchWatcher)(postgresBranchWatcher), ) } diff --git a/internal/grpc/grpcdatabase/testdata/dev-gcp/myteam/postgres.yaml b/internal/grpc/grpcdatabase/testdata/dev-gcp/myteam/postgres.yaml index 6b8b3310e..af5e715d7 100644 --- a/internal/grpc/grpcdatabase/testdata/dev-gcp/myteam/postgres.yaml +++ b/internal/grpc/grpcdatabase/testdata/dev-gcp/myteam/postgres.yaml @@ -7,10 +7,10 @@ metadata: spec: majorVersion: "17" status: - activeInstance: pg-b + activeBranch: pg-b --- apiVersion: nais.io/v1 -kind: PostgresInstance +kind: PostgresBranch metadata: name: pg-b namespace: myteam @@ -33,10 +33,10 @@ metadata: spec: majorVersion: "17" status: - activeInstance: pg-a + activeBranch: pg-a --- apiVersion: nais.io/v1 -kind: PostgresInstance +kind: PostgresBranch metadata: name: pg-a namespace: myteam diff --git a/internal/kubernetes/fake/fake.go b/internal/kubernetes/fake/fake.go index 5e7c5831a..e71300572 100644 --- a/internal/kubernetes/fake/fake.go +++ b/internal/kubernetes/fake/fake.go @@ -191,6 +191,8 @@ func depluralized(s string) string { return "remoteunleashes" case "postgreses": return "postgres" + case "postgresbranchs": + return "postgresbranches" } return s @@ -217,7 +219,7 @@ func NewDynamicClient(scheme *runtime.Scheme) *dynfake.FakeDynamicClient { unleash_nais_io_v1.GroupVersion.WithResource("remoteunleashes"): "RemoteUnleashList", mapperatorv1.GroupVersion.WithResource("postgres"): "PostgresList", {Group: "data.nais.io", Version: "v1", Resource: "postgres"}: "PostgresList", - mapperatorv1.GroupVersion.WithResource("postgresinstances"): "PostgresInstanceList", + mapperatorv1.GroupVersion.WithResource("postgresbranches"): "PostgresBranchList", nais_io_v1alpha1.GroupVersion.WithResource("tunnels"): "TunnelList", mapperatorv1.GroupVersion.WithResource("valkeys"): "ValkeyList", mapperatorv1.GroupVersion.WithResource("opensearches"): "OpenSearchList", diff --git a/internal/kubernetes/fake/postgres_fixtures_test.go b/internal/kubernetes/fake/postgres_fixtures_test.go index d10508d96..7352b72bb 100644 --- a/internal/kubernetes/fake/postgres_fixtures_test.go +++ b/internal/kubernetes/fake/postgres_fixtures_test.go @@ -6,8 +6,22 @@ import ( "github.com/nais/api/internal/kubernetes" "github.com/nais/api/internal/kubernetes/fake" + "k8s.io/apimachinery/pkg/api/meta" + "k8s.io/apimachinery/pkg/runtime/schema" ) +func TestPostgresBranchKindResolver(t *testing.T) { + _, kinds, _, err := fake.Clients(nil)("dev") + if err != nil { + t.Fatal(err) + } + resolved, err := kinds.KindsFor(schema.GroupVersionResource{Group: "nais.io", Version: "v1", Resource: "postgresbranches"}) + if err != nil || len(resolved) != 1 || resolved[0].Kind != "PostgresBranch" { + guessed, _ := meta.UnsafeGuessKindToResource(schema.GroupVersion{Group: "nais.io", Version: "v1"}.WithKind("PostgresBranch")) + t.Fatalf("resolving PostgresBranch resource: %v, %v (guessed %s)", resolved, err, guessed.Resource) + } +} + func TestPostgresFixturesUseRegisteredV1Kinds(t *testing.T) { scheme, err := kubernetes.NewScheme() if err != nil { @@ -17,9 +31,9 @@ func TestPostgresFixturesUseRegisteredV1Kinds(t *testing.T) { // suites may intentionally describe the same resource. for _, path := range []string{ "../../../integration_tests/k8s_resources/create_postgres_access", - "../../../integration_tests/k8s_resources/postgres_instances", + "../../../integration_tests/k8s_resources/postgres_branches", "../../../integration_tests/k8s_resources/postgres_workloads", - "../../../integration_tests/k8s_resources/postgres_delete", + "../../../integration_tests/k8s_resources/postgres_branch_delete", "../../../integration_tests/k8s_resources/postgres_audit_log", "../../../integration_tests/k8s_resources/label_selectors", "../../../data/k8s", diff --git a/internal/kubernetes/watchers/watchers.go b/internal/kubernetes/watchers/watchers.go index d93fcc555..2bae5f017 100644 --- a/internal/kubernetes/watchers/watchers.go +++ b/internal/kubernetes/watchers/watchers.go @@ -39,7 +39,7 @@ type ( BucketWatcher = watcher.Watcher[*bucket.Bucket] SqlDatabaseWatcher = watcher.Watcher[*sqlinstance.SQLDatabase] SqlInstanceWatcher = watcher.Watcher[*sqlinstance.SQLInstance] - PostgresWatcher = watcher.Watcher[*postgres.PostgresInstance] + PostgresBranchWatcher = watcher.Watcher[*postgres.PostgresBranch] KafkaTopicWatcher = watcher.Watcher[*kafkatopic.KafkaTopic] PodWatcher = watcher.Watcher[*v1.Pod] IngressWatcher = watcher.Watcher[*netv1.Ingress] @@ -63,7 +63,7 @@ type Watchers struct { BucketWatcher *BucketWatcher SqlDatabaseWatcher *SqlDatabaseWatcher SqlInstanceWatcher *SqlInstanceWatcher - PostgresWatcher *PostgresWatcher + PostgresBranchWatcher *PostgresBranchWatcher KafkaTopicWatcher *KafkaTopicWatcher PodWatcher *PodWatcher IngressWatcher *IngressWatcher @@ -93,7 +93,7 @@ func SetupWatchers( BucketWatcher: bucket.NewWatcher(ctx, watcherMgr), SqlDatabaseWatcher: sqlinstance.NewDatabaseWatcher(ctx, watcherMgr), SqlInstanceWatcher: sqlinstance.NewInstanceWatcher(ctx, watcherMgr), - PostgresWatcher: postgres.NewPostgresWatcher(ctx, watcherMgr), + PostgresBranchWatcher: postgres.NewPostgresBranchWatcher(ctx, watcherMgr), KafkaTopicWatcher: kafkatopic.NewWatcher(ctx, watcherMgr), PodWatcher: workload.NewWatcher(ctx, watcherMgr), IngressWatcher: application.NewIngressWatcher(ctx, watcherMgr), diff --git a/internal/persistence/postgres/connection.go b/internal/persistence/postgres/connection.go index a57e1dd98..ef508c3f4 100644 --- a/internal/persistence/postgres/connection.go +++ b/internal/persistence/postgres/connection.go @@ -99,7 +99,7 @@ func accessSecretData(secret, access *unstructured.Unstructured, key string) (st } func getAccessResource(ctx context.Context, environment, namespace, name string, gvr schema.GroupVersionResource) (*unstructured.Unstructured, error) { - client, err := fromContext(ctx).postgresWatcher.SystemAuthenticatedClient(ctx, environment, watcher.WithImpersonatedClientGVR(gvr)) + client, err := fromContext(ctx).postgresBranchWatcher.SystemAuthenticatedClient(ctx, environment, watcher.WithImpersonatedClientGVR(gvr)) if err != nil { return nil, fmt.Errorf("creating %s client: %w", gvr.Resource, err) } diff --git a/internal/persistence/postgres/dataloader.go b/internal/persistence/postgres/dataloader.go index 7759e8b55..3e9845d0c 100644 --- a/internal/persistence/postgres/dataloader.go +++ b/internal/persistence/postgres/dataloader.go @@ -6,6 +6,7 @@ import ( "github.com/nais/api/internal/kubernetes/watcher" "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/dynamic" ) type ctxKey int @@ -14,32 +15,36 @@ const loadersKey ctxKey = iota func NewLoaderContext( ctx context.Context, - postgresWatcher *watcher.Watcher[*PostgresInstance], + postgresBranchWatcher *watcher.Watcher[*PostgresBranch], auditLogProjectID string, auditLogLocation string, tenantName string, + clients map[string]dynamic.Interface, ) context.Context { - return context.WithValue(ctx, loadersKey, newLoaders(postgresWatcher, auditLogProjectID, auditLogLocation, tenantName)) + return context.WithValue(ctx, loadersKey, newLoaders(postgresBranchWatcher, auditLogProjectID, auditLogLocation, tenantName, clients)) } type loaders struct { - postgresWatcher *watcher.Watcher[*PostgresInstance] - auditLogProjectID string - auditLogLocation string - tenantName string + postgresBranchWatcher *watcher.Watcher[*PostgresBranch] + auditLogProjectID string + auditLogLocation string + tenantName string + clients map[string]dynamic.Interface } func newLoaders( - postgresWatcher *watcher.Watcher[*PostgresInstance], + postgresBranchWatcher *watcher.Watcher[*PostgresBranch], auditLogProjectID string, auditLogLocation string, tenantName string, + clients map[string]dynamic.Interface, ) *loaders { return &loaders{ - postgresWatcher: postgresWatcher, - auditLogProjectID: auditLogProjectID, - auditLogLocation: auditLogLocation, - tenantName: tenantName, + postgresBranchWatcher: postgresBranchWatcher, + auditLogProjectID: auditLogProjectID, + auditLogLocation: auditLogLocation, + tenantName: tenantName, + clients: clients, } } @@ -49,9 +54,9 @@ func GetAuditLogConfig(ctx context.Context) (projectID, location string) { return loaders.auditLogProjectID, loaders.auditLogLocation } -func NewPostgresWatcher(ctx context.Context, mgr *watcher.Manager) *watcher.Watcher[*PostgresInstance] { - w := watcher.Watch(mgr, &PostgresInstance{}, watcher.WithConverter(func(o *unstructured.Unstructured, environmentName string) (obj any, ok bool) { - ret, err := toPostgresInstance(o, environmentName) +func NewPostgresBranchWatcher(ctx context.Context, mgr *watcher.Manager) *watcher.Watcher[*PostgresBranch] { + w := watcher.Watch(mgr, &PostgresBranch{}, watcher.WithConverter(func(o *unstructured.Unstructured, environmentName string) (obj any, ok bool) { + ret, err := toPostgresBranch(o, environmentName) if err != nil { return nil, false } @@ -59,7 +64,7 @@ func NewPostgresWatcher(ctx context.Context, mgr *watcher.Manager) *watcher.Watc }), watcher.WithGVR(schema.GroupVersionResource{ Group: "nais.io", Version: "v1", - Resource: "postgresinstances", + Resource: "postgresbranches", })) w.Start(ctx) return w diff --git a/internal/persistence/postgres/delete_test.go b/internal/persistence/postgres/delete_test.go index d1104e60b..97a8a0abc 100644 --- a/internal/persistence/postgres/delete_test.go +++ b/internal/persistence/postgres/delete_test.go @@ -18,7 +18,7 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ) -func TestDeletePostgresInstanceRequiresInactiveInstance(t *testing.T) { +func TestDeletePostgresBranchRequiresInactiveBranch(t *testing.T) { instance := &unstructured.Unstructured{Object: map[string]any{ "metadata": map[string]any{"name": "orders-restored"}, }} @@ -27,10 +27,10 @@ func TestDeletePostgresInstanceRequiresInactiveInstance(t *testing.T) { postgres map[string]any wantDenied bool }{ - {"selected in status", map[string]any{"status": map[string]any{"activeInstance": "orders-restored"}}, true}, - {"selected in spec", map[string]any{"spec": map[string]any{"activeInstance": "orders-restored"}}, true}, - {"pending switch", map[string]any{"spec": map[string]any{"activeInstance": "orders-restored"}, "status": map[string]any{"activeInstance": "orders-original"}}, true}, - {"inactive", map[string]any{"status": map[string]any{"activeInstance": "orders-original"}}, false}, + {"selected in status", map[string]any{"status": map[string]any{"activeBranch": "orders-restored"}}, true}, + {"selected in spec", map[string]any{"spec": map[string]any{"activeBranch": "orders-restored"}}, true}, + {"pending switch", map[string]any{"spec": map[string]any{"activeBranch": "orders-restored"}, "status": map[string]any{"activeBranch": "orders-original"}}, true}, + {"inactive", map[string]any{"status": map[string]any{"activeBranch": "orders-original"}}, false}, {"default active", map[string]any{}, true}, } for _, tt := range tests { @@ -65,7 +65,7 @@ func TestWorkloadUsesMultiplePostgresResources(t *testing.T) { } t.Cleanup(mgr.Stop) ctx := context.Background() - postgresWatcher := NewPostgresWatcher(ctx, mgr) + postgresBranchWatcher := NewPostgresBranchWatcher(ctx, mgr) appWatcher := application.NewWatcher(ctx, mgr) jobWatcher := job.NewWatcher(ctx, mgr) wait, cancel := context.WithTimeout(ctx, 5*time.Second) @@ -73,7 +73,7 @@ func TestWorkloadUsesMultiplePostgresResources(t *testing.T) { if !mgr.WaitForReady(wait) { t.Fatal("watchers did not synchronize") } - ctx = NewLoaderContext(ctx, postgresWatcher, "", "", "nav") + ctx = NewLoaderContext(ctx, postgresBranchWatcher, "", "", "nav", mgr.GetDynamicClients()) ctx = application.NewLoaderContext(ctx, appWatcher, nil, log) ctx = job.NewLoaderContext(ctx, jobWatcher, nil) team := slug.Slug("postgres-workload-team") @@ -101,7 +101,7 @@ func TestWorkloadUsesMultiplePostgresResources(t *testing.T) { } } -func TestReadyPostgresInstanceUsesConcreteName(t *testing.T) { +func TestReadyPostgresBranchUsesConcreteName(t *testing.T) { scheme, err := kubernetes.NewScheme() if err != nil { t.Fatal(err) @@ -117,25 +117,25 @@ func TestReadyPostgresInstanceUsesConcreteName(t *testing.T) { } t.Cleanup(mgr.Stop) ctx := context.Background() - postgresWatcher := NewPostgresWatcher(ctx, mgr) + postgresBranchWatcher := NewPostgresBranchWatcher(ctx, mgr) wait, cancel := context.WithTimeout(ctx, 5*time.Second) defer cancel() if !mgr.WaitForReady(wait) { - t.Fatal("PostgresInstance watcher did not synchronize") + t.Fatal("PostgresBranch watcher did not synchronize") } - ctx = NewLoaderContext(ctx, postgresWatcher, "", "", "nav") + ctx = NewLoaderContext(ctx, postgresBranchWatcher, "", "", "nav", mgr.GetDynamicClients()) team := slug.Slug("someteamname") for _, name := range []string{"foobar", "foobar-recovered"} { - instance, err := GetReadyPostgresInstance(ctx, team, "dev", name) - if err != nil || instance.State != PostgresInstanceStateAvailable || instance.Name != name || instance.PostgresName != "foobar" { + instance, err := GetReadyPostgresBranch(ctx, team, "dev", name) + if err != nil || instance.State != PostgresBranchStateAvailable || instance.Name != name || instance.PostgresName != "foobar" { t.Errorf("%s: got instance %+v, error %v", name, instance, err) } } - instance, err := GetReadyPostgresInstance(ctx, team, "dev", "progressing") - if err != nil || instance.State == PostgresInstanceStateAvailable { + instance, err := GetReadyPostgresBranch(ctx, team, "dev", "progressing") + if err != nil || instance.State == PostgresBranchStateAvailable { t.Errorf("progressing instance = %+v, error %v", instance, err) } - _, err = GetReadyPostgresInstance(ctx, team, "dev", "missing") + _, err = GetReadyPostgresBranch(ctx, team, "dev", "missing") if !errors.Is(err, &watcher.ErrorNotFound{}) { t.Errorf("missing instance error = %v", err) } @@ -157,20 +157,20 @@ func TestCreatePostgresAccessRejectsMissingInstance(t *testing.T) { } t.Cleanup(mgr.Stop) ctx := context.Background() - postgresWatcher := NewPostgresWatcher(ctx, mgr) + postgresBranchWatcher := NewPostgresBranchWatcher(ctx, mgr) wait, cancel := context.WithTimeout(ctx, 5*time.Second) defer cancel() if !mgr.WaitForReady(wait) { - t.Fatal("PostgresInstance watcher did not synchronize") + t.Fatal("PostgresBranch watcher did not synchronize") } - ctx = NewLoaderContext(ctx, postgresWatcher, "", "", "nav") + ctx = NewLoaderContext(ctx, postgresBranchWatcher, "", "", "nav", mgr.GetDynamicClients()) input := CreatePostgresAccessInput{ - PostgresInstance: "missing", TeamSlug: slug.Slug("myteam"), + PostgresBranch: "missing", TeamSlug: slug.Slug("myteam"), EnvironmentName: "dev", AccessLevel: PostgresAccessLevelRead, Reason: "Investigating missing instance", } err = input.Validate(ctx) - if err == nil || !strings.Contains(err.Error(), `Could not find PostgresInstance named "missing"`) { + if err == nil || !strings.Contains(err.Error(), `Could not find PostgresBranch named "missing"`) { t.Errorf("validation error = %v, want named missing instance", err) } } diff --git a/internal/persistence/postgres/facets.go b/internal/persistence/postgres/facets.go index 6f0eb3b1a..0ce32c5c4 100644 --- a/internal/persistence/postgres/facets.go +++ b/internal/persistence/postgres/facets.go @@ -9,24 +9,24 @@ import ( ) // Filtered returns the filtered Postgres instances, computing it exactly once per request. -func (f *PostgresInstanceFacets) Filtered(ctx context.Context) []*PostgresInstance { +func (f *PostgresBranchFacets) Filtered(ctx context.Context) []*PostgresBranch { f.filteredOnce.Do(func() { - f.filteredInstances = SortFilterPostgresInstance.Filter(ctx, f.AllInstances, f.Filter) + f.filteredInstances = SortFilterPostgresBranch.Filter(ctx, f.AllInstances, f.Filter) }) return f.filteredInstances } // Environments computes environments facets for a Postgres query. -func (f *PostgresInstanceFacets) Environments(ctx context.Context) []model.StringFacetItem { +func (f *PostgresBranchFacets) Environments(ctx context.Context) []model.StringFacetItem { filtered := f.Filtered(ctx) - return model.ComputeEnvironmentsFacet(f.AllInstances, filtered, func(inst *PostgresInstance) string { + return model.ComputeEnvironmentsFacet(f.AllInstances, filtered, func(inst *PostgresBranch) string { return inst.EnvironmentName }) } // States computes states facets for a Postgres query. -func (f *PostgresInstanceFacets) States(ctx context.Context) []PostgresInstanceStateFacetItem { - stateCounts := map[PostgresInstanceState]int{} +func (f *PostgresBranchFacets) States(ctx context.Context) []PostgresBranchStateFacetItem { + stateCounts := map[PostgresBranchState]int{} for _, inst := range f.AllInstances { stateCounts[inst.State] = 0 } @@ -36,14 +36,14 @@ func (f *PostgresInstanceFacets) States(ctx context.Context) []PostgresInstanceS stateCounts[inst.State]++ } - states := make([]PostgresInstanceStateFacetItem, 0, len(stateCounts)) + states := make([]PostgresBranchStateFacetItem, 0, len(stateCounts)) for state, count := range stateCounts { - states = append(states, PostgresInstanceStateFacetItem{ + states = append(states, PostgresBranchStateFacetItem{ State: state, Count: count, }) } - slices.SortFunc(states, func(a, b PostgresInstanceStateFacetItem) int { + slices.SortFunc(states, func(a, b PostgresBranchStateFacetItem) int { return strings.Compare(a.State.String(), b.State.String()) }) @@ -51,9 +51,9 @@ func (f *PostgresInstanceFacets) States(ctx context.Context) []PostgresInstanceS } // Labels computes labels facets for a Postgres query. -func (f *PostgresInstanceFacets) Labels(ctx context.Context) []model.LabelFacetItem { +func (f *PostgresBranchFacets) Labels(ctx context.Context) []model.LabelFacetItem { filtered := f.Filtered(ctx) - return model.ComputeLabelsFacet(f.AllInstances, filtered, func(inst *PostgresInstance) []*model.ResourceLabel { + return model.ComputeLabelsFacet(f.AllInstances, filtered, func(inst *PostgresBranch) []*model.ResourceLabel { return inst.Labels }) } diff --git a/internal/persistence/postgres/facets_test.go b/internal/persistence/postgres/facets_test.go index bff04e2a7..5db7cd727 100644 --- a/internal/persistence/postgres/facets_test.go +++ b/internal/persistence/postgres/facets_test.go @@ -9,24 +9,24 @@ import ( ) func TestComputeFacets(t *testing.T) { - all := []*PostgresInstance{ - {Name: "first", EnvironmentName: "dev", State: PostgresInstanceStateAvailable}, - {Name: "second", EnvironmentName: "dev", State: PostgresInstanceStateProgressing}, - {Name: "third", EnvironmentName: "prod", State: PostgresInstanceStateDegraded}, + all := []*PostgresBranch{ + {Name: "first", EnvironmentName: "dev", State: PostgresBranchStateAvailable}, + {Name: "second", EnvironmentName: "dev", State: PostgresBranchStateProgressing}, + {Name: "third", EnvironmentName: "prod", State: PostgresBranchStateDegraded}, } tests := []struct { name string - filter *PostgresInstanceFilter + filter *PostgresBranchFilter wantEnvironments []model.StringFacetItem - wantStates []PostgresInstanceStateFacetItem + wantStates []PostgresBranchStateFacetItem }{ - {"all", nil, []model.StringFacetItem{{Value: "dev", Count: 2}, {Value: "prod", Count: 1}}, []PostgresInstanceStateFacetItem{{State: PostgresInstanceStateAvailable, Count: 1}, {State: PostgresInstanceStateDegraded, Count: 1}, {State: PostgresInstanceStateProgressing, Count: 1}}}, - {"filter by environment", &PostgresInstanceFilter{Environments: []string{"dev"}}, []model.StringFacetItem{{Value: "dev", Count: 2}, {Value: "prod", Count: 0}}, []PostgresInstanceStateFacetItem{{State: PostgresInstanceStateAvailable, Count: 1}, {State: PostgresInstanceStateDegraded, Count: 0}, {State: PostgresInstanceStateProgressing, Count: 1}}}, - {"filter by state", &PostgresInstanceFilter{States: []PostgresInstanceState{PostgresInstanceStateAvailable}}, []model.StringFacetItem{{Value: "dev", Count: 1}, {Value: "prod", Count: 0}}, []PostgresInstanceStateFacetItem{{State: PostgresInstanceStateAvailable, Count: 1}, {State: PostgresInstanceStateDegraded, Count: 0}, {State: PostgresInstanceStateProgressing, Count: 0}}}, + {"all", nil, []model.StringFacetItem{{Value: "dev", Count: 2}, {Value: "prod", Count: 1}}, []PostgresBranchStateFacetItem{{State: PostgresBranchStateAvailable, Count: 1}, {State: PostgresBranchStateDegraded, Count: 1}, {State: PostgresBranchStateProgressing, Count: 1}}}, + {"filter by environment", &PostgresBranchFilter{Environments: []string{"dev"}}, []model.StringFacetItem{{Value: "dev", Count: 2}, {Value: "prod", Count: 0}}, []PostgresBranchStateFacetItem{{State: PostgresBranchStateAvailable, Count: 1}, {State: PostgresBranchStateDegraded, Count: 0}, {State: PostgresBranchStateProgressing, Count: 1}}}, + {"filter by state", &PostgresBranchFilter{States: []PostgresBranchState{PostgresBranchStateAvailable}}, []model.StringFacetItem{{Value: "dev", Count: 1}, {Value: "prod", Count: 0}}, []PostgresBranchStateFacetItem{{State: PostgresBranchStateAvailable, Count: 1}, {State: PostgresBranchStateDegraded, Count: 0}, {State: PostgresBranchStateProgressing, Count: 0}}}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - f := &PostgresInstanceFacets{AllInstances: all, Filter: tt.filter} + f := &PostgresBranchFacets{AllInstances: all, Filter: tt.filter} if got := f.Environments(context.Background()); !reflect.DeepEqual(got, tt.wantEnvironments) { t.Errorf("environments=%v want %v", got, tt.wantEnvironments) } diff --git a/internal/persistence/postgres/grant.go b/internal/persistence/postgres/grant.go index 70be4e361..b66157d3e 100644 --- a/internal/persistence/postgres/grant.go +++ b/internal/persistence/postgres/grant.go @@ -9,6 +9,7 @@ import ( "github.com/nais/api/internal/activitylog" "github.com/nais/api/internal/auth/authz" + "github.com/nais/api/internal/environmentmapper" "github.com/nais/api/internal/kubernetes" "github.com/nais/api/internal/kubernetes/watcher" "github.com/nais/api/internal/slug" @@ -19,10 +20,14 @@ import ( "k8s.io/client-go/dynamic" ) -// Keep the legacy Zalando port-forward grant independent of the new NAIS Postgres watcher. -// Only this mutation reads data.nais.io; the rest of the Postgres API uses nais.io. +// Keep the legacy Zalando port-forward grant independent of the PostgresBranch CRD. +// It uses API's existing system clients; only this mutation reads data.nais.io. func legacyPostgresClient(ctx context.Context, environment string, gvr schema.GroupVersionResource) (dynamic.NamespaceableResourceInterface, error) { - return fromContext(ctx).postgresWatcher.SystemAuthenticatedClient(ctx, environment, watcher.WithImpersonatedClientGVR(gvr)) + client, ok := fromContext(ctx).clients[environmentmapper.ClusterName(environment)] + if !ok { + return nil, &watcher.ErrorUnknownEnvironment{Environment: environment} + } + return client.Resource(gvr), nil } func getLegacyPostgres(ctx context.Context, input GrantPostgresAccessInput) error { diff --git a/internal/persistence/postgres/grant_test.go b/internal/persistence/postgres/grant_test.go index 25cacc629..7d12ccaa6 100644 --- a/internal/persistence/postgres/grant_test.go +++ b/internal/persistence/postgres/grant_test.go @@ -29,13 +29,13 @@ func TestLegacyPostgresGrantValidatesTheOldCluster(t *testing.T) { } t.Cleanup(mgr.Stop) ctx := context.Background() - postgresWatcher := NewPostgresWatcher(ctx, mgr) wait, cancel := context.WithTimeout(ctx, 5*time.Second) defer cancel() if !mgr.WaitForReady(wait) { t.Fatal("Postgres watcher did not synchronize") } - ctx = NewLoaderContext(ctx, postgresWatcher, "", "", "nav") + // The legacy grant must work even when the PostgresBranch CRD is absent. + ctx = NewLoaderContext(ctx, nil, "", "", "nav", mgr.GetDynamicClients()) input := GrantPostgresAccessInput{ ClusterName: "foobar", TeamSlug: slug.Slug("someteamname"), EnvironmentName: "dev", Grantee: "someone@example.com", Duration: "30m", diff --git a/internal/persistence/postgres/models.go b/internal/persistence/postgres/models.go index 4438b6be7..7d1e14334 100644 --- a/internal/persistence/postgres/models.go +++ b/internal/persistence/postgres/models.go @@ -26,36 +26,36 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" ) -type PostgresInstanceEdge = pagination.Edge[*PostgresInstance] +type PostgresBranchEdge = pagination.Edge[*PostgresBranch] -type PostgresInstanceFilter struct { - Name string `json:"name"` - Environments []string `json:"environments"` - States []PostgresInstanceState `json:"states"` - Labels model.LabelFilters `json:"labels,omitempty"` +type PostgresBranchFilter struct { + Name string `json:"name"` + Environments []string `json:"environments"` + States []PostgresBranchState `json:"states"` + Labels model.LabelFilters `json:"labels,omitempty"` } -type PostgresInstanceConnection = pagination.FacetableConnection[*PostgresInstance, *PostgresInstanceFilter] +type PostgresBranchConnection = pagination.FacetableConnection[*PostgresBranch, *PostgresBranchFilter] -type PostgresInstanceFacets struct { - AllInstances []*PostgresInstance - Filter *PostgresInstanceFilter +type PostgresBranchFacets struct { + AllInstances []*PostgresBranch + Filter *PostgresBranchFilter filteredOnce sync.Once - filteredInstances []*PostgresInstance + filteredInstances []*PostgresBranch } -type PostgresInstanceStateFacetItem struct { - State PostgresInstanceState `json:"state"` - Count int `json:"count"` +type PostgresBranchStateFacetItem struct { + State PostgresBranchState `json:"state"` + Count int `json:"count"` } -// PostgresInstance represents an independently running database instance. -type PostgresInstance struct { +// PostgresBranch represents an independently running database instance. +type PostgresBranch struct { Name string `json:"name"` EnvironmentName string `json:"-"` TeamSlug slug.Slug `json:"-"` PostgresName string `json:"postgres"` - State PostgresInstanceState `json:"state"` + State PostgresBranchState `json:"state"` Labels []*model.ResourceLabel `json:"labels"` } @@ -64,7 +64,7 @@ type Postgres struct { Name string `json:"name"` EnvironmentName string `json:"-"` TeamSlug slug.Slug `json:"-"` - ActiveInstance *string `json:"activeInstance,omitempty"` + ActiveBranch *string `json:"activeBranch,omitempty"` MajorVersion string `json:"majorVersion"` HighAvailability bool `json:"highAvailability"` Resources PostgresResources `json:"resources"` @@ -81,50 +81,50 @@ type PostgresResources struct { func (Postgres) IsNode() {} func (p *Postgres) ID() ident.Ident { return newPostgresIdent(p.TeamSlug, p.EnvironmentName, p.Name) } -type PostgresInstanceState string +type PostgresBranchState string const ( - PostgresInstanceStateAvailable PostgresInstanceState = "AVAILABLE" - PostgresInstanceStateProgressing PostgresInstanceState = "PROGRESSING" - PostgresInstanceStateDegraded PostgresInstanceState = "DEGRADED" + PostgresBranchStateAvailable PostgresBranchState = "AVAILABLE" + PostgresBranchStateProgressing PostgresBranchState = "PROGRESSING" + PostgresBranchStateDegraded PostgresBranchState = "DEGRADED" ) -var AllPostgresInstanceState = []PostgresInstanceState{ - PostgresInstanceStateAvailable, - PostgresInstanceStateProgressing, - PostgresInstanceStateDegraded, +var AllPostgresBranchState = []PostgresBranchState{ + PostgresBranchStateAvailable, + PostgresBranchStateProgressing, + PostgresBranchStateDegraded, } -func (e PostgresInstanceState) IsValid() bool { +func (e PostgresBranchState) IsValid() bool { switch e { - case PostgresInstanceStateAvailable, PostgresInstanceStateProgressing, PostgresInstanceStateDegraded: + case PostgresBranchStateAvailable, PostgresBranchStateProgressing, PostgresBranchStateDegraded: return true } return false } -func (e PostgresInstanceState) String() string { +func (e PostgresBranchState) String() string { return string(e) } -func (e *PostgresInstanceState) UnmarshalGQL(v any) error { +func (e *PostgresBranchState) UnmarshalGQL(v any) error { str, ok := v.(string) if !ok { return fmt.Errorf("enums must be strings") } - *e = PostgresInstanceState(str) + *e = PostgresBranchState(str) if !e.IsValid() { - return fmt.Errorf("%s is not a valid PostgresInstanceState", str) + return fmt.Errorf("%s is not a valid PostgresBranchState", str) } return nil } -func (e PostgresInstanceState) MarshalGQL(w io.Writer) { +func (e PostgresBranchState) MarshalGQL(w io.Writer) { fmt.Fprint(w, strconv.Quote(e.String())) } -func (e *PostgresInstanceState) UnmarshalJSON(b []byte) error { +func (e *PostgresBranchState) UnmarshalJSON(b []byte) error { s, err := strconv.Unquote(string(b)) if err != nil { return err @@ -132,29 +132,29 @@ func (e *PostgresInstanceState) UnmarshalJSON(b []byte) error { return e.UnmarshalGQL(s) } -func (e PostgresInstanceState) MarshalJSON() ([]byte, error) { +func (e PostgresBranchState) MarshalJSON() ([]byte, error) { var buf bytes.Buffer e.MarshalGQL(&buf) return buf.Bytes(), nil } -func (PostgresInstance) IsPersistence() {} +func (PostgresBranch) IsPersistence() {} -func (PostgresInstance) IsNode() {} +func (PostgresBranch) IsNode() {} -func (PostgresInstance) IsSearchNode() {} +func (PostgresBranch) IsSearchNode() {} -type DeletePostgresInput struct { +type DeletePostgresBranchInput struct { Name string `json:"name"` EnvironmentName string `json:"environmentName"` TeamSlug slug.Slug `json:"teamSlug"` } -func (i *DeletePostgresInput) Validate(ctx context.Context) error { +func (i *DeletePostgresBranchInput) Validate(ctx context.Context) error { return i.ValidationErrors(ctx).NilIfEmpty() } -func (i *DeletePostgresInput) ValidationErrors(_ context.Context) *validate.ValidationErrors { +func (i *DeletePostgresBranchInput) ValidationErrors(_ context.Context) *validate.ValidationErrors { verr := validate.New() i.Name = strings.TrimSpace(i.Name) i.EnvironmentName = strings.TrimSpace(i.EnvironmentName) @@ -172,8 +172,8 @@ func (i *DeletePostgresInput) ValidationErrors(_ context.Context) *validate.Vali return verr } -type DeletePostgresPayload struct { - PostgresDeleted *bool `json:"postgresDeleted,omitempty"` +type DeletePostgresBranchPayload struct { + PostgresBranchDeleted *bool `json:"postgresBranchDeleted,omitempty"` } // GrantPostgresAccessInput retains the temporary port-forward grant for legacy Zalando Postgres clusters. @@ -234,12 +234,12 @@ type GrantPostgresAccessPayload struct { // CreatePostgresAccessInput requests a new, time-limited personal database access. // The authenticated actor and final expiry are server-controlled. type CreatePostgresAccessInput struct { - PostgresInstance string `json:"postgresInstance"` - TeamSlug slug.Slug `json:"teamSlug"` - EnvironmentName string `json:"environmentName"` - AccessLevel PostgresAccessLevel `json:"accessLevel"` - Reason string `json:"reason"` - TTL string `json:"ttl"` + PostgresBranch string `json:"postgresBranch"` + TeamSlug slug.Slug `json:"teamSlug"` + EnvironmentName string `json:"environmentName"` + AccessLevel PostgresAccessLevel `json:"accessLevel"` + Reason string `json:"reason"` + TTL string `json:"ttl"` } func (i *CreatePostgresAccessInput) Validate(ctx context.Context) error { @@ -248,13 +248,13 @@ func (i *CreatePostgresAccessInput) Validate(ctx context.Context) error { func (i *CreatePostgresAccessInput) ValidationErrors(ctx context.Context) *validate.ValidationErrors { verr := validate.New() - i.PostgresInstance = strings.TrimSpace(i.PostgresInstance) + i.PostgresBranch = strings.TrimSpace(i.PostgresBranch) i.EnvironmentName = strings.TrimSpace(i.EnvironmentName) i.Reason = strings.TrimSpace(i.Reason) i.TTL = strings.TrimSpace(i.TTL) - if i.PostgresInstance == "" { - verr.Add("postgresInstance", "Postgres instance must not be empty.") + if i.PostgresBranch == "" { + verr.Add("postgresBranch", "Postgres branch must not be empty.") } if i.EnvironmentName == "" { verr.Add("environmentName", "Environment name must not be empty.") @@ -272,19 +272,19 @@ func (i *CreatePostgresAccessInput) ValidationErrors(ctx context.Context) *valid verr.Add("ttl", "%s", err) } - if i.PostgresInstance == "" || i.EnvironmentName == "" || i.TeamSlug == "" { + if i.PostgresBranch == "" || i.EnvironmentName == "" || i.TeamSlug == "" { return verr } - instance, err := GetReadyPostgresInstance(ctx, i.TeamSlug, i.EnvironmentName, i.PostgresInstance) + instance, err := GetReadyPostgresBranch(ctx, i.TeamSlug, i.EnvironmentName, i.PostgresBranch) if err != nil { if k8serrors.IsNotFound(err) || errors.Is(err, &watcher.ErrorNotFound{}) { - verr.Add("postgresInstance", "Could not find PostgresInstance named %q", i.PostgresInstance) + verr.Add("postgresBranch", "Could not find PostgresBranch named %q", i.PostgresBranch) } else { - verr.Add("postgresInstance", "%s", err) + verr.Add("postgresBranch", "%s", err) } - } else if instance.State != PostgresInstanceStateAvailable { - verr.Add("postgresInstance", "Postgres instance %q is not available.", i.PostgresInstance) + } else if instance.State != PostgresBranchStateAvailable { + verr.Add("postgresBranch", "Postgres branch %q is not available.", i.PostgresBranch) } return verr @@ -331,43 +331,43 @@ func (e PostgresAccessLevel) MarshalGQL(w io.Writer) { fmt.Fprint(w, strconv.Quote(e.String())) } -func (p *PostgresInstance) GetObjectKind() schema.ObjectKind { +func (p *PostgresBranch) GetObjectKind() schema.ObjectKind { return schema.EmptyObjectKind } -func (p *PostgresInstance) DeepCopyObject() runtime.Object { +func (p *PostgresBranch) DeepCopyObject() runtime.Object { return p } -func (p *PostgresInstance) GetName() string { +func (p *PostgresBranch) GetName() string { return p.Name } -func (p *PostgresInstance) GetNamespace() string { +func (p *PostgresBranch) GetNamespace() string { return p.TeamSlug.String() } -func (p *PostgresInstance) GetLabels() map[string]string { +func (p *PostgresBranch) GetLabels() map[string]string { return nil } -func (p *PostgresInstance) ID() ident.Ident { +func (p *PostgresBranch) ID() ident.Ident { return newIdent(p.TeamSlug, p.EnvironmentName, p.Name) } -func toPostgresInstance(u *unstructured.Unstructured, environmentName string) (*PostgresInstance, error) { - obj := &nais_io_v1.PostgresInstance{} +func toPostgresBranch(u *unstructured.Unstructured, environmentName string) (*PostgresBranch, error) { + obj := &nais_io_v1.PostgresBranch{} if err := runtime.DefaultUnstructuredConverter.FromUnstructured(u.Object, obj); err != nil { - return nil, fmt.Errorf("converting PostgresInstance: %w", err) + return nil, fmt.Errorf("converting PostgresBranch: %w", err) } if obj.Spec.Postgres == "" { - return nil, fmt.Errorf("PostgresInstance %q has no Postgres", obj.Name) + return nil, fmt.Errorf("PostgresBranch %q has no Postgres", obj.Name) } - state := PostgresInstanceStateProgressing + state := PostgresBranchStateProgressing if obj.Status != nil { state = postgresStateFromConditions(obj.Status.Conditions, obj.Status.ReconcilePhase == "Completed" && obj.Status.ObservedGeneration >= obj.Generation) } - return &PostgresInstance{Name: obj.Name, EnvironmentName: environmentName, TeamSlug: slug.Slug(obj.Namespace), PostgresName: obj.Spec.Postgres, State: state, Labels: model.UserLabels(obj.Labels)}, nil + return &PostgresBranch{Name: obj.Name, EnvironmentName: environmentName, TeamSlug: slug.Slug(obj.Namespace), PostgresName: obj.Spec.Postgres, State: state, Labels: model.UserLabels(obj.Labels)}, nil } func toPostgres(u *unstructured.Unstructured, environmentName string) (*Postgres, error) { @@ -376,8 +376,8 @@ func toPostgres(u *unstructured.Unstructured, environmentName string) (*Postgres return nil, fmt.Errorf("converting Postgres: %w", err) } var active *string - if obj.Status != nil && obj.Status.ActiveInstance != "" { - active = &obj.Status.ActiveInstance + if obj.Status != nil && obj.Status.ActiveBranch != "" { + active = &obj.Status.ActiveBranch } quantity := func(value resource.Quantity) *string { if value.IsZero() { @@ -388,7 +388,7 @@ func toPostgres(u *unstructured.Unstructured, environmentName string) (*Postgres } return &Postgres{ Name: obj.Name, EnvironmentName: environmentName, TeamSlug: slug.Slug(obj.Namespace), - ActiveInstance: active, MajorVersion: obj.Spec.MajorVersion, HighAvailability: obj.Spec.HighAvailability, + ActiveBranch: active, MajorVersion: obj.Spec.MajorVersion, HighAvailability: obj.Spec.HighAvailability, Resources: PostgresResources{ CPU: quantity(obj.Spec.Resources.Cpu), Memory: quantity(obj.Spec.Resources.Memory), DiskSize: quantity(obj.Spec.Resources.DiskSize), @@ -399,9 +399,9 @@ func toPostgres(u *unstructured.Unstructured, environmentName string) (*Postgres // postgresStateFromConditions interprets the CNPG phase mirrored by pgrator. // ObservedState=False means no phase has been observed, not a failed cluster. -func postgresStateFromConditions(conditions []metav1.Condition, reconciled bool) PostgresInstanceState { +func postgresStateFromConditions(conditions []metav1.Condition, reconciled bool) PostgresBranchState { if !reconciled { - return PostgresInstanceStateProgressing + return PostgresBranchStateProgressing } for _, condition := range conditions { if condition.Type != "cluster.postgresql.cnpg.io/ObservedState" || condition.Status != metav1.ConditionTrue { @@ -413,64 +413,64 @@ func postgresStateFromConditions(conditions []metav1.Condition, reconciled bool) } switch phase { case "Cluster in healthy state": - return PostgresInstanceStateAvailable + return PostgresBranchStateAvailable case "Cluster is unrecoverable and needs manual intervention", "Cluster cannot proceed to reconciliation due to an unknown plugin being required", "Cluster cannot proceed to reconciliation due to an error while interacting with plugins", "Cluster has incomplete or invalid image catalog": - return PostgresInstanceStateDegraded + return PostgresBranchStateDegraded } } - return PostgresInstanceStateProgressing + return PostgresBranchStateProgressing } -type PostgresInstanceOrder struct { - Field PostgresInstanceOrderField `json:"field"` - Direction model.OrderDirection `json:"direction"` +type PostgresBranchOrder struct { + Field PostgresBranchOrderField `json:"field"` + Direction model.OrderDirection `json:"direction"` } -type PostgresInstanceOrderField string +type PostgresBranchOrderField string const ( - PostgresInstanceOrderFieldName PostgresInstanceOrderField = "NAME" - PostgresInstanceOrderFieldEnvironment PostgresInstanceOrderField = "ENVIRONMENT" + PostgresBranchOrderFieldName PostgresBranchOrderField = "NAME" + PostgresBranchOrderFieldEnvironment PostgresBranchOrderField = "ENVIRONMENT" ) -var AllPostgresInstanceOrderField = []PostgresInstanceOrderField{ - PostgresInstanceOrderFieldName, - PostgresInstanceOrderFieldEnvironment, +var AllPostgresBranchOrderField = []PostgresBranchOrderField{ + PostgresBranchOrderFieldName, + PostgresBranchOrderFieldEnvironment, } -func (e PostgresInstanceOrderField) IsValid() bool { +func (e PostgresBranchOrderField) IsValid() bool { switch e { - case PostgresInstanceOrderFieldName, PostgresInstanceOrderFieldEnvironment: + case PostgresBranchOrderFieldName, PostgresBranchOrderFieldEnvironment: return true } return false } -func (e PostgresInstanceOrderField) String() string { +func (e PostgresBranchOrderField) String() string { return string(e) } -func (e *PostgresInstanceOrderField) UnmarshalGQL(v any) error { +func (e *PostgresBranchOrderField) UnmarshalGQL(v any) error { str, ok := v.(string) if !ok { return fmt.Errorf("enums must be strings") } - *e = PostgresInstanceOrderField(str) + *e = PostgresBranchOrderField(str) if !e.IsValid() { - return fmt.Errorf("%s is not a valid PostgresInstanceOrderField", str) + return fmt.Errorf("%s is not a valid PostgresBranchOrderField", str) } return nil } -func (e PostgresInstanceOrderField) MarshalGQL(w io.Writer) { +func (e PostgresBranchOrderField) MarshalGQL(w io.Writer) { fmt.Fprint(w, strconv.Quote(e.String())) } -func (e *PostgresInstanceOrderField) UnmarshalJSON(b []byte) error { +func (e *PostgresBranchOrderField) UnmarshalJSON(b []byte) error { s, err := strconv.Unquote(string(b)) if err != nil { return err @@ -478,13 +478,13 @@ func (e *PostgresInstanceOrderField) UnmarshalJSON(b []byte) error { return e.UnmarshalGQL(s) } -func (e PostgresInstanceOrderField) MarshalJSON() ([]byte, error) { +func (e PostgresBranchOrderField) MarshalJSON() ([]byte, error) { var buf bytes.Buffer e.MarshalGQL(&buf) return buf.Bytes(), nil } -type TeamInventoryCountPostgresInstances struct { +type TeamInventoryCountPostgresBranches struct { Total int `json:"total"` } @@ -492,16 +492,16 @@ type TeamInventoryCountPostgresInstances struct { // database access. Credentials are read from the controller-owned Secret on // demand; they are never cached by the watcher. type PostgresAccess struct { - Name string `json:"name"` - TeamSlug slug.Slug `json:"-"` - EnvironmentName string `json:"-"` - PostgresInstanceName string `json:"postgresInstance"` - Username string `json:"username"` - AccessLevel PostgresAccessLevel `json:"accessLevel"` - ExpiresAt time.Time `json:"expiresAt"` - State PostgresAccessState `json:"state"` - Message *string `json:"message,omitempty"` - RelayAccess *string `json:"relayAccess,omitempty"` + Name string `json:"name"` + TeamSlug slug.Slug `json:"-"` + EnvironmentName string `json:"-"` + PostgresBranchName string `json:"postgresBranch"` + Username string `json:"username"` + AccessLevel PostgresAccessLevel `json:"accessLevel"` + ExpiresAt time.Time `json:"expiresAt"` + State PostgresAccessState `json:"state"` + Message *string `json:"message,omitempty"` + RelayAccess *string `json:"relayAccess,omitempty"` } func (PostgresAccess) IsNode() {} diff --git a/internal/persistence/postgres/models_test.go b/internal/persistence/postgres/models_test.go index 43bd76580..45657b2aa 100644 --- a/internal/persistence/postgres/models_test.go +++ b/internal/persistence/postgres/models_test.go @@ -10,34 +10,37 @@ import ( "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" ) -func TestToPostgresInstance(t *testing.T) { +func TestToPostgresBranch(t *testing.T) { obj := &unstructured.Unstructured{Object: map[string]any{ - "apiVersion": "nais.io/v1", "kind": "PostgresInstance", + "apiVersion": "nais.io/v1", "kind": "PostgresBranch", "metadata": map[string]any{"name": "orders-restored", "namespace": "my-team"}, "spec": map[string]any{"postgres": "orders"}, "status": map[string]any{"reconcilePhase": "Completed", "conditions": []any{map[string]any{"type": "cluster.postgresql.cnpg.io/ObservedState", "status": "True", "lastTransitionTime": "2026-01-01T00:00:00Z", "reason": "Reconciled", "message": "Cluster is in phase: Cluster in healthy state"}}}, }} - got, err := toPostgresInstance(obj, "dev") + got, err := toPostgresBranch(obj, "dev") if err != nil { t.Fatal(err) } - if got.Name != "orders-restored" || got.PostgresName != "orders" || got.State != PostgresInstanceStateAvailable { - t.Errorf("unexpected physical instance: %+v", got) + if got.Name != "orders-restored" || got.PostgresName != "orders" || got.State != PostgresBranchStateAvailable { + t.Errorf("unexpected PostgresBranch: %+v", got) + } + if got.ID().Type != "PBR" { + t.Errorf("PostgresBranch ID type = %q, want PBR", got.ID().Type) } } -func TestToLogicalPostgres(t *testing.T) { +func TestToPostgres(t *testing.T) { obj := &unstructured.Unstructured{Object: map[string]any{ "apiVersion": "nais.io/v1", "kind": "Postgres", "metadata": map[string]any{"name": "orders", "namespace": "my-team"}, "spec": map[string]any{"majorVersion": "17", "highAvailability": true, "resources": map[string]any{"cpu": "100m", "memory": "2Gi", "diskSize": "10Gi"}}, - "status": map[string]any{"activeInstance": "orders-restored"}, + "status": map[string]any{"activeBranch": "orders-restored"}, }} got, err := toPostgres(obj, "dev") if err != nil { t.Fatal(err) } - if got.Name != "orders" || got.MajorVersion != "17" || got.ActiveInstance == nil || *got.ActiveInstance != "orders-restored" { + if got.Name != "orders" || got.MajorVersion != "17" || got.ActiveBranch == nil || *got.ActiveBranch != "orders-restored" { t.Errorf("unexpected Postgres: %+v", got) } if got.Resources.CPU == nil || *got.Resources.CPU != "100m" || got.Resources.Memory == nil || *got.Resources.Memory != "2Gi" || got.Resources.DiskSize == nil || *got.Resources.DiskSize != "10Gi" { @@ -50,15 +53,15 @@ func TestPostgresStateFromConditions(t *testing.T) { name string reconciled bool conditions []metav1.Condition - want PostgresInstanceState + want PostgresBranchState }{ - {name: "not reconciled", want: PostgresInstanceStateProgressing}, - {name: "healthy", reconciled: true, conditions: []metav1.Condition{{Type: "cluster.postgresql.cnpg.io/ObservedState", Status: metav1.ConditionTrue, Message: "Cluster is in phase: Cluster in healthy state"}}, want: PostgresInstanceStateAvailable}, - {name: "still starting", reconciled: true, conditions: []metav1.Condition{{Type: "cluster.postgresql.cnpg.io/ObservedState", Status: metav1.ConditionFalse, Message: "Cluster is in phase: "}}, want: PostgresInstanceStateProgressing}, - {name: "unrecoverable", reconciled: true, conditions: []metav1.Condition{{Type: "cluster.postgresql.cnpg.io/ObservedState", Status: metav1.ConditionTrue, Message: "Cluster is in phase: Cluster is unrecoverable and needs manual intervention"}}, want: PostgresInstanceStateDegraded}, - {name: "plugin failure", reconciled: true, conditions: []metav1.Condition{{Type: "cluster.postgresql.cnpg.io/ObservedState", Status: metav1.ConditionTrue, Message: "Cluster is in phase: Cluster cannot proceed to reconciliation due to an error while interacting with plugins"}}, want: PostgresInstanceStateDegraded}, - {name: "other phase", reconciled: true, conditions: []metav1.Condition{{Type: "cluster.postgresql.cnpg.io/ObservedState", Status: metav1.ConditionTrue, Message: "Cluster is in phase: Online upgrade in progress"}}, want: PostgresInstanceStateProgressing}, - {name: "missing", reconciled: true, want: PostgresInstanceStateProgressing}, + {name: "not reconciled", want: PostgresBranchStateProgressing}, + {name: "healthy", reconciled: true, conditions: []metav1.Condition{{Type: "cluster.postgresql.cnpg.io/ObservedState", Status: metav1.ConditionTrue, Message: "Cluster is in phase: Cluster in healthy state"}}, want: PostgresBranchStateAvailable}, + {name: "still starting", reconciled: true, conditions: []metav1.Condition{{Type: "cluster.postgresql.cnpg.io/ObservedState", Status: metav1.ConditionFalse, Message: "Cluster is in phase: "}}, want: PostgresBranchStateProgressing}, + {name: "unrecoverable", reconciled: true, conditions: []metav1.Condition{{Type: "cluster.postgresql.cnpg.io/ObservedState", Status: metav1.ConditionTrue, Message: "Cluster is in phase: Cluster is unrecoverable and needs manual intervention"}}, want: PostgresBranchStateDegraded}, + {name: "plugin failure", reconciled: true, conditions: []metav1.Condition{{Type: "cluster.postgresql.cnpg.io/ObservedState", Status: metav1.ConditionTrue, Message: "Cluster is in phase: Cluster cannot proceed to reconciliation due to an error while interacting with plugins"}}, want: PostgresBranchStateDegraded}, + {name: "other phase", reconciled: true, conditions: []metav1.Condition{{Type: "cluster.postgresql.cnpg.io/ObservedState", Status: metav1.ConditionTrue, Message: "Cluster is in phase: Online upgrade in progress"}}, want: PostgresBranchStateProgressing}, + {name: "missing", reconciled: true, want: PostgresBranchStateProgressing}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -69,15 +72,15 @@ func TestPostgresStateFromConditions(t *testing.T) { } } -func TestDeletePostgresInput_ValidationErrors(t *testing.T) { +func TestDeletePostgresBranchInput_ValidationErrors(t *testing.T) { tests := []struct { name string - input DeletePostgresInput + input DeletePostgresBranchInput wantErrFields []string }{ { name: "all fields valid", - input: DeletePostgresInput{ + input: DeletePostgresBranchInput{ Name: "my-db", EnvironmentName: "dev", TeamSlug: slug.Slug("my-team"), @@ -86,7 +89,7 @@ func TestDeletePostgresInput_ValidationErrors(t *testing.T) { }, { name: "empty name", - input: DeletePostgresInput{ + input: DeletePostgresBranchInput{ Name: "", EnvironmentName: "dev", TeamSlug: slug.Slug("my-team"), @@ -95,7 +98,7 @@ func TestDeletePostgresInput_ValidationErrors(t *testing.T) { }, { name: "empty environmentName", - input: DeletePostgresInput{ + input: DeletePostgresBranchInput{ Name: "my-db", EnvironmentName: "", TeamSlug: slug.Slug("my-team"), @@ -104,7 +107,7 @@ func TestDeletePostgresInput_ValidationErrors(t *testing.T) { }, { name: "empty teamSlug", - input: DeletePostgresInput{ + input: DeletePostgresBranchInput{ Name: "my-db", EnvironmentName: "dev", TeamSlug: slug.Slug(""), @@ -113,7 +116,7 @@ func TestDeletePostgresInput_ValidationErrors(t *testing.T) { }, { name: "all fields empty", - input: DeletePostgresInput{ + input: DeletePostgresBranchInput{ Name: "", EnvironmentName: "", TeamSlug: slug.Slug(""), @@ -122,7 +125,7 @@ func TestDeletePostgresInput_ValidationErrors(t *testing.T) { }, { name: "whitespace-only name treated as empty", - input: DeletePostgresInput{ + input: DeletePostgresBranchInput{ Name: " ", EnvironmentName: "dev", TeamSlug: slug.Slug("my-team"), diff --git a/internal/persistence/postgres/node.go b/internal/persistence/postgres/node.go index 7f63751f5..96052981b 100644 --- a/internal/persistence/postgres/node.go +++ b/internal/persistence/postgres/node.go @@ -10,18 +10,18 @@ import ( type identType int const ( - identPostgresInstance identType = iota + identPostgresBranch identType = iota identPostgresAccess identPostgres ) func init() { - ident.RegisterIdentType(identPostgresInstance, "PP", GetPostgresInstanceByIdent) + ident.RegisterIdentType(identPostgresBranch, "PBR", GetPostgresBranchByIdent) ident.RegisterIdentType(identPostgresAccess, "PA", GetPostgresAccessByIdent) ident.RegisterIdentType(identPostgres, "PG", GetPostgresByIdent) } -func parsePostgresInstanceIdent(id ident.Ident) (teamSlug slug.Slug, environmentName, postgresInstanceName string, err error) { +func parsePostgresBranchIdent(id ident.Ident) (teamSlug slug.Slug, environmentName, postgresBranchName string, err error) { parts := id.Parts() if len(parts) != 3 { return "", "", "", fmt.Errorf("invalid ident") @@ -30,8 +30,8 @@ func parsePostgresInstanceIdent(id ident.Ident) (teamSlug slug.Slug, environment return slug.Slug(parts[0]), parts[1], parts[2], nil } -func newIdent(teamSlug slug.Slug, environmentName, postgresInstanceName string) ident.Ident { - return ident.NewIdent(identPostgresInstance, teamSlug.String(), environmentName, postgresInstanceName) +func newIdent(teamSlug slug.Slug, environmentName, postgresBranchName string) ident.Ident { + return ident.NewIdent(identPostgresBranch, teamSlug.String(), environmentName, postgresBranchName) } func parseAccessIdent(id ident.Ident) (teamSlug slug.Slug, environmentName, name string, err error) { diff --git a/internal/persistence/postgres/queries.go b/internal/persistence/postgres/queries.go index a3f827924..fabde8c0d 100644 --- a/internal/persistence/postgres/queries.go +++ b/internal/persistence/postgres/queries.go @@ -30,24 +30,24 @@ import ( "k8s.io/utils/ptr" ) -func Delete(ctx context.Context, input DeletePostgresInput) (*DeletePostgresPayload, error) { +func Delete(ctx context.Context, input DeletePostgresBranchInput) (*DeletePostgresBranchPayload, error) { if err := input.Validate(ctx); err != nil { return nil, err } - client, err := fromContext(ctx).postgresWatcher.SystemAuthenticatedClient(ctx, input.EnvironmentName) + client, err := fromContext(ctx).postgresBranchWatcher.SystemAuthenticatedClient(ctx, input.EnvironmentName) if err != nil { return nil, err } instance, err := client.Namespace(input.TeamSlug.String()).Get(ctx, input.Name, metav1.GetOptions{}) if err != nil { - return nil, fmt.Errorf("getting PostgresInstance %q before deletion: %w", input.Name, err) + return nil, fmt.Errorf("getting PostgresBranch %q before deletion: %w", input.Name, err) } postgresName, _, err := unstructured.NestedString(instance.Object, "spec", "postgres") if err != nil || postgresName == "" { - return nil, apierror.Errorf("PostgresInstance %q has no Postgres", input.Name) + return nil, apierror.Errorf("PostgresBranch %q has no Postgres", input.Name) } - postgresClient, err := fromContext(ctx).postgresWatcher.SystemAuthenticatedClient(ctx, input.EnvironmentName, watcher.WithImpersonatedClientGVR(schema.GroupVersionResource{ + postgresClient, err := fromContext(ctx).postgresBranchWatcher.SystemAuthenticatedClient(ctx, input.EnvironmentName, watcher.WithImpersonatedClientGVR(schema.GroupVersionResource{ Group: "nais.io", Version: "v1", Resource: "postgres", })) if err != nil { @@ -75,17 +75,17 @@ func Delete(ctx context.Context, input DeletePostgresInput) (*DeletePostgresPayl return nil, err } - return &DeletePostgresPayload{PostgresDeleted: new(true)}, nil + return &DeletePostgresBranchPayload{PostgresBranchDeleted: new(true)}, nil } // ensureInstanceMayBeDeleted prevents an API request from marking the active // instance as terminating. Pgrator independently blocks finalization as well. func ensureInstanceMayBeDeleted(instance, postgres *unstructured.Unstructured) error { - requested, _, err := unstructured.NestedString(postgres.Object, "spec", "activeInstance") + requested, _, err := unstructured.NestedString(postgres.Object, "spec", "activeBranch") if err != nil { return err } - current, _, err := unstructured.NestedString(postgres.Object, "status", "activeInstance") + current, _, err := unstructured.NestedString(postgres.Object, "status", "activeBranch") if err != nil { return err } @@ -94,12 +94,12 @@ func ensureInstanceMayBeDeleted(instance, postgres *unstructured.Unstructured) e current = postgres.GetName() } if instance.GetName() == requested || instance.GetName() == current { - return apierror.Errorf("PostgresInstance %q is active and cannot be deleted", instance.GetName()) + return apierror.Errorf("PostgresBranch %q is active and cannot be deleted", instance.GetName()) } return nil } -func GetForWorkload(ctx context.Context, teamSlug slug.Slug, environmentName, postgresName string) (*PostgresInstance, error) { +func GetForWorkload(ctx context.Context, teamSlug slug.Slug, environmentName, postgresName string) (*PostgresBranch, error) { if postgresName == "" { return nil, nil } @@ -107,16 +107,16 @@ func GetForWorkload(ctx context.Context, teamSlug slug.Slug, environmentName, po if err != nil { return nil, err } - if postgres.ActiveInstance == nil { + if postgres.ActiveBranch == nil { return nil, nil } - return GetPostgresInstance(ctx, teamSlug, environmentName, *postgres.ActiveInstance) + return GetPostgresBranch(ctx, teamSlug, environmentName, *postgres.ActiveBranch) } // ListForWorkload resolves each Postgres use to the instance selected by that // Postgres. A workload can use several databases, each with its own active instance. -func ListForWorkload(ctx context.Context, teamSlug slug.Slug, environmentName string, uses []liberatorv1.PostgresUse) ([]*PostgresInstance, error) { - instances := make([]*PostgresInstance, 0, len(uses)) +func ListForWorkload(ctx context.Context, teamSlug slug.Slug, environmentName string, uses []liberatorv1.PostgresUse) ([]*PostgresBranch, error) { + instances := make([]*PostgresBranch, 0, len(uses)) for _, use := range uses { instance, err := GetForWorkload(ctx, teamSlug, environmentName, use.Name) if err != nil { @@ -126,39 +126,39 @@ func ListForWorkload(ctx context.Context, teamSlug slug.Slug, environmentName st instances = append(instances, instance) } } - slices.SortFunc(instances, func(a, b *PostgresInstance) int { return cmp.Compare(a.Name, b.Name) }) + slices.SortFunc(instances, func(a, b *PostgresBranch) int { return cmp.Compare(a.Name, b.Name) }) return instances, nil } -func ListForTeam(ctx context.Context, teamSlug slug.Slug, page *pagination.Pagination, orderBy *PostgresInstanceOrder, filter *PostgresInstanceFilter) (*PostgresInstanceConnection, error) { +func ListForTeam(ctx context.Context, teamSlug slug.Slug, page *pagination.Pagination, orderBy *PostgresBranchOrder, filter *PostgresBranchFilter) (*PostgresBranchConnection, error) { all := ListAllForTeam(ctx, teamSlug, filter) if orderBy == nil { - orderBy = &PostgresInstanceOrder{ - Field: PostgresInstanceOrderFieldName, + orderBy = &PostgresBranchOrder{ + Field: PostgresBranchOrderFieldName, Direction: model.OrderDirectionAsc, } } - return SortFilterPostgresInstance.PaginatedList(ctx, all, page, orderBy.Field, orderBy.Direction, filter), nil + return SortFilterPostgresBranch.PaginatedList(ctx, all, page, orderBy.Field, orderBy.Direction, filter), nil } -func ListAllForTeam(ctx context.Context, teamSlug slug.Slug, filter *PostgresInstanceFilter) []*PostgresInstance { - all := fromContext(ctx).postgresWatcher.GetByNamespace(teamSlug.String()) +func ListAllForTeam(ctx context.Context, teamSlug slug.Slug, filter *PostgresBranchFilter) []*PostgresBranch { + all := fromContext(ctx).postgresBranchWatcher.GetByNamespace(teamSlug.String()) return watcher.Objects(all) } func CountForTeam(ctx context.Context, teamSlug slug.Slug) int { - return len(fromContext(ctx).postgresWatcher.GetByNamespace(teamSlug.String())) + return len(fromContext(ctx).postgresBranchWatcher.GetByNamespace(teamSlug.String())) } -func GetPostgresInstanceByIdent(ctx context.Context, id ident.Ident) (*PostgresInstance, error) { - teamSlug, environmentName, clusterName, err := parsePostgresInstanceIdent(id) +func GetPostgresBranchByIdent(ctx context.Context, id ident.Ident) (*PostgresBranch, error) { + teamSlug, environmentName, clusterName, err := parsePostgresBranchIdent(id) if err != nil { return nil, err } - return GetPostgresInstance(ctx, teamSlug, environmentName, clusterName) + return GetPostgresBranch(ctx, teamSlug, environmentName, clusterName) } func GetPostgresByIdent(ctx context.Context, id ident.Ident) (*Postgres, error) { @@ -249,7 +249,7 @@ func GetPostgresAccessConnection(ctx context.Context, input PostgresAccessConnec } func getPostgresAccessResource(ctx context.Context, name string, teamSlug slug.Slug, environmentName string) (*unstructured.Unstructured, error) { - accessClient, err := fromContext(ctx).postgresWatcher.SystemAuthenticatedClient(ctx, environmentName, watcher.WithImpersonatedClientGVR(postgresAccessGVR())) + accessClient, err := fromContext(ctx).postgresBranchWatcher.SystemAuthenticatedClient(ctx, environmentName, watcher.WithImpersonatedClientGVR(postgresAccessGVR())) if err != nil { return nil, fmt.Errorf("creating postgresaccess client: %w", err) } @@ -324,7 +324,7 @@ func postgresAccessIsReady(obj map[string]any) bool { func toPostgresAccess(u *unstructured.Unstructured, teamSlug slug.Slug, environmentName string) (*PostgresAccess, error) { name := u.GetName() - postgresInstance, _, _ := unstructured.NestedString(u.Object, "spec", "postgresInstance") + postgresBranch, _, _ := unstructured.NestedString(u.Object, "spec", "postgresBranch") username, _, _ := unstructured.NestedString(u.Object, "spec", "username") levelStr, _, _ := unstructured.NestedString(u.Object, "spec", "accessLevel") expiresStr, _, _ := unstructured.NestedString(u.Object, "spec", "expiresAt") @@ -344,16 +344,16 @@ func toPostgresAccess(u *unstructured.Unstructured, teamSlug slug.Slug, environm relayName, _, _ := unstructured.NestedString(u.Object, "status", "relayAccess") return &PostgresAccess{ - Name: name, - TeamSlug: teamSlug, - EnvironmentName: environmentName, - PostgresInstanceName: postgresInstance, - Username: username, - AccessLevel: level, - ExpiresAt: expiresAt, - State: state, - Message: strPtr(message), - RelayAccess: strPtr(relayName), + Name: name, + TeamSlug: teamSlug, + EnvironmentName: environmentName, + PostgresBranchName: postgresBranch, + Username: username, + AccessLevel: level, + ExpiresAt: expiresAt, + State: state, + Message: strPtr(message), + RelayAccess: strPtr(relayName), }, nil } @@ -400,12 +400,12 @@ func postgresAccessState(obj map[string]any, expiresAt time.Time) (PostgresAcces return PostgresAccessStatePending, "waiting for controller" } -func GetReadyPostgresInstance(ctx context.Context, teamSlug slug.Slug, environmentName, name string) (*PostgresInstance, error) { - instance, err := GetPostgresInstance(ctx, teamSlug, environmentName, name) +func GetReadyPostgresBranch(ctx context.Context, teamSlug slug.Slug, environmentName, name string) (*PostgresBranch, error) { + instance, err := GetPostgresBranch(ctx, teamSlug, environmentName, name) if err != nil { return nil, err } - if instance.State != PostgresInstanceStateAvailable { + if instance.State != PostgresBranchStateAvailable { return instance, nil } if _, err := GetPostgres(ctx, teamSlug, environmentName, instance.PostgresName); err != nil { @@ -413,24 +413,24 @@ func GetReadyPostgresInstance(ctx context.Context, teamSlug slug.Slug, environme } // The pgrator reconciliation condition reflects the CNPG phase, but must be // corroborated with CNPG's own Ready condition before issuing access. - client, err := fromContext(ctx).postgresWatcher.SystemAuthenticatedClient(ctx, environmentName, watcher.WithImpersonatedClientGVR(schema.GroupVersionResource{Group: "postgresql.cnpg.io", Version: "v1", Resource: "clusters"})) + client, err := fromContext(ctx).postgresBranchWatcher.SystemAuthenticatedClient(ctx, environmentName, watcher.WithImpersonatedClientGVR(schema.GroupVersionResource{Group: "postgresql.cnpg.io", Version: "v1", Resource: "clusters"})) if err != nil { return nil, err } cluster, err := client.Namespace(teamSlug.String()).Get(ctx, nais_io_v1.CNPGClusterName(name), metav1.GetOptions{}) if k8serrors.IsNotFound(err) { - instance.State = PostgresInstanceStateProgressing + instance.State = PostgresBranchStateProgressing return instance, nil } if err != nil { - return nil, fmt.Errorf("getting CNPG Cluster for PostgresInstance %q: %w", name, err) + return nil, fmt.Errorf("getting CNPG Cluster for PostgresBranch %q: %w", name, err) } conditions, found, err := unstructured.NestedSlice(cluster.Object, "status", "conditions") if err != nil { return nil, err } if !found { - instance.State = PostgresInstanceStateProgressing + instance.State = PostgresBranchStateProgressing return instance, nil } for _, raw := range conditions { @@ -439,16 +439,16 @@ func GetReadyPostgresInstance(ctx context.Context, teamSlug slug.Slug, environme return instance, nil } } - instance.State = PostgresInstanceStateProgressing + instance.State = PostgresBranchStateProgressing return instance, nil } -func GetPostgresInstance(ctx context.Context, teamSlug slug.Slug, environmentName, name string) (*PostgresInstance, error) { - return fromContext(ctx).postgresWatcher.Get(environmentName, teamSlug.String(), name) +func GetPostgresBranch(ctx context.Context, teamSlug slug.Slug, environmentName, name string) (*PostgresBranch, error) { + return fromContext(ctx).postgresBranchWatcher.Get(environmentName, teamSlug.String(), name) } func GetPostgres(ctx context.Context, teamSlug slug.Slug, environmentName, name string) (*Postgres, error) { - client, err := fromContext(ctx).postgresWatcher.SystemAuthenticatedClient(ctx, environmentName, watcher.WithImpersonatedClientGVR(schema.GroupVersionResource{Group: "nais.io", Version: "v1", Resource: "postgres"})) + client, err := fromContext(ctx).postgresBranchWatcher.SystemAuthenticatedClient(ctx, environmentName, watcher.WithImpersonatedClientGVR(schema.GroupVersionResource{Group: "nais.io", Version: "v1", Resource: "postgres"})) if err != nil { return nil, err } @@ -474,7 +474,7 @@ func CreatePostgresAccess(ctx context.Context, input CreatePostgresAccessInput) return nil, err } - client, err := fromContext(ctx).postgresWatcher.SystemAuthenticatedClient(ctx, input.EnvironmentName, watcher.WithImpersonatedClientGVR(postgresAccessGVR())) + client, err := fromContext(ctx).postgresBranchWatcher.SystemAuthenticatedClient(ctx, input.EnvironmentName, watcher.WithImpersonatedClientGVR(postgresAccessGVR())) if err != nil { return nil, err } @@ -491,7 +491,7 @@ func CreatePostgresAccess(ctx context.Context, input CreatePostgresAccessInput) Action: activityLogEntryActionCreatePersonalAccess, Actor: authz.ActorFromContext(ctx).User, ResourceType: activityLogEntryResourceTypePostgres, - ResourceName: input.PostgresInstance, + ResourceName: input.PostgresBranch, EnvironmentName: new(input.EnvironmentName), TeamSlug: new(input.TeamSlug), Data: PostgresPersonalAccessCreatedActivityLogEntryData{ @@ -534,21 +534,21 @@ func newPostgresAccessResource(input CreatePostgresAccessInput, username, name s res.SetAnnotations(kubernetes.WithCommonAnnotations(nil, username)) kubernetes.SetManagedByConsoleLabel(res) res.Object["spec"] = map[string]any{ - "postgresInstance": input.PostgresInstance, - "username": username, - "accessLevel": input.AccessLevel.CRDValue(), - "expiresAt": expiresAt.Format(time.RFC3339), + "postgresBranch": input.PostgresBranch, + "username": username, + "accessLevel": input.AccessLevel.CRDValue(), + "expiresAt": expiresAt.Format(time.RFC3339), } return res } func WorkloadsForInstance(ctx context.Context, teamSlug slug.Slug, environmentName, instanceName string) []workload.Workload { - instance, err := GetPostgresInstance(ctx, teamSlug, environmentName, instanceName) + instance, err := GetPostgresBranch(ctx, teamSlug, environmentName, instanceName) if err != nil { return nil } postgres, err := GetPostgres(ctx, teamSlug, environmentName, instance.PostgresName) - if err != nil || postgres.ActiveInstance == nil || *postgres.ActiveInstance != instanceName { + if err != nil || postgres.ActiveBranch == nil || *postgres.ActiveBranch != instanceName { return nil } apps := application.ListAllForTeamInEnvironment(ctx, teamSlug, environmentName) diff --git a/internal/persistence/postgres/queries_test.go b/internal/persistence/postgres/queries_test.go index 7c986251f..ff66daeba 100644 --- a/internal/persistence/postgres/queries_test.go +++ b/internal/persistence/postgres/queries_test.go @@ -13,10 +13,10 @@ import ( func TestNewPostgresAccessResource(t *testing.T) { expiresAt := time.Date(2026, time.September, 17, 12, 0, 0, 0, time.UTC) resource := newPostgresAccessResource(CreatePostgresAccessInput{ - PostgresInstance: "orders", - TeamSlug: slug.Slug("team-a"), - EnvironmentName: "dev", - AccessLevel: PostgresAccessLevelReadWrite, + PostgresBranch: "orders", + TeamSlug: slug.Slug("team-a"), + EnvironmentName: "dev", + AccessLevel: PostgresAccessLevelReadWrite, }, "user@example.com", "postgres-access-12345678", expiresAt) if got, want := resource.GetAPIVersion(), "nais.io/v1"; got != want { @@ -37,10 +37,10 @@ func TestNewPostgresAccessResource(t *testing.T) { t.Fatalf("spec = (%v, %t, %v), want a spec", spec, found, err) } wantSpec := map[string]any{ - "postgresInstance": "orders", - "username": "user@example.com", - "accessLevel": "readwrite", - "expiresAt": "2026-09-17T12:00:00Z", + "postgresBranch": "orders", + "username": "user@example.com", + "accessLevel": "readwrite", + "expiresAt": "2026-09-17T12:00:00Z", } if !reflect.DeepEqual(wantSpec, spec) { t.Errorf("spec = %#v, want %#v", spec, wantSpec) @@ -176,12 +176,12 @@ func TestPostgresAccessConnectionDetails(t *testing.T) { "metadata": map[string]any{"name": "access"}, "spec": map[string]any{"expiresAt": "2026-09-17T13:00:00Z"}, "status": map[string]any{ - "databaseRole": "personal-role", - "relayAccess": "access", - "tokenSecret": "access-relay-token", - "serverName": "pg-orders-rw.team.svc.cluster.local", + "databaseRole": "personal-role", + "relayAccess": "access", + "tokenSecret": "access-relay-token", + "serverName": "pg-orders-rw.team.svc.cluster.local", "serverCASecret": "pg-orders-ca", - "conditions": []any{map[string]any{"type": "Ready", "status": "True"}}, + "conditions": []any{map[string]any{"type": "Ready", "status": "True"}}, }, }} } diff --git a/internal/persistence/postgres/search.go b/internal/persistence/postgres/search.go index dd9eaef50..57597e0a3 100644 --- a/internal/persistence/postgres/search.go +++ b/internal/persistence/postgres/search.go @@ -9,14 +9,14 @@ import ( "github.com/nais/api/internal/slug" ) -func AddSearchPostgres(client search.Client, watcher *watcher.Watcher[*PostgresInstance]) { - createIdent := func(env string, obj *PostgresInstance) ident.Ident { +func AddSearchPostgresBranch(client search.Client, watcher *watcher.Watcher[*PostgresBranch]) { + createIdent := func(env string, obj *PostgresBranch) ident.Ident { return newIdent(slug.Slug(obj.GetNamespace()), env, obj.GetName()) } gbi := func(ctx context.Context, id ident.Ident) (search.SearchNode, error) { - return GetPostgresInstanceByIdent(ctx, id) + return GetPostgresBranchByIdent(ctx, id) } - client.AddClient("POSTGRES", search.NewK8sSearch("POSTGRES", watcher, gbi, createIdent)) + client.AddClient("POSTGRES_BRANCH", search.NewK8sSearch("POSTGRES_BRANCH", watcher, gbi, createIdent)) } diff --git a/internal/persistence/postgres/sortfilter.go b/internal/persistence/postgres/sortfilter.go index 30ebbb47b..805822036 100644 --- a/internal/persistence/postgres/sortfilter.go +++ b/internal/persistence/postgres/sortfilter.go @@ -9,17 +9,17 @@ import ( "github.com/nais/api/internal/graph/sortfilter" ) -var SortFilterPostgresInstance = sortfilter.New[*PostgresInstance, PostgresInstanceOrderField, *PostgresInstanceFilter]() +var SortFilterPostgresBranch = sortfilter.New[*PostgresBranch, PostgresBranchOrderField, *PostgresBranchFilter]() func init() { - SortFilterPostgresInstance.RegisterSort("NAME", func(ctx context.Context, a, b *PostgresInstance) int { + SortFilterPostgresBranch.RegisterSort("NAME", func(ctx context.Context, a, b *PostgresBranch) int { return strings.Compare(a.GetName(), b.GetName()) }, "ENVIRONMENT") - SortFilterPostgresInstance.RegisterSort("ENVIRONMENT", func(ctx context.Context, a, b *PostgresInstance) int { + SortFilterPostgresBranch.RegisterSort("ENVIRONMENT", func(ctx context.Context, a, b *PostgresBranch) int { return strings.Compare(a.EnvironmentName, b.EnvironmentName) }, "NAME") - SortFilterPostgresInstance.RegisterFilter(func(ctx context.Context, v *PostgresInstance, filter *PostgresInstanceFilter) bool { + SortFilterPostgresBranch.RegisterFilter(func(ctx context.Context, v *PostgresBranch, filter *PostgresBranchFilter) bool { if filter.Name != "" { if !strings.Contains(strings.ToLower(v.Name), strings.ToLower(filter.Name)) { return false From 4d37b2d2f749e9489b5345e6b45e674cd9c105fc Mon Sep 17 00:00:00 2001 From: Johnny Fredheim Horvi Date: Tue, 29 Sep 2026 20:44:13 +0200 Subject: [PATCH 18/19] fix: build PostgresBranch API against published pgrator module --- go.mod | 68 ++++++------ go.sum | 126 ++++++++++++----------- internal/thirdparty/promclient/client.go | 2 +- 3 files changed, 103 insertions(+), 93 deletions(-) diff --git a/go.mod b/go.mod index e08a92fae..dc1984c78 100644 --- a/go.mod +++ b/go.mod @@ -41,14 +41,14 @@ require ( github.com/nais/api/pkg/apiclient v0.0.0-20250219111538-2b76a0fd6ed9 github.com/nais/bifrost v0.0.0-20260106105449-911627ac2c61 github.com/nais/liberator v0.0.0-20260903194126-706ea87ddf9a - github.com/nais/pgrator/pkg/api v0.0.0-20260915202302-d699a2823ec5 + github.com/nais/pgrator/pkg/api v0.0.0-20260929133826-b665367bc31f github.com/nais/tester v0.2.0 github.com/nais/unleasherator v0.0.0-20251216221129-efebc54203fe github.com/nais/v13s/pkg/api v0.0.0-20260826091953-1b518b13ca28 github.com/patrickmn/go-cache v2.1.0+incompatible github.com/pressly/goose/v3 v3.27.0 - github.com/prometheus/client_golang v1.23.2 - github.com/prometheus/common v0.69.0 + github.com/prometheus/client_golang v1.24.0 + github.com/prometheus/common v0.70.0 github.com/prometheus/prometheus v0.312.0 github.com/ravilushqa/otelgqlgen v0.19.0 github.com/robfig/cron/v3 v3.0.1 @@ -64,7 +64,7 @@ require ( github.com/yuin/gopher-lua v1.1.2 github.com/zitadel/oidc/v3 v3.33.1 github.com/zitadel/zitadel-go/v3 v3.4.3 - go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.67.0 + go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.68.0 go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.69.0 go.opentelemetry.io/otel v1.44.0 go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.44.0 @@ -74,7 +74,7 @@ require ( go.opentelemetry.io/otel/sdk v1.44.0 go.opentelemetry.io/otel/sdk/metric v1.44.0 go.opentelemetry.io/otel/trace v1.44.0 - golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa + golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f golang.org/x/oauth2 v0.36.0 golang.org/x/sync v0.22.0 golang.org/x/text v0.41.0 @@ -83,9 +83,9 @@ require ( google.golang.org/genproto/googleapis/api v0.0.0-20260630182238-925bb5da69e7 google.golang.org/grpc v1.83.1 google.golang.org/protobuf v1.36.12 - k8s.io/api v0.36.2 - k8s.io/apimachinery v0.36.4 - k8s.io/client-go v0.36.2 + k8s.io/api v0.37.0 + k8s.io/apimachinery v0.37.0 + k8s.io/client-go v0.37.0 k8s.io/klog/v2 v2.140.0 k8s.io/utils v0.0.0-20260707023825-cf1189d6abe3 sigs.k8s.io/yaml v1.6.0 @@ -203,23 +203,24 @@ require ( github.com/go-ole/go-ole v1.3.0 // indirect github.com/go-openapi/analysis v0.25.0 // indirect github.com/go-openapi/errors v0.22.7 // indirect - github.com/go-openapi/jsonpointer v0.24.0 // indirect - github.com/go-openapi/jsonreference v0.21.6 // indirect + github.com/go-openapi/jsonpointer v1.0.0 // indirect + github.com/go-openapi/jsonreference v1.0.0 // indirect github.com/go-openapi/loads v0.23.3 // indirect github.com/go-openapi/spec v0.22.4 // indirect github.com/go-openapi/strfmt v0.26.2 // indirect - github.com/go-openapi/swag v0.27.0 // indirect - github.com/go-openapi/swag/cmdutils v0.27.0 // indirect - github.com/go-openapi/swag/conv v0.27.0 // indirect - github.com/go-openapi/swag/fileutils v0.27.0 // indirect + github.com/go-openapi/swag v0.27.1 // indirect + github.com/go-openapi/swag/cmdutils v0.27.1 // indirect + github.com/go-openapi/swag/conv v0.27.1 // indirect + github.com/go-openapi/swag/fileutils v0.27.1 // indirect github.com/go-openapi/swag/jsonname v0.26.0 // indirect - github.com/go-openapi/swag/jsonutils v0.27.0 // indirect - github.com/go-openapi/swag/loading v0.27.0 // indirect - github.com/go-openapi/swag/mangling v0.27.0 // indirect - github.com/go-openapi/swag/netutils v0.27.0 // indirect - github.com/go-openapi/swag/stringutils v0.27.0 // indirect - github.com/go-openapi/swag/typeutils v0.27.0 // indirect - github.com/go-openapi/swag/yamlutils v0.27.0 // indirect + github.com/go-openapi/swag/jsonutils v0.27.1 // indirect + github.com/go-openapi/swag/loading v0.27.1 // indirect + github.com/go-openapi/swag/mangling v0.27.1 // indirect + github.com/go-openapi/swag/netutils v0.27.1 // indirect + github.com/go-openapi/swag/pools v0.27.1 // indirect + github.com/go-openapi/swag/stringutils v0.27.1 // indirect + github.com/go-openapi/swag/typeutils v0.27.1 // indirect + github.com/go-openapi/swag/yamlutils v0.27.1 // indirect github.com/go-openapi/validate v0.25.2 // indirect github.com/go-sql-driver/mysql v1.9.3 // indirect github.com/go-viper/mapstructure/v2 v2.5.0 // indirect @@ -235,7 +236,7 @@ require ( github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v1.0.0 // indirect github.com/google/btree v1.1.3 // indirect - github.com/google/cel-go v0.28.0 // indirect + github.com/google/cel-go v0.29.2 // indirect github.com/google/flatbuffers v25.12.19+incompatible // indirect github.com/google/gnostic-models v0.7.1 // indirect github.com/google/s2a-go v0.1.9 // indirect @@ -284,7 +285,7 @@ require ( github.com/julienschmidt/httprouter v1.3.0 // indirect github.com/kamstrup/intmap v0.5.2 // indirect github.com/kelseyhightower/envconfig v1.4.0 // indirect - github.com/klauspost/compress v1.18.6 // indirect + github.com/klauspost/compress v1.19.0 // indirect github.com/klauspost/cpuid/v2 v2.3.0 // indirect github.com/knadh/koanf/maps v0.1.2 // indirect github.com/knadh/koanf/parsers/yaml v1.1.0 // indirect @@ -406,9 +407,9 @@ require ( github.com/zitadel/logging v0.6.1 // indirect github.com/zitadel/schema v1.3.0 // indirect go.etcd.io/bbolt v1.5.0 // indirect - go.etcd.io/etcd/api/v3 v3.6.8 // indirect - go.etcd.io/etcd/client/pkg/v3 v3.6.8 // indirect - go.etcd.io/etcd/client/v3 v3.6.8 // indirect + go.etcd.io/etcd/api/v3 v3.7.0 // indirect + go.etcd.io/etcd/client/pkg/v3 v3.7.0 // indirect + go.etcd.io/etcd/client/v3 v3.7.0 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/collector/component v1.59.0 // indirect @@ -466,13 +467,13 @@ require ( gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect honnef.co/go/tools v0.7.0 // indirect - k8s.io/apiextensions-apiserver v0.36.2 // indirect - k8s.io/kube-openapi v0.0.0-20260624041617-8f3fa4921821 // indirect + k8s.io/apiextensions-apiserver v0.37.0 // indirect + k8s.io/kube-openapi v0.0.0-20260721132016-d427ff9ee9ad // indirect mvdan.cc/gofumpt v0.9.2 // indirect - sigs.k8s.io/controller-runtime v0.24.1 // indirect + sigs.k8s.io/controller-runtime v0.25.1 // indirect sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/randfill v1.0.0 // indirect - sigs.k8s.io/structured-merge-diff/v6 v6.4.0 // indirect + sigs.k8s.io/structured-merge-diff/v6 v6.4.2 // indirect ) replace github.com/GoogleCloudPlatform/k8s-config-connector/mockgcp => ./mockgcp @@ -482,3 +483,10 @@ replace github.com/hashicorp/terraform-provider-google-beta => ./third_party/git replace github.com/nais/api/pkg/apiclient => ./pkg/apiclient replace github.com/hashicorp/memberlist => github.com/grafana/memberlist v0.3.1-0.20251126142931-6f9f62ab6f86 + +// Loki's dskit dependency is not compatible with the etcd 3.7 API pulled in by pgrator's Kubernetes dependencies. +replace go.etcd.io/etcd/api/v3 => go.etcd.io/etcd/api/v3 v3.6.14 + +replace go.etcd.io/etcd/client/pkg/v3 => go.etcd.io/etcd/client/pkg/v3 v3.6.14 + +replace go.etcd.io/etcd/client/v3 => go.etcd.io/etcd/client/v3 v3.6.14 diff --git a/go.sum b/go.sum index 7016f6add..53efc3aa7 100644 --- a/go.sum +++ b/go.sum @@ -385,42 +385,44 @@ github.com/go-openapi/analysis v0.25.0 h1:EnjAq1yO8wEO9HbPmY8vLPEIkdZuuFhCAKBPvC github.com/go-openapi/analysis v0.25.0/go.mod h1:5WFTRE43WLkPG9r9OtlMfqkkvUTYLVVCIxLlEpyF8kE= github.com/go-openapi/errors v0.22.7 h1:JLFBGC0Apwdzw3484MmBqspjPbwa2SHvpDm0u5aGhUA= github.com/go-openapi/errors v0.22.7/go.mod h1://QW6SD9OsWtH6gHllUCddOXDL0tk0ZGNYHwsw4sW3w= -github.com/go-openapi/jsonpointer v0.24.0 h1:AA6mCjHYHmZ+1RU2Js089EaOK/iwXXNwQsTgnsTha2M= -github.com/go-openapi/jsonpointer v0.24.0/go.mod h1:Z3rw7dWu1p9IgitXCFamSlA5lmDiklEB6vkaxcNZW5Y= -github.com/go-openapi/jsonreference v0.21.6 h1:NZ5nGfnaM1n4I43Xjm1e5/M2GjOwQwndQz22uhxwD+Y= -github.com/go-openapi/jsonreference v0.21.6/go.mod h1:xzbgtQ3ZbWxvET3AxdzCJlJt6vkovbf+IfSPJjD0tUY= +github.com/go-openapi/jsonpointer v1.0.0 h1:kR9tHqY0CtZaOPVFm622dPVNhrvYpwr4uCxgL3h1H8s= +github.com/go-openapi/jsonpointer v1.0.0/go.mod h1:Z3rw7dWu1p9IgitXCFamSlA5lmDiklEB6vkaxcNZW5Y= +github.com/go-openapi/jsonreference v1.0.0 h1:jlmTr6torcd1YgDQvSfNmRtKzYDO4FGBkrAdlAVWnpY= +github.com/go-openapi/jsonreference v1.0.0/go.mod h1:jtwdyGbJk0Xhe5Y+rwtglQP6Sb1WZST4rT32LWB+sv0= github.com/go-openapi/loads v0.23.3 h1:g5Xap1JfwKkUnZdn+S0L3SzBDpcTIYzZ5Qaag0YDkKQ= github.com/go-openapi/loads v0.23.3/go.mod h1:NOH07zLajXo8y55hom0omlHWDVVvCwBM/S+csCK8LqA= github.com/go-openapi/spec v0.22.4 h1:4pxGjipMKu0FzFiu/DPwN3CTBRlVM2yLf/YTWorYfDQ= github.com/go-openapi/spec v0.22.4/go.mod h1:WQ6Ai0VPWMZgMT4XySjlRIE6GP1bGQOtEThn3gcWLtQ= github.com/go-openapi/strfmt v0.26.2 h1:ysjheCh4i1rmFEo2LanhELDNucNzfWTZhUDKgWWPaFM= github.com/go-openapi/strfmt v0.26.2/go.mod h1:fXh1e449cyUn2NYuz+wb3wARBUdMl7qPEZwX00nqivY= -github.com/go-openapi/swag v0.27.0 h1:8ecSuZlh4NXc3GsmAOqECIYqDTApCWaMe3gO4gjJNEE= -github.com/go-openapi/swag v0.27.0/go.mod h1:Kkgz9Ht0+ul9/aVdFmc9xSyPzUwf/aFF5KiFPBXfSY0= -github.com/go-openapi/swag/cmdutils v0.27.0 h1:aIKiqhB29AaP+7xm8/CPg3uOpeHx2SUp6TvMpu/a31Y= -github.com/go-openapi/swag/cmdutils v0.27.0/go.mod h1:Sm1MVFMkF6guJJ+pQqHnQA3N0j9qALV3NxzDSv6bETM= -github.com/go-openapi/swag/conv v0.27.0 h1:EKOH4feXrvdo8DbSsXSAqRT8fz1epEnS5O2IfXUOzE8= -github.com/go-openapi/swag/conv v0.27.0/go.mod h1:pfiv0uKQTbaGApk8Zs/lZV3uSjmSpa2FO1y183YngN8= -github.com/go-openapi/swag/fileutils v0.27.0 h1:ib5jMUqGq5tY1EyO4inlrabsaeDAleFU+XD1FXQcgp8= -github.com/go-openapi/swag/fileutils v0.27.0/go.mod h1:VvJFZLTZS0AI854gEQz5tk7dBESdLjiNUMSZ/th2ry8= +github.com/go-openapi/swag v0.27.1 h1:VotvOLWW8q/EAxB0YdsBBGC8XYyeL1YwBj2ungAGPNg= +github.com/go-openapi/swag v0.27.1/go.mod h1:GTkJPwHfhJp6MWr4/rCh64HVI3Ofu+tcsbfjfHmTxpE= +github.com/go-openapi/swag/cmdutils v0.27.1 h1:I7sYqaWVl5mq0NEmNQkAmFDyNin9ufvMX/p2zwtQaOE= +github.com/go-openapi/swag/cmdutils v0.27.1/go.mod h1:Sm1MVFMkF6guJJ+pQqHnQA3N0j9qALV3NxzDSv6bETM= +github.com/go-openapi/swag/conv v0.27.1 h1:8wi9ZG+olmY1wXphl93EWniPtbSPkXM/feH7FgjsvrU= +github.com/go-openapi/swag/conv v0.27.1/go.mod h1:QbqMivkpKhC3g1B1GGGOJ6ANewI3S62dbzYu3Duowqs= +github.com/go-openapi/swag/fileutils v0.27.1 h1:QQqBSoi5mW4XpU85nS0mLcA+zAE6vLzrb0QkmLKf9oM= +github.com/go-openapi/swag/fileutils v0.27.1/go.mod h1:VvJFZLTZS0AI854gEQz5tk7dBESdLjiNUMSZ/th2ry8= github.com/go-openapi/swag/jsonname v0.26.0 h1:gV1NFX9M8avo0YSpmWogqfQISigCmpaiNci8cGECU5w= github.com/go-openapi/swag/jsonname v0.26.0/go.mod h1:urBBR8bZNoDYGr653ynhIx+gTeIz0ARZxHkAPktJK2M= -github.com/go-openapi/swag/jsonutils v0.27.0 h1:VYtd9jEQYeU4j8q5vdn5KWotF4vKywhGdMBrALtAsfE= -github.com/go-openapi/swag/jsonutils v0.27.0/go.mod h1:U7pb8AGuwhok3RDicHeHwSG4L3PXSq6PAL98Aon632g= -github.com/go-openapi/swag/jsonutils/fixtures_test v0.27.0 h1:+d7C7Ur/SsGg/UZ9G0JEovnfRqtMNZCJQGKc2h/ojoE= -github.com/go-openapi/swag/jsonutils/fixtures_test v0.27.0/go.mod h1:mofwUWx70wvskwESqRJ//k/9kURmCgyJl5m5Ppoh5kY= -github.com/go-openapi/swag/loading v0.27.0 h1:s8DA9aPEdFH6OluHUYUn3DnIuoTdyWs9RwffXBUfyeI= -github.com/go-openapi/swag/loading v0.27.0/go.mod h1:VOz+Jg6UGGywcmRvYsI4fvtp+bd7NfioseGEPleYdA4= -github.com/go-openapi/swag/mangling v0.27.0 h1:rpPJuqQHa6z2pDiP3iIpXOyNXlSs9cQCxnJSAxzdfOc= -github.com/go-openapi/swag/mangling v0.27.0/go.mod h1:jtBE2+V+3pILxOR7Vgce+Cwp6A2PgZbvVqfNntbVs0w= -github.com/go-openapi/swag/netutils v0.27.0 h1:lEUG+hHvPvLggB3A8snFk0IRKNf9uC0YKc+7WYqvAF8= -github.com/go-openapi/swag/netutils v0.27.0/go.mod h1:J+WYyFMLtvtCGqa6jLv+YNUmIKI3ZRQRrvfNDMoQoEQ= -github.com/go-openapi/swag/stringutils v0.27.0 h1:Of7w/HljWsNZvuxsUAnw3n+hCOyI6HLJOxW2kQRAxio= -github.com/go-openapi/swag/stringutils v0.27.0/go.mod h1:lzRN95CxXmA03XcDWHLOb6nOMcxCqR5rGY0lOgsfRoM= -github.com/go-openapi/swag/typeutils v0.27.0 h1:aCf4MSGo8NLwZP8Q6t32DWLJSvl/WwNqgmEG+xJ6v2o= -github.com/go-openapi/swag/typeutils v0.27.0/go.mod h1:Srm0xFNRZ1Y+vCxJclo5qzx8aj+1pAKda/YfFPrG0dQ= -github.com/go-openapi/swag/yamlutils v0.27.0 h1:bQ6eAMil5X9tdcf7dMn4t15alzG6jddnrKPuKa/zxKM= -github.com/go-openapi/swag/yamlutils v0.27.0/go.mod h1:yRfIo7qqVkmJRQjX8exjA3AfcI8rH1KDNPsTparoCv4= +github.com/go-openapi/swag/jsonutils v0.27.1 h1:SVgK3i4USzCU5mibOOS/l4ea2h9UQXy7J7RNLTjuXjU= +github.com/go-openapi/swag/jsonutils v0.27.1/go.mod h1:tdlEpZqdcQ17uj6J4YdK9vd8It5qWMwjWXOs0tjpRlk= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.27.1 h1:mJu3COL9WEaZVp/Kf2PRMi7tPszPEJfSr/OO75ynCs8= +github.com/go-openapi/swag/jsonutils/fixtures_test v0.27.1/go.mod h1:mofwUWx70wvskwESqRJ//k/9kURmCgyJl5m5Ppoh5kY= +github.com/go-openapi/swag/loading v0.27.1 h1:/DxUgDXKbBX4bcn7r9uEXfJyzN5XpiJmZplzQTjrRCY= +github.com/go-openapi/swag/loading v0.27.1/go.mod h1:jvGh3iA2+zyUUycB5fgJWzeHnhrpvGnJJM0RVE9ZShE= +github.com/go-openapi/swag/mangling v0.27.1 h1:yC9D0HyUE8gbP+BfmGx9+AA89ikwZTMjESK3OnnoaqA= +github.com/go-openapi/swag/mangling v0.27.1/go.mod h1:jtBE2+V+3pILxOR7Vgce+Cwp6A2PgZbvVqfNntbVs0w= +github.com/go-openapi/swag/netutils v0.27.1 h1:mICMFoS82F5TZ4Zy3cqmcQk+BFeCp3Uyq3Np7GI0/qU= +github.com/go-openapi/swag/netutils v0.27.1/go.mod h1:J+WYyFMLtvtCGqa6jLv+YNUmIKI3ZRQRrvfNDMoQoEQ= +github.com/go-openapi/swag/pools v0.27.1 h1:9LeadcMyb2GJCbXX5hVQDbZ2Lq9TL4dCs/nx1j5DO0E= +github.com/go-openapi/swag/pools v0.27.1/go.mod h1:kVQefhSK5RWuRe7BXsL8htgBPAMpN7HDGpGEknqugeE= +github.com/go-openapi/swag/stringutils v0.27.1 h1:ZXePZ0r2p1qSjo8tD3Un4vFj8+FqlCkczxDrJIhYUp8= +github.com/go-openapi/swag/stringutils v0.27.1/go.mod h1:lzRN95CxXmA03XcDWHLOb6nOMcxCqR5rGY0lOgsfRoM= +github.com/go-openapi/swag/typeutils v0.27.1 h1:KSTdFlfnse4r6dP9IrEnwMldjE+zs71UeEB3//PtVXc= +github.com/go-openapi/swag/typeutils v0.27.1/go.mod h1:Srm0xFNRZ1Y+vCxJclo5qzx8aj+1pAKda/YfFPrG0dQ= +github.com/go-openapi/swag/yamlutils v0.27.1 h1:ftxv6xvXb1E3zohUc+okZ9nSqNb9StQX/FXnKZ98sQA= +github.com/go-openapi/swag/yamlutils v0.27.1/go.mod h1:bnxFIB1qewGRiZHypXGZ3fNgf13/0HfRgnS/iZBDrOo= github.com/go-openapi/testify/enable/yaml/v2 v2.6.0 h1:gGHwAJ0R/5jU8BEGDbfRNR3hL68dAVi84WuOApp29B0= github.com/go-openapi/testify/enable/yaml/v2 v2.6.0/go.mod h1:tY+St1SGq4NFl0QIqdTY4aEdbChAHxhyB77XQi9iJCo= github.com/go-openapi/testify/v2 v2.6.0 h1:5PKH2HE7YJ/LuRPQGvSxBRlFXNQhSetBLlGAgUEu3ug= @@ -485,8 +487,8 @@ github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs= github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= -github.com/google/cel-go v0.28.0 h1:KjSWstCpz/MN5t4a8gnGJNIYUsJRpdi/r97xWDphIQc= -github.com/google/cel-go v0.28.0/go.mod h1:X0bD6iVNR8pkROSOoHVdgTkzmRcosof7WQqCD6wcMc8= +github.com/google/cel-go v0.29.2 h1:ZtDxkeiMmz0mxbKDYiNkE5Lk7V5edMRcaaDf2jX002k= +github.com/google/cel-go v0.29.2/go.mod h1:X0bD6iVNR8pkROSOoHVdgTkzmRcosof7WQqCD6wcMc8= github.com/google/flatbuffers v25.12.19+incompatible h1:haMV2JRRJCe1998HeW/p0X9UaMTK6SDo0ffLn2+DbLs= github.com/google/flatbuffers v25.12.19+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/gnostic-models v0.7.1 h1:SisTfuFKJSKM5CPZkffwi6coztzzeYUhc3v4yxLWH8c= @@ -672,8 +674,8 @@ github.com/keybase/go-keychain v0.0.1/go.mod h1:PdEILRW3i9D8JcdM+FmY6RwkHGnhHxXw github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= -github.com/klauspost/compress v1.18.6 h1:2jupLlAwFm95+YDR+NwD2MEfFO9d4z4Prjl1XXDjuao= -github.com/klauspost/compress v1.18.6/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= +github.com/klauspost/compress v1.19.0 h1:sXLILfc9jV2QYWkzFOPWStmcUVH2RHEB1JCdY2oVvCQ= +github.com/klauspost/compress v1.19.0/go.mod h1:cwPg85FWrGar70rWktvGQj8/hthj3wpl0PGDogxkrSQ= github.com/klauspost/cpuid/v2 v2.3.0 h1:S4CRMLnYUhGeDFDqkGriYKdfoFlDnMtqTiI/sFzhA9Y= github.com/klauspost/cpuid/v2 v2.3.0/go.mod h1:hqwkgyIinND0mEev00jJYCxPNVRVXFQeu1XKlok6oO0= github.com/knadh/koanf/maps v0.1.2 h1:RBfmAW5CnZT+PJ1CVc1QSJKf4Xu9kxfQgYVQSu8hpbo= @@ -805,8 +807,8 @@ github.com/nais/bifrost v0.0.0-20260106105449-911627ac2c61 h1:DMIjq7U47OJ8GlgOR3 github.com/nais/bifrost v0.0.0-20260106105449-911627ac2c61/go.mod h1:sAeomjrnGAI9VAErCaOHbTehVkf6hhKoJpHL8uzOqGg= github.com/nais/liberator v0.0.0-20260903194126-706ea87ddf9a h1:GAIHGbZVhT5Yzx/NrYWdLxlsn+IaqXetGm4zsnJW5hU= github.com/nais/liberator v0.0.0-20260903194126-706ea87ddf9a/go.mod h1:11Mi+k5w8IcdmgNwk6gORoBhHR9Ua4I9UtI8uljg4kc= -github.com/nais/pgrator/pkg/api v0.0.0-20260915202302-d699a2823ec5 h1:7VBS6QIP1BTG3i9OLW1J1ekbd+yh6XIGfmAlM8BSQFU= -github.com/nais/pgrator/pkg/api v0.0.0-20260915202302-d699a2823ec5/go.mod h1:kjcHI6Uh4++6CEsQf8JeGKE37XrY+ffhoaQv3jn0qAc= +github.com/nais/pgrator/pkg/api v0.0.0-20260929133826-b665367bc31f h1:Rg9Pu9l2owbY40k0XYMP4DgA77aWPxGX9S8JnqRbimo= +github.com/nais/pgrator/pkg/api v0.0.0-20260929133826-b665367bc31f/go.mod h1:jwS3ovEbOWcVTYyM2EicvkUSjtOrYA57t+jcTct2uzM= github.com/nais/tester v0.2.0 h1:lcTkDP52ddw9l5s3KC4snUP+GlUpZMUtJ3XR2vF4G0w= github.com/nais/tester v0.2.0/go.mod h1:Pp7CtcVk/NZI3z0MW7V4j8CPMG5lhKZeAV4IaJKcslo= github.com/nais/unleasherator v0.0.0-20251216221129-efebc54203fe h1:CdRVopOihru4tXVwKZjhg6C8SbPLCQYOhJKpjBZYhjg= @@ -905,8 +907,8 @@ github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5Fsn github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.1/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.23.2 h1:Je96obch5RDVy3FDMndoUsjAhG5Edi49h0RJWRi/o0o= -github.com/prometheus/client_golang v1.23.2/go.mod h1:Tb1a6LWHB3/SPIzCoaDXI4I8UHKeFTEQ1YCr+0Gyqmg= +github.com/prometheus/client_golang v1.24.0 h1:5XStIklKuAtJSNpdD3s8XJj/Yv78IQmE1kbNk87JrAI= +github.com/prometheus/client_golang v1.24.0/go.mod h1:QcsNdotprC2nS4BTM2ucbcqxd2CeXTEa9jW7zHO9iDE= github.com/prometheus/client_golang/exp v0.0.0-20260518105423-c9d5bc4c50a9 h1:e33IfrrwrJkylWwAGcQ2jMvbWVv13lv0suTXjGNeiqY= github.com/prometheus/client_golang/exp v0.0.0-20260518105423-c9d5bc4c50a9/go.mod h1:vW/EVguzbNw6xMRmozJQWbY60/+Zsg0TgVJOSXGx2iI= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= @@ -919,8 +921,8 @@ github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8 github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.69.0 h1:OA85nJQS/T/MaYh/Q2CcgDKSGWqNIgrBDvDH85CuiNk= -github.com/prometheus/common v0.69.0/go.mod h1:ZzL3f6u94qUxh9p+tJTrF+FvBS1XXbbRAZCQkytAL0Y= +github.com/prometheus/common v0.70.0 h1:bcpru3tWPVnxGnETLgOV5jbp/JRXgYEyv65CuBLAMMI= +github.com/prometheus/common v0.70.0/go.mod h1:S/SFasQmgGiYH6C81LKCtYa8QACgthGg5zxL2udV7SY= github.com/prometheus/common/sigv4 v0.1.0 h1:qoVebwtwwEhS85Czm2dSROY5fTo2PAPEVdDeppTwGX4= github.com/prometheus/common/sigv4 v0.1.0/go.mod h1:2Jkxxk9yYvCkE5G1sQT7GuEXm57JrvHu9k5YwTjsNtI= github.com/prometheus/exporter-toolkit v0.16.0 h1:xT/j7L2XKF+VJd6B4fpUw6xWabHrSmsUf6mYmFqyu0s= @@ -1119,12 +1121,12 @@ go.einride.tech/aip v0.79.0 h1:19zdPlZzlUvxOA8syAFw4LkdJdXepzyTl6gt9XEeqdU= go.einride.tech/aip v0.79.0/go.mod h1:E8+wdTApA70odnpFzJgsGogHozC2JCIhFJBKPr8bVig= go.etcd.io/bbolt v1.5.0 h1:S7GAl7Fxv12yohbwFfIbQCGDWbQbtDGPET4P/bD4lxU= go.etcd.io/bbolt v1.5.0/go.mod h1:mkltfYE5aUHQxUct9N9V+Kp7aSjFqjgrhcXIS70Lrdk= -go.etcd.io/etcd/api/v3 v3.6.8 h1:gqb1VN92TAI6G2FiBvWcqKtHiIjr4SU2GdXxTwyexbM= -go.etcd.io/etcd/api/v3 v3.6.8/go.mod h1:qyQj1HZPUV3B5cbAL8scG62+fyz5dSxxu0w8pn28N6Q= -go.etcd.io/etcd/client/pkg/v3 v3.6.8 h1:Qs/5C0LNFiqXxYf2GU8MVjYUEXJ6sZaYOz0zEqQgy50= -go.etcd.io/etcd/client/pkg/v3 v3.6.8/go.mod h1:GsiTRUZE2318PggZkAo6sWb6l8JLVrnckTNfbG8PWtw= -go.etcd.io/etcd/client/v3 v3.6.8 h1:B3G76t1UykqAOrbio7s/EPatixQDkQBevN8/mwiplrY= -go.etcd.io/etcd/client/v3 v3.6.8/go.mod h1:MVG4BpSIuumPi+ELF7wYtySETmoTWBHVcDoHdVupwt8= +go.etcd.io/etcd/api/v3 v3.6.14 h1:3EEwTzQPiCyhLtacyl2ZkC0pMJWowghi61nJ9JSpO1w= +go.etcd.io/etcd/api/v3 v3.6.14/go.mod h1:L4HXnXoJ5NqXSxiwB4RihT5gGJJVvHEEOpEZ37g1Uj4= +go.etcd.io/etcd/client/pkg/v3 v3.6.14 h1:kqZf/BCRDWk9u5cNwBn1mTA+4GIZAU0POFPHmWHvo/I= +go.etcd.io/etcd/client/pkg/v3 v3.6.14/go.mod h1:Po3WXW01VRS7/gSDf8xjiY2rJTLmAwq/YmKAEz6u1+E= +go.etcd.io/etcd/client/v3 v3.6.14 h1:3hjJbZCFJ3nFR47dZ/jjVu1/z6BRUHN1AA34pRbUW8Q= +go.etcd.io/etcd/client/v3 v3.6.14/go.mod h1:rQqHPE7ju1B1nmaqpGdhRgBHqOTiVaUeymlY1/ATcoM= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= @@ -1173,8 +1175,8 @@ go.opentelemetry.io/contrib/detectors/gcp v1.44.0 h1:NmLfL734pJhM0JKaYd2Y28+nY9d go.opentelemetry.io/contrib/detectors/gcp v1.44.0/go.mod h1:tNAsgd8avTGke1+MndXlU5Cru4PQ9Ai/cCNWQv/ZJ/s= go.opentelemetry.io/contrib/exporters/autoexport v0.64.0 h1:9pzPj3RFyKOxBAMkM2w84LpT+rdHam1XoFA+QhARiRw= go.opentelemetry.io/contrib/exporters/autoexport v0.64.0/go.mod h1:hlVZx1btWH0XTfXpuGX9dsquB50s+tc3fYFOO5elo2M= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.67.0 h1:yI1/OhfEPy7J9eoa6Sj051C7n5dvpj0QX8g4sRchg04= -go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.67.0/go.mod h1:NoUCKYWK+3ecatC4HjkRktREheMeEtrXoQxrqYFeHSc= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.68.0 h1:0Qx7VGBacMm9ZENQ7TnNObTYI4ShC+lHI16seduaxZo= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.68.0/go.mod h1:Sje3i3MjSPKTSPvVWCaL8ugBzJwik3u4smCjUeuupqg= go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.69.0 h1:MCcYL7J6Vt/X0kjqbMZkekCmwsurbQRbL69vkiye2lk= go.opentelemetry.io/contrib/instrumentation/net/http/httptrace/otelhttptrace v0.69.0/go.mod h1:3jnStNwSufK+f5ktjL4EPcwtig4rtd81NS70lqHuXl8= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.69.0 h1:8tvICD4vSTOOsNrsI4Ljf6C+6UKvpTEH5XY3JMoyPoo= @@ -1271,8 +1273,8 @@ golang.org/x/crypto v0.54.0 h1:YLIA59K4fiNzHzjnZt2tUJQjQtUWfWbeHBqKtk3eScw= golang.org/x/crypto v0.54.0/go.mod h1:KWL8ny2AZdGR2cWmzeHrp2azQPGogOv+HeQaVEXC2dk= golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa h1:Zt3DZoOFFYkKhDT3v7Lm9FDMEV06GpzjG2jrqW+QTE0= -golang.org/x/exp v0.0.0-20260218203240-3dfff04db8fa/go.mod h1:K79w1Vqn7PoiZn+TkNpx3BUWUQksGO3JcVX6qIjytmA= +golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f h1:W3F4c+6OLc6H2lb//N1q4WpJkhzJCK5J6kUi1NTVXfM= +golang.org/x/exp v0.0.0-20260410095643-746e56fc9e2f/go.mod h1:J1xhfL/vlindoeF/aINzNzt2Bket5bjo9sdOYzOsU80= golang.org/x/exp/typeparams v0.0.0-20251209150349-8475f28825e9 h1:DXiKAjbw2KpfWz1Bq2YqF/dBDPEZGJsl3IA2JuVzy8U= golang.org/x/exp/typeparams v0.0.0-20251209150349-8475f28825e9/go.mod h1:4Mzdyp/6jzw9auFDJ3OMF5qksa7UvPnzKqTVGcb04ms= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -1459,18 +1461,18 @@ honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.7.0 h1:w6WUp1VbkqPEgLz4rkBzH/CSU6HkoqNLp6GstyTx3lU= honnef.co/go/tools v0.7.0/go.mod h1:pm29oPxeP3P82ISxZDgIYeOaf9ta6Pi0EWvCFoLG2vc= -k8s.io/api v0.36.2 h1:TF6YDLIzKfccK7cq9YpTcGX8TJmEkHVRv78DM51fRYY= -k8s.io/api v0.36.2/go.mod h1:F4LbMO4brjZYh7yFkXWhynSvtB7YauxV4c+HHkNRGNg= -k8s.io/apiextensions-apiserver v0.36.2 h1:3O5gqOj/dt2XWWbpMe+TXWpE9yU6pjM/tXxtHHJT/K4= -k8s.io/apiextensions-apiserver v0.36.2/go.mod h1:cL1tBWe8XSaP1H30iWKGo7hf6iAUUUJPEU70dskmAnA= -k8s.io/apimachinery v0.36.4 h1:PT2UzkupGuAx/+xT5XjiMJ1WGpY3fn9/hdAvjweRet4= -k8s.io/apimachinery v0.36.4/go.mod h1:p2I2dipt7JHG+quVwQ1d02d28O4GdDi77RByQ13MTpk= -k8s.io/client-go v0.36.2 h1:bfgxmFKc9CgqsgX4xKLAAdmTQlWee7Ob/HlDOrJ5TBI= -k8s.io/client-go v0.36.2/go.mod h1:1vgO4OAlfPnoLcb+Rze2GF5rAr14w8qjrYMoyXJzQj0= +k8s.io/api v0.37.0 h1:Z//Vj9N7RA/yS2sDmxyeo7h+RR4zbUrd2vrd3Z0TbB4= +k8s.io/api v0.37.0/go.mod h1:LKXgcJWMc+f4OLbP5SFR8rulEg07zZhpi/zMULiBImk= +k8s.io/apiextensions-apiserver v0.37.0 h1:zRMQ3+/LIE5oZ0tVvXwYHC+dIkSP5cjNWju7AZU1LOI= +k8s.io/apiextensions-apiserver v0.37.0/go.mod h1:HU0PfSBwchHL5iDau6jjt9zU6ryWkDDlaVUiq91NK80= +k8s.io/apimachinery v0.37.0 h1:Np2AbDtf8x6RDHiD8T9LbKJ9gaegeVNa8yNm5FuGKm0= +k8s.io/apimachinery v0.37.0/go.mod h1:RN3nhprFSCxOi5Selxd7oMTXOe/c+ZbcE7Im+TS2zkE= +k8s.io/client-go v0.37.0 h1:nsN31fy8wBySuZ+QRnKmrjRSQLOG2rvoGN0tKd12zhQ= +k8s.io/client-go v0.37.0/go.mod h1:FcGqw+Ll/gNQiq+nPGY1Oyt9y7SgDh1d3MW3RFDEbn0= k8s.io/klog/v2 v2.140.0 h1:Tf+J3AH7xnUzZyVVXhTgGhEKnFqye14aadWv7bzXdzc= k8s.io/klog/v2 v2.140.0/go.mod h1:o+/RWfJ6PwpnFn7OyAG3QnO47BFsymfEfrz6XyYSSp0= -k8s.io/kube-openapi v0.0.0-20260624041617-8f3fa4921821 h1:m2wZhD5+vJZyCVkTvUHIfaiXc/mdt3Pxyx3vUnGsKzU= -k8s.io/kube-openapi v0.0.0-20260624041617-8f3fa4921821/go.mod h1:V/QaCUYDa+0QpcHhVVc5l99Uz56wEMEXBSj9oCDkNDY= +k8s.io/kube-openapi v0.0.0-20260721132016-d427ff9ee9ad h1:oXImqH8mQNk7PmvzKhmN3ddJoY6OnyM225MXwGHPm0A= +k8s.io/kube-openapi v0.0.0-20260721132016-d427ff9ee9ad/go.mod h1:0/mqHCVhlumdJ3BhCfnjSZQE037nAhNodh1/hK0T8/I= k8s.io/utils v0.0.0-20260707023825-cf1189d6abe3 h1:jVkFFVfXdXP74B/zbO3hM3hpSFD0xvhQ5U686DPurkE= k8s.io/utils v0.0.0-20260707023825-cf1189d6abe3/go.mod h1:M2s5JB1lIYP3jzZdorPLHXIPJzt9vv2muW5a6L9DtNM= modernc.org/libc v1.68.0 h1:PJ5ikFOV5pwpW+VqCK1hKJuEWsonkIJhhIXyuF/91pQ= @@ -1483,13 +1485,13 @@ modernc.org/sqlite v1.46.1 h1:eFJ2ShBLIEnUWlLy12raN0Z1plqmFX9Qe3rjQTKt6sU= modernc.org/sqlite v1.46.1/go.mod h1:CzbrU2lSB1DKUusvwGz7rqEKIq+NUd8GWuBBZDs9/nA= mvdan.cc/gofumpt v0.9.2 h1:zsEMWL8SVKGHNztrx6uZrXdp7AX8r421Vvp23sz7ik4= mvdan.cc/gofumpt v0.9.2/go.mod h1:iB7Hn+ai8lPvofHd9ZFGVg2GOr8sBUw1QUWjNbmIL/s= -sigs.k8s.io/controller-runtime v0.24.1 h1:miPEwrmirImAvgME1L9qebGHrOnGJoVmVdtOU9fRfo4= -sigs.k8s.io/controller-runtime v0.24.1/go.mod h1:vFkfY5fGt5xAC/sKb8IBFKgWPNKG9OUG29dR8Y2wImw= +sigs.k8s.io/controller-runtime v0.25.1 h1:BKgU9OeE8xv8EbbM8cY0NVzTQs35rokkdq1jh12fMb4= +sigs.k8s.io/controller-runtime v0.25.1/go.mod h1:4QqLdT6z/L6Olj8JJCtvztid4/fnIiYsfaTFScegctc= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= sigs.k8s.io/randfill v1.0.0/go.mod h1:XeLlZ/jmk4i1HRopwe7/aU3H5n1zNUcX6TM94b3QxOY= -sigs.k8s.io/structured-merge-diff/v6 v6.4.0 h1:qmp2e3ZfFi1/jJbDGpD4mt3wyp6PE1NfKHCYLqgNQJo= -sigs.k8s.io/structured-merge-diff/v6 v6.4.0/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= +sigs.k8s.io/structured-merge-diff/v6 v6.4.2 h1:qdOxHwrl2Kaag1aQEarlYcOA9vSyGCp3CIki3aW8c4Q= +sigs.k8s.io/structured-merge-diff/v6 v6.4.2/go.mod h1:M3W8sfWvn2HhQDIbGWj3S099YozAsymCo/wrT5ohRUE= sigs.k8s.io/yaml v1.6.0 h1:G8fkbMSAFqgEFgh4b1wmtzDnioxFCUgTZhlbj5P9QYs= sigs.k8s.io/yaml v1.6.0/go.mod h1:796bPqUfzR/0jLAl6XjHl3Ck7MiyVv8dbTdyT3/pMf4= diff --git a/internal/thirdparty/promclient/client.go b/internal/thirdparty/promclient/client.go index 49041aba8..1b3f348e9 100644 --- a/internal/thirdparty/promclient/client.go +++ b/internal/thirdparty/promclient/client.go @@ -126,7 +126,7 @@ func (c *RealClient) QueryRange(ctx context.Context, environment string, query s } func (c *RealClient) Rules(ctx context.Context, environment string, teamSlug slug.Slug) (promv1.RulesResult, error) { - res, err := c.mimirRules.Rules(ctx) + res, err := c.mimirRules.Rules(ctx, nil) if err != nil { return promv1.RulesResult{}, err } From 080ae360eea61589cf97f441a076d87e1b9d3cb9 Mon Sep 17 00:00:00 2001 From: Johnny Fredheim Horvi Date: Thu, 1 Oct 2026 09:12:51 +0200 Subject: [PATCH 19/19] test: update label selector Postgres expectations for local branch names --- integration_tests/label_selectors.lua | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/integration_tests/label_selectors.lua b/integration_tests/label_selectors.lua index f32c7b84b..b25c865c0 100644 --- a/integration_tests/label_selectors.lua +++ b/integration_tests/label_selectors.lua @@ -145,6 +145,9 @@ Test.gql("Check all Postgres instances (no filter)", function(t) } nodes { name + postgres { + name + } labels { key value @@ -165,20 +168,23 @@ Test.gql("Check all Postgres instances (no filter)", function(t) }, nodes = { { - name = "postgres-one", + name = "main", + postgres = { name = "postgres-one" }, labels = { { key = "priority", value = "high" }, { key = "tag", value = "target" }, }, }, { - name = "postgres-three", + name = "main", + postgres = { name = "postgres-three" }, labels = { { key = "tag", value = "other" }, }, }, { - name = "postgres-two", + name = "main", + postgres = { name = "postgres-two" }, labels = { { key = "tag", value = "target" }, }, @@ -201,6 +207,9 @@ Test.gql("Postgres filter by tag=target", function(t) } nodes { name + postgres { + name + } } } } @@ -215,8 +224,8 @@ Test.gql("Postgres filter by tag=target", function(t) totalCount = 2, }, nodes = { - { name = "postgres-one" }, - { name = "postgres-two" }, + { name = "main", postgres = { name = "postgres-one" } }, + { name = "main", postgres = { name = "postgres-two" } }, }, }, }, @@ -240,6 +249,9 @@ Test.gql("Postgres filter by tag=target and priority=high", function(t) } nodes { name + postgres { + name + } } } } @@ -254,7 +266,7 @@ Test.gql("Postgres filter by tag=target and priority=high", function(t) totalCount = 1, }, nodes = { - { name = "postgres-one" }, + { name = "main", postgres = { name = "postgres-one" } }, }, }, },