From 2fa4c1a0488171913ce5529c78ac3aedbae8611b Mon Sep 17 00:00:00 2001 From: Teodor Yanev Date: Thu, 16 Nov 2023 12:26:31 +0200 Subject: [PATCH 01/10] add-postgresql-messaging-pubsub-watermill --- cmd/server/app/serve.go | 2 +- config/config.yaml.example | 2 +- go.mod | 1 + go.sum | 2 ++ internal/controlplane/handlers_user_test.go | 4 +-- internal/controlplane/server_test.go | 2 +- internal/events/eventer.go | 39 +++++++++++++++++++-- internal/events/eventer_test.go | 2 +- 8 files changed, 45 insertions(+), 9 deletions(-) diff --git a/cmd/server/app/serve.go b/cmd/server/app/serve.go index 72a57b98df..1216661680 100644 --- a/cmd/server/app/serve.go +++ b/cmd/server/app/serve.go @@ -71,7 +71,7 @@ var serveCmd = &cobra.Command{ errg, ctx := errgroup.WithContext(ctx) - evt, err := events.Setup(ctx, &cfg.Events) + evt, err := events.Setup(ctx, &cfg.Events, dbConn) if err != nil { log.Printf("Failed to set up eventer: %v", err) return err diff --git a/config/config.yaml.example b/config/config.yaml.example index 0aebdb0f9f..ccf1a5d066 100644 --- a/config/config.yaml.example +++ b/config/config.yaml.example @@ -100,6 +100,6 @@ github: events: ["*"] events: - driver: go-channel + driver: postgresql router_close_timeout: 10 go-channel: {} diff --git a/go.mod b/go.mod index 715742b994..7e3705c975 100644 --- a/go.mod +++ b/go.mod @@ -72,6 +72,7 @@ require ( ) require ( + github.com/ThreeDotsLabs/watermill-sql/v2 v2.0.0 // indirect github.com/atotto/clipboard v0.1.4 // indirect github.com/aws/aws-sdk-go-v2/service/ecr v1.20.2 // indirect github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.18.2 // indirect diff --git a/go.sum b/go.sum index 9868101bd2..c17c7358e4 100644 --- a/go.sum +++ b/go.sum @@ -112,6 +112,8 @@ github.com/ThalesIgnite/crypto11 v1.2.5/go.mod h1:ILDKtnCKiQ7zRoNxcp36Y1ZR8LBPmR github.com/ThreeDotsLabs/watermill v1.1.1/go.mod h1:Qd1xNFxolCAHCzcMrm6RnjW0manbvN+DJVWc1MWRFlI= github.com/ThreeDotsLabs/watermill v1.3.5 h1:50JEPEhMGZQMh08ct0tfO1PsgMOAOhV3zxK2WofkbXg= github.com/ThreeDotsLabs/watermill v1.3.5/go.mod h1:O/u/Ptyrk5MPTxSeWM5vzTtZcZfxXfO9PK9eXTYiFZY= +github.com/ThreeDotsLabs/watermill-sql/v2 v2.0.0 h1:wswlLYY0Jc0tloj3lty4Y+VTEA8AM1vYfrIDwWtqyJk= +github.com/ThreeDotsLabs/watermill-sql/v2 v2.0.0/go.mod h1:83l/4sKaLHwoHJlrAsDLaXcHN+QOHHntAAyabNmiuO4= github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ= github.com/acomagu/bufpipe v1.0.4/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4= github.com/agnivade/levenshtein v1.1.1 h1:QY8M92nrzkmr798gCo3kmMyqXFzdQVpxLlGPRBij0P8= diff --git a/internal/controlplane/handlers_user_test.go b/internal/controlplane/handlers_user_test.go index 52afbda5bd..6ff3d05f05 100644 --- a/internal/controlplane/handlers_user_test.go +++ b/internal/controlplane/handlers_user_test.go @@ -261,7 +261,7 @@ func TestCreateUser_gRPC(t *testing.T) { evt, err := events.Setup(context.Background(), &config.EventConfig{ Driver: "go-channel", GoChannel: config.GoChannelEventConfig{}, - }) + }, nil) require.NoError(t, err, "failed to setup eventer") server, err := NewServer(mockStore, evt, NewMetrics(), &config.Config{ Salt: config.DefaultConfigForTest().Salt, @@ -468,7 +468,7 @@ func TestDeleteUser_gRPC(t *testing.T) { evt, err := events.Setup(context.Background(), &config.EventConfig{ Driver: "go-channel", GoChannel: config.GoChannelEventConfig{}, - }) + }, nil) require.NoError(t, err, "failed to setup eventer") server, err := NewServer(mockStore, evt, NewMetrics(), &config.Config{ Salt: config.DefaultConfigForTest().Salt, diff --git a/internal/controlplane/server_test.go b/internal/controlplane/server_test.go index 440af1e2c9..72eda3278a 100644 --- a/internal/controlplane/server_test.go +++ b/internal/controlplane/server_test.go @@ -73,7 +73,7 @@ func newDefaultServer(t *testing.T, mockStore *mockdb.MockStore) *Server { evt, err := events.Setup(context.Background(), &config.EventConfig{ Driver: "go-channel", GoChannel: config.GoChannelEventConfig{}, - }) + }, nil) require.NoError(t, err, "failed to setup eventer") var c *config.Config diff --git a/internal/events/eventer.go b/internal/events/eventer.go index 009d5b8015..4738f68460 100644 --- a/internal/events/eventer.go +++ b/internal/events/eventer.go @@ -19,6 +19,7 @@ package events import ( "context" + "database/sql" "errors" "fmt" "reflect" @@ -26,6 +27,7 @@ import ( "time" "github.com/ThreeDotsLabs/watermill" + watermillsql "github.com/ThreeDotsLabs/watermill-sql/v2/pkg/sql" "github.com/ThreeDotsLabs/watermill/components/metrics" "github.com/ThreeDotsLabs/watermill/message" "github.com/ThreeDotsLabs/watermill/message/router/middleware" @@ -98,7 +100,7 @@ var _ message.Publisher = (*Eventer)(nil) // Setup creates an Eventer object which isolates the watermill setup code // TODO: pass in logger -func Setup(ctx context.Context, cfg *config.EventConfig) (*Eventer, error) { +func Setup(ctx context.Context, cfg *config.EventConfig, db *sql.DB) (*Eventer, error) { if cfg == nil { return nil, errors.New("event config is nil") } @@ -137,7 +139,7 @@ func Setup(ctx context.Context, cfg *config.EventConfig) (*Eventer, error) { middleware.Recoverer, ) - pub, sub, err := instantiateDriver(cfg.Driver, cfg) + pub, sub, err := instantiateDriver(cfg.Driver, cfg, db) if err != nil { return nil, fmt.Errorf("failed instantiating driver: %w", err) } @@ -159,10 +161,12 @@ func Setup(ctx context.Context, cfg *config.EventConfig) (*Eventer, error) { }, nil } -func instantiateDriver(driver string, cfg *config.EventConfig) (message.Publisher, message.Subscriber, error) { +func instantiateDriver(driver string, cfg *config.EventConfig, db *sql.DB) (message.Publisher, message.Subscriber, error) { switch driver { case "go-channel": return buildGoChannelDriver(cfg) + case "postgresql": + return buildPostgreSQLDriver(db) default: return nil, nil, fmt.Errorf("unknown driver %s", driver) } @@ -177,6 +181,35 @@ func buildGoChannelDriver(cfg *config.EventConfig) (message.Publisher, message.S return pubsub, pubsub, nil } +func buildPostgreSQLDriver(db *sql.DB) (message.Publisher, message.Subscriber, error) { + publisher, err := watermillsql.NewPublisher( + db, + watermillsql.PublisherConfig{ + SchemaAdapter: watermillsql.DefaultPostgreSQLSchema{}, + AutoInitializeSchema: true, + }, + watermill.NewStdLogger(false, false), + ) + if err != nil { + return nil, nil, fmt.Errorf("failed to create SQL publisher: %w", err) + } + + subscriber, err := watermillsql.NewSubscriber( + db, + watermillsql.SubscriberConfig{ + SchemaAdapter: watermillsql.DefaultPostgreSQLSchema{}, + OffsetsAdapter: watermillsql.DefaultPostgreSQLOffsetsAdapter{}, + InitializeSchema: true, + }, + watermill.NewStdLogger(false, false), + ) + if err != nil { + return nil, nil, fmt.Errorf("failed to create SQL subscriber: %w", err) + } + + return publisher, subscriber, nil +} + // Close closes the router func (e *Eventer) Close() error { //nolint:gosec // It's fine if there's an error as long as we close the router diff --git a/internal/events/eventer_test.go b/internal/events/eventer_test.go index 8a76b8177c..17bc735938 100644 --- a/internal/events/eventer_test.go +++ b/internal/events/eventer_test.go @@ -126,7 +126,7 @@ func TestEventer(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - eventer, err := events.Setup(ctx, driverConfig()) + eventer, err := events.Setup(ctx, driverConfig(), nil) if err != nil { t.Errorf("Setup() error = %v", err) return From ec775c04175a68f72268323572307c21ad2e7a08 Mon Sep 17 00:00:00 2001 From: Teodor Yanev Date: Thu, 16 Nov 2023 14:15:22 +0200 Subject: [PATCH 02/10] fix helm tests --- deployment/helm_tests/basic.yaml-out | 866 ++++++++++++++++++++++++- deployment/helm_tests/sidecar.yaml-out | 866 ++++++++++++++++++++++++- 2 files changed, 1728 insertions(+), 4 deletions(-) diff --git a/deployment/helm_tests/basic.yaml-out b/deployment/helm_tests/basic.yaml-out index 2e84562374..342ba23276 100644 --- a/deployment/helm_tests/basic.yaml-out +++ b/deployment/helm_tests/basic.yaml-out @@ -1,4 +1,199 @@ --- +# Source: minder/templates/combined.yml +# Copyright 2023 Stacklok, Inc +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: v1 +kind: ServiceAccount +metadata: + name: mediator + labels: + # This includes a newline, so ko sees this as valid yaml + # + app.kubernetes.io/instance: minder + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: minder + app.kubernetes.io/version: "2023-07-31" + helm.sh/chart: minder-0.1.0 + annotations: + eks.amazonaws.com/role-arn: "arn:aws:iam::123456789012:role/" +imagePullSecrets: + - name: mediator-pull-secret +--- +# Source: minder/templates/combined.yml +# Copyright 2023 Stacklok, Inc +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: v1 +kind: ConfigMap +metadata: + name: mediator-config + labels: + # This includes a newline, so ko sees this as valid yaml + # + app.kubernetes.io/instance: minder + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: minder + app.kubernetes.io/version: "2023-07-31" + helm.sh/chart: minder-0.1.0 +data: + config.yaml: | + + # + # Copyright 2023 Stacklok, Inc. + # + # Licensed under the Apache License, Version 2.0 (the "License"); + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + + # HTTP, gRPC & metrics server configuration + http_server: + host: "127.0.0.1" + port: 8080 + grpc_server: + host: "127.0.0.1" + port: 8090 + metric_server: + host: "127.0.0.1" + port: 9090 + + logging: + level: "debug" + format: "json" + #logFile: "/var/log/minder.log" + + tracing: + enabled: false + #sample_ratio: 0.1 + + metrics: + enabled: true + + database: + dbhost: "localhost" + dbport: 5432 + dbuser: postgres + dbpass: postgres + dbname: minder + sslmode: disable + + identity: + cli: + issuer_url: http://localhost:8081 + realm: stacklok + client_id: minder-cli + server: + issuer_url: http://keycloak:8080 # Use http://localhost:8081 instead for running minder outside of docker-compose + realm: stacklok + client_id: minder-server + client_secret: secret + + # Crypto (these should be ultimately stored in a secure vault) + # The token key can be generated with: + # openssl rand -base64 32 > .ssh/token_key_passphrase + auth: + token_key: "./.ssh/token_key_passphrase" + + # Password Salting, these values are using argon2id + # https://en.wikipedia.org/wiki/Argon2 + # Argon has resistance against side-channel timing attacks and tradeoff attacks + # but it is computationally expensive. + # If this is a problematic, we could use bcrypt instead. + # https://en.wikipedia.org/wiki/Bcrypt + salt: + # The amount of memory used by the algorithm (in kibibytes). + memory: 65536 + # the amount of iterations + iterations: 50 + # degree of parallelism (number of threads) + parallelism: 4 + # the length of the salt to be used + salt_length: 16 + # the desired number of returned bytes + key_length: 32 + + # Webhook Configuration + # change example.com to an exposed IP / domain + # webhook_secret is set withing the webhook sent to github. Github then signs + # the payload sent to minder and minder verifies. + webhook-config: + external_webhook_url: "https://example.com/api/v1/webhook/github" + external_ping_url: "https://example.com/api/v1/health" + webhook_secret: "your-password" + + # OAuth2 Configuration (used during enrollment) + # These values are to be set within the GitHub OAuth2 App page + github: + client_id: "abcde....." + client_secret: "abcde....." + payload_secret: "your-password" + redirect_uri: "http://localhost:8080/api/v1/auth/callback/github" + # [*] for all events. It can also be a list such as [push,branch_protection_rule]. + # Please check complete list on https://docs.github.com/es/webhooks-and-events/webhooks/webhook-events-and-payloads + events: ["*"] + + events: + driver: postgresql + router_close_timeout: 10 + go-channel: {} + + overrides.yaml: | + + database: + dbuser: minder + dbname: minder + sslmode: disabled + + identity: + server: + issuer_url: http://keycloak-deployment.keycloak.svc:80 + realm: minder + client_id: minder-server + + github: + redirect_uri: "https://minder-test.example.com/api/v1/auth/callback/github" + + webhook-config: + external_webhook_url: "https://minder-test.example.com/api/v1/webhook/github" + external_ping_url: "https://minder-test.example.com/api/v1/health" + webhook_secret: "this-is-unused" + + events: + driver: go-channel + router_close_timeout: 30 + go-channel: + buffer_size: 200 +--- # Source: minder/templates/configmap.yaml # Copyright 2023 Stacklok, Inc # @@ -130,7 +325,7 @@ data: events: ["*"] events: - driver: go-channel + driver: postgresql router_close_timeout: 10 go-channel: {} @@ -161,6 +356,97 @@ data: go-channel: buffer_size: 200 --- +# Source: minder/templates/combined.yml +# Copyright 2023 Stacklok, Inc +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: v1 +kind: Service +metadata: + name: mediator-http + annotations: + alb.ingress.kubernetes.io/healthcheck-path: "/api/v1/health" + labels: + # This includes a newline, so ko sees this as valid yaml + # + app.kubernetes.io/instance: minder + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: minder + app.kubernetes.io/version: "2023-07-31" + helm.sh/chart: minder-0.1.0 +spec: + type: ClusterIP + ports: + - port: !!int "8080" + targetPort: http + protocol: TCP + name: http + selector: + app: mediator +--- +# Source: minder/templates/combined.yml +apiVersion: v1 +kind: Service +metadata: + name: mediator-grpc + annotations: + alb.ingress.kubernetes.io/backend-protocol-version: "GRPC" + alb.ingress.kubernetes.io/healthcheck-protocol: "HTTP" + alb.ingress.kubernetes.io/healthcheck-path: "/mediator.v1.HealthService/CheckHealth" + # For some reason, ALB defaults to 12 (unimplemented) as a success code + alb.ingress.kubernetes.io/success-codes: "0" + labels: + # This includes a newline, so ko sees this as valid yaml + # + app.kubernetes.io/instance: minder + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: minder + app.kubernetes.io/version: "2023-07-31" + helm.sh/chart: minder-0.1.0 +spec: + type: ClusterIP + ports: + - port: !!int "8090" + targetPort: grpc + protocol: TCP + name: grpc + selector: + app: mediator +--- +# Source: minder/templates/combined.yml +apiVersion: v1 +kind: Service +metadata: + name: mediator-metrics + labels: + # This includes a newline, so ko sees this as valid yaml + # + app.kubernetes.io/instance: minder + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: minder + app.kubernetes.io/version: "2023-07-31" + helm.sh/chart: minder-0.1.0 +spec: + type: ClusterIP + ports: + - port: !!int "9090" + targetPort: http + protocol: TCP + name: metrics + selector: + app: mediator +--- # Source: minder/templates/service.yaml # Copyright 2023 Stacklok, Inc # @@ -249,6 +535,137 @@ spec: selector: app: minder --- +# Source: minder/templates/combined.yml +# Copyright 2023 Stacklok, Inc +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: mediator + labels: + # This includes a newline, so ko sees this as valid yaml + # + app.kubernetes.io/instance: minder + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: minder + app.kubernetes.io/version: "2023-07-31" + helm.sh/chart: minder-0.1.0 +spec: + # We'll use autoscaling, sometimes clamped to one instance + selector: + matchLabels: + app: 'minder' + template: + metadata: + labels: + app: 'minder' + annotations: + # This includes a newline, so ko sees this as valid yaml + # + prometheus.io/scrape: "true" + prometheus.io/port: "9090" + prometheus.io/path: "/metrics" + spec: + serviceAccountName: mediator + containers: + - name: mediator + # restricted security context: + # https://kubernetes.io/docs/concepts/security/pod-security-standards/ + securityContext: + allowPrivilegeEscalation: false + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + capabilities: + drop: + - ALL + image: server:latest@sha256:23918f251e61748d850296d1a475ad81f2315a628cfd47864e52f10e6d3f4920 + args: + - "serve" + - "--db-host=postgres.postgres.svc" + - "--config=/config/config.yaml" + # We use two config files, one with all the defaults, and one with + # additional override values from helm. (This is a viper feature.) + - "--config=/config/overrides.yaml" + - "--grpc-host=0.0.0.0" + - "--http-host=0.0.0.0" + - "--metric-host=0.0.0.0" + - "--github-client-id-file=/secrets/app/client_id" + - "--github-client-secret-file=/secrets/app/client_secret" + env: + - name: "AUTH_ACCESS_TOKEN_PRIVATE_KEY" + value: "/secrets/auth/access_token_rsa" + - name: "AUTH_ACCESS_TOKEN_PUBLIC_KEY" + value: "/secrets/auth/access_token_rsa.pub" + - name: "AUTH_REFRESH_TOKEN_PRIVATE_KEY" + value: "/secrets/auth/refresh_token_rsa" + - name: "AUTH_REFRESH_TOKEN_PUBLIC_KEY" + value: "/secrets/auth/refresh_token_rsa.pub" + - name: "AUTH_TOKEN_KEY" + value: "/secrets/auth/token_key_passphrase" + # ko will always specify a digest, so we don't need to worry about + # CRI image caching + imagePullPolicy: IfNotPresent + ports: + - name: http + containerPort: !!int "8080" + protocol: TCP + - name: grpc + containerPort: !!int "8090" + protocol: TCP + - name: metric + containerPort: !!int "9090" + protocol: TCP + livenessProbe: + httpGet: + path: /api/v1/health + port: http + readinessProbe: + httpGet: + path: /api/v1/health + port: http + resources: + requests: + cpu: 1 + memory: 1Gi + limits: + cpu: 4 + memory: 1.5Gi + volumeMounts: + - name: config + mountPath: /config + - name: auth-secrets + mountPath: /secrets/auth + - name: app-secrets + mountPath: /secrets/app + volumes: + - name: config + configMap: + name: mediator-config + items: + - key: config.yaml + path: config.yaml + - key: overrides.yaml + path: overrides.yaml + - name: auth-secrets + secret: + secretName: mediator-auth-secrets + - name: app-secrets + secret: + secretName: mediator-github-secrets +--- # Source: minder/templates/deployment.yaml # Copyright 2023 Stacklok, Inc # @@ -383,6 +800,49 @@ spec: secret: secretName: minder-identity-secrets --- +# Source: minder/templates/combined.yml +# Copyright 2023 Stacklok, Inc +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: mediator + labels: + # This includes a newline, so ko sees this as valid yaml + # + app.kubernetes.io/instance: minder + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: minder + app.kubernetes.io/version: "2023-07-31" + helm.sh/chart: minder-0.1.0 +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: mediator + minReplicas: 1 + # Clamp to 1 at the moment + maxReplicas: 1 + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 60 +--- # Source: minder/templates/hpa.yaml # Copyright 2023 Stacklok, Inc # @@ -424,6 +884,153 @@ spec: type: Utilization averageUtilization: 60 --- +# Source: minder/templates/combined.yml +# Copyright 2023 Stacklok, Inc +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: mediator + labels: + # This includes a newline, so ko sees this as valid yaml + # + app.kubernetes.io/instance: minder + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: minder + app.kubernetes.io/version: "2023-07-31" + helm.sh/chart: minder-0.1.0 + annotations: + alb.ingress.kubernetes.io/group.name: mediator-vip + alb.ingress.kubernetes.io/group.order: '200' + alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80},{"HTTPS":443}]' + alb.ingress.kubernetes.io/scheme: internet-facing + alb.ingress.kubernetes.io/ssl-redirect: "443" + alb.ingress.kubernetes.io/target-type: ip + # ALB doesn't use support cert-manager, but maybe someone else will benefit from it? + cert-manager.io/cluster-issuer: letsencrypt +spec: + # Don't set ingressClassName for now, assume default + tls: + - hosts: + - "minder-test.example.com" + secretName: mediator-tls + rules: + - host: "minder-test.example.com" + http: + paths: + # We use Prefix matches on gRPC service names because Ingress API + # doesn't support matching on Content-Type: application/grpc + - path: /grpc.reflection.v1alpha.ServerReflection + pathType: Prefix + backend: + service: + name: mediator-grpc + port: + name: grpc + - path: /mediator.v1.OAuthService + pathType: Prefix + backend: + service: + name: mediator-grpc + port: + name: grpc + - path: /mediator.v1.AuthService + pathType: Prefix + backend: + service: + name: mediator-grpc + port: + name: grpc + - path: /mediator.v1.VulnerabilitiesService + pathType: Prefix + backend: + service: + name: mediator-grpc + port: + name: grpc + - path: /mediator.v1.SecretsService + pathType: Prefix + backend: + service: + name: mediator-grpc + port: + name: grpc + - path: /mediator.v1.RepositoryService + pathType: Prefix + backend: + service: + name: mediator-grpc + port: + name: grpc + - path: /mediator.v1.BranchProtectionService + pathType: Prefix + backend: + service: + name: mediator-grpc + port: + name: grpc + - path: /mediator.v1.OrganizationService + pathType: Prefix + backend: + service: + name: mediator-grpc + port: + name: grpc + - path: /mediator.v1.GroupService + pathType: Prefix + backend: + service: + name: mediator-grpc + port: + name: grpc + - path: /mediator.v1.RoleService + pathType: Prefix + backend: + service: + name: mediator-grpc + port: + name: grpc + - path: /mediator.v1.UserService + pathType: Prefix + backend: + service: + name: mediator-grpc + port: + name: grpc + - path: /mediator.v1.PolicyService + pathType: Prefix + backend: + service: + name: mediator-grpc + port: + name: grpc + - path: /mediator.v1.KeyService + pathType: Prefix + backend: + service: + name: mediator-grpc + port: + name: grpc + - path: / + pathType: Prefix + backend: + service: + name: mediator-http + port: + name: http +--- # Source: minder/templates/ingress.yaml # Copyright 2023 Stacklok, Inc # @@ -619,6 +1226,193 @@ spec: # See the License for the specific language governing permissions and # limitations under the License. --- +# Source: minder/templates/combined.yml +# Copyright 2023 Stacklok, Inc +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# We need a separate service account for the db-update job, because +# it runs as a helm pre-install hook, and the mediator service account +# won't have been installed at that point. +apiVersion: v1 +kind: ServiceAccount +metadata: + name: db-update + annotations: + eks.amazonaws.com/role-arn: "arn:aws:iam::123456789012:role/" + helm.sh/hook-delete-policy: before-hook-creation + helm.sh/hook: pre-install,pre-upgrade + labels: + # This includes a newline, so ko sees this as valid yaml + # + app.kubernetes.io/instance: minder + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: minder + app.kubernetes.io/version: "2023-07-31" + helm.sh/chart: minder-0.1.0 +imagePullSecrets: + - name: mediator-pull-secret +--- +# Source: minder/templates/combined.yml +apiVersion: v1 +kind: ConfigMap +metadata: + name: db-update-config + annotations: + helm.sh/hook-delete-policy: before-hook-creation + helm.sh/hook: pre-install,pre-upgrade + labels: + helm.sh/chart: 'minder-0.1.0' + app.kubernetes.io/name: mediator + app.kubernetes.io/instance: "minder" + app.kubernetes.io/version: "2023-07-31" + app.kubernetes.io/managed-by: "Helm" +data: + config.yaml: | + + # + # Copyright 2023 Stacklok, Inc. + # + # Licensed under the Apache License, Version 2.0 (the "License"); + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + + # HTTP, gRPC & metrics server configuration + http_server: + host: "127.0.0.1" + port: 8080 + grpc_server: + host: "127.0.0.1" + port: 8090 + metric_server: + host: "127.0.0.1" + port: 9090 + + logging: + level: "debug" + format: "json" + #logFile: "/var/log/minder.log" + + tracing: + enabled: false + #sample_ratio: 0.1 + + metrics: + enabled: true + + database: + dbhost: "localhost" + dbport: 5432 + dbuser: postgres + dbpass: postgres + dbname: minder + sslmode: disable + + identity: + cli: + issuer_url: http://localhost:8081 + realm: stacklok + client_id: minder-cli + server: + issuer_url: http://keycloak:8080 # Use http://localhost:8081 instead for running minder outside of docker-compose + realm: stacklok + client_id: minder-server + client_secret: secret + + # Crypto (these should be ultimately stored in a secure vault) + # The token key can be generated with: + # openssl rand -base64 32 > .ssh/token_key_passphrase + auth: + token_key: "./.ssh/token_key_passphrase" + + # Password Salting, these values are using argon2id + # https://en.wikipedia.org/wiki/Argon2 + # Argon has resistance against side-channel timing attacks and tradeoff attacks + # but it is computationally expensive. + # If this is a problematic, we could use bcrypt instead. + # https://en.wikipedia.org/wiki/Bcrypt + salt: + # The amount of memory used by the algorithm (in kibibytes). + memory: 65536 + # the amount of iterations + iterations: 50 + # degree of parallelism (number of threads) + parallelism: 4 + # the length of the salt to be used + salt_length: 16 + # the desired number of returned bytes + key_length: 32 + + # Webhook Configuration + # change example.com to an exposed IP / domain + # webhook_secret is set withing the webhook sent to github. Github then signs + # the payload sent to minder and minder verifies. + webhook-config: + external_webhook_url: "https://example.com/api/v1/webhook/github" + external_ping_url: "https://example.com/api/v1/health" + webhook_secret: "your-password" + + # OAuth2 Configuration (used during enrollment) + # These values are to be set within the GitHub OAuth2 App page + github: + client_id: "abcde....." + client_secret: "abcde....." + payload_secret: "your-password" + redirect_uri: "http://localhost:8080/api/v1/auth/callback/github" + # [*] for all events. It can also be a list such as [push,branch_protection_rule]. + # Please check complete list on https://docs.github.com/es/webhooks-and-events/webhooks/webhook-events-and-payloads + events: ["*"] + + events: + driver: postgresql + router_close_timeout: 10 + go-channel: {} + + overrides.yaml: | + + database: + dbuser: minder + dbname: minder + sslmode: disabled + + identity: + server: + issuer_url: http://keycloak-deployment.keycloak.svc:80 + realm: minder + client_id: minder-server + + github: + redirect_uri: "https://minder-test.example.com/api/v1/auth/callback/github" + + webhook-config: + external_webhook_url: "https://minder-test.example.com/api/v1/webhook/github" + external_ping_url: "https://minder-test.example.com/api/v1/health" + webhook_secret: "this-is-unused" + + events: + driver: go-channel + router_close_timeout: 30 + go-channel: + buffer_size: 200 +--- # Source: minder/templates/job.yaml apiVersion: v1 kind: ConfigMap @@ -738,7 +1532,7 @@ data: events: ["*"] events: - driver: go-channel + driver: postgresql router_close_timeout: 10 go-channel: {} @@ -749,6 +1543,74 @@ data: dbname: minder sslmode: disabled --- +# Source: minder/templates/combined.yml +apiVersion: batch/v1 +kind: Job +metadata: + name: db-update + annotations: + helm.sh/hook-delete-policy: hook-succeeded + helm.sh/hook: pre-install,pre-upgrade + helm.sh/hook-weight: "5" + labels: + helm.sh/chart: 'minder-0.1.0' + app.kubernetes.io/name: mediator + app.kubernetes.io/instance: "minder" + app.kubernetes.io/version: "2023-07-31" + app.kubernetes.io/managed-by: "Helm" +spec: + template: + metadata: + labels: + app: db-init + spec: + serviceAccountName: db-update + restartPolicy: Never + containers: + - name: mediator-dbinit + # restricted security context: + # https://kubernetes.io/docs/concepts/security/pod-security-standards/ + securityContext: + allowPrivilegeEscalation: false + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + capabilities: + drop: + - ALL + image: server:latest@sha256:23918f251e61748d850296d1a475ad81f2315a628cfd47864e52f10e6d3f4920 + args: + - "migrate" + - "up" + - "--yes" + - "--db-host=postgres.postgres.svc" + - "--config=/config/config.yaml" + # We use two config files, one with all the defaults, and one with + # additional override values from helm. (This is a viper feature.) + - "--config=/config/overrides.yaml" + # ko will always specify a digest, so we don't need to worry about + # CRI image caching + imagePullPolicy: IfNotPresent + resources: + requests: + cpu: 200m + memory: 200Mi + limits: + cpu: 1 + memory: 300Mi + volumeMounts: + - name: config + mountPath: /config + volumes: + - name: config + configMap: + name: db-update-config + items: + - key: config.yaml + path: config.yaml + - key: overrides.yaml + path: overrides.yaml +--- # Source: minder/templates/job.yaml apiVersion: batch/v1 kind: Job diff --git a/deployment/helm_tests/sidecar.yaml-out b/deployment/helm_tests/sidecar.yaml-out index bbd763dd64..3d48b97730 100644 --- a/deployment/helm_tests/sidecar.yaml-out +++ b/deployment/helm_tests/sidecar.yaml-out @@ -1,4 +1,199 @@ --- +# Source: minder/templates/combined.yml +# Copyright 2023 Stacklok, Inc +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: v1 +kind: ServiceAccount +metadata: + name: mediator + labels: + # This includes a newline, so ko sees this as valid yaml + # + app.kubernetes.io/instance: minder + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: minder + app.kubernetes.io/version: "2023-07-31" + helm.sh/chart: minder-0.1.0 + annotations: + eks.amazonaws.com/role-arn: "arn:aws:iam::123456789012:role/" +imagePullSecrets: + - name: mediator-pull-secret +--- +# Source: minder/templates/combined.yml +# Copyright 2023 Stacklok, Inc +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: v1 +kind: ConfigMap +metadata: + name: mediator-config + labels: + # This includes a newline, so ko sees this as valid yaml + # + app.kubernetes.io/instance: minder + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: minder + app.kubernetes.io/version: "2023-07-31" + helm.sh/chart: minder-0.1.0 +data: + config.yaml: | + + # + # Copyright 2023 Stacklok, Inc. + # + # Licensed under the Apache License, Version 2.0 (the "License"); + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + + # HTTP, gRPC & metrics server configuration + http_server: + host: "127.0.0.1" + port: 8080 + grpc_server: + host: "127.0.0.1" + port: 8090 + metric_server: + host: "127.0.0.1" + port: 9090 + + logging: + level: "debug" + format: "json" + #logFile: "/var/log/minder.log" + + tracing: + enabled: false + #sample_ratio: 0.1 + + metrics: + enabled: true + + database: + dbhost: "localhost" + dbport: 5432 + dbuser: postgres + dbpass: postgres + dbname: minder + sslmode: disable + + identity: + cli: + issuer_url: http://localhost:8081 + realm: stacklok + client_id: minder-cli + server: + issuer_url: http://keycloak:8080 # Use http://localhost:8081 instead for running minder outside of docker-compose + realm: stacklok + client_id: minder-server + client_secret: secret + + # Crypto (these should be ultimately stored in a secure vault) + # The token key can be generated with: + # openssl rand -base64 32 > .ssh/token_key_passphrase + auth: + token_key: "./.ssh/token_key_passphrase" + + # Password Salting, these values are using argon2id + # https://en.wikipedia.org/wiki/Argon2 + # Argon has resistance against side-channel timing attacks and tradeoff attacks + # but it is computationally expensive. + # If this is a problematic, we could use bcrypt instead. + # https://en.wikipedia.org/wiki/Bcrypt + salt: + # The amount of memory used by the algorithm (in kibibytes). + memory: 65536 + # the amount of iterations + iterations: 50 + # degree of parallelism (number of threads) + parallelism: 4 + # the length of the salt to be used + salt_length: 16 + # the desired number of returned bytes + key_length: 32 + + # Webhook Configuration + # change example.com to an exposed IP / domain + # webhook_secret is set withing the webhook sent to github. Github then signs + # the payload sent to minder and minder verifies. + webhook-config: + external_webhook_url: "https://example.com/api/v1/webhook/github" + external_ping_url: "https://example.com/api/v1/health" + webhook_secret: "your-password" + + # OAuth2 Configuration (used during enrollment) + # These values are to be set within the GitHub OAuth2 App page + github: + client_id: "abcde....." + client_secret: "abcde....." + payload_secret: "your-password" + redirect_uri: "http://localhost:8080/api/v1/auth/callback/github" + # [*] for all events. It can also be a list such as [push,branch_protection_rule]. + # Please check complete list on https://docs.github.com/es/webhooks-and-events/webhooks/webhook-events-and-payloads + events: ["*"] + + events: + driver: postgresql + router_close_timeout: 10 + go-channel: {} + + overrides.yaml: | + + database: + dbuser: minder + dbname: minder + sslmode: disabled + + identity: + server: + issuer_url: http://keycloak-deployment.keycloak.svc:80 + realm: minder + client_id: minder-server + + github: + redirect_uri: "https://minder-test.example.com/api/v1/auth/callback/github" + + webhook-config: + external_webhook_url: "https://minder-test.example.com/api/v1/webhook/github" + external_ping_url: "https://minder-test.example.com/api/v1/health" + webhook_secret: "this-is-unused" + + events: + driver: go-channel + router_close_timeout: 30 + go-channel: + buffer_size: 200 +--- # Source: minder/templates/configmap.yaml # Copyright 2023 Stacklok, Inc # @@ -130,7 +325,7 @@ data: events: ["*"] events: - driver: go-channel + driver: postgresql router_close_timeout: 10 go-channel: {} @@ -161,6 +356,97 @@ data: go-channel: buffer_size: 200 --- +# Source: minder/templates/combined.yml +# Copyright 2023 Stacklok, Inc +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: v1 +kind: Service +metadata: + name: mediator-http + annotations: + alb.ingress.kubernetes.io/healthcheck-path: "/api/v1/health" + labels: + # This includes a newline, so ko sees this as valid yaml + # + app.kubernetes.io/instance: minder + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: minder + app.kubernetes.io/version: "2023-07-31" + helm.sh/chart: minder-0.1.0 +spec: + type: ClusterIP + ports: + - port: !!int "8080" + targetPort: http + protocol: TCP + name: http + selector: + app: mediator +--- +# Source: minder/templates/combined.yml +apiVersion: v1 +kind: Service +metadata: + name: mediator-grpc + annotations: + alb.ingress.kubernetes.io/backend-protocol-version: "GRPC" + alb.ingress.kubernetes.io/healthcheck-protocol: "HTTP" + alb.ingress.kubernetes.io/healthcheck-path: "/mediator.v1.HealthService/CheckHealth" + # For some reason, ALB defaults to 12 (unimplemented) as a success code + alb.ingress.kubernetes.io/success-codes: "0" + labels: + # This includes a newline, so ko sees this as valid yaml + # + app.kubernetes.io/instance: minder + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: minder + app.kubernetes.io/version: "2023-07-31" + helm.sh/chart: minder-0.1.0 +spec: + type: ClusterIP + ports: + - port: !!int "8090" + targetPort: grpc + protocol: TCP + name: grpc + selector: + app: mediator +--- +# Source: minder/templates/combined.yml +apiVersion: v1 +kind: Service +metadata: + name: mediator-metrics + labels: + # This includes a newline, so ko sees this as valid yaml + # + app.kubernetes.io/instance: minder + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: minder + app.kubernetes.io/version: "2023-07-31" + helm.sh/chart: minder-0.1.0 +spec: + type: ClusterIP + ports: + - port: !!int "9090" + targetPort: http + protocol: TCP + name: metrics + selector: + app: mediator +--- # Source: minder/templates/service.yaml # Copyright 2023 Stacklok, Inc # @@ -249,6 +535,137 @@ spec: selector: app: minder --- +# Source: minder/templates/combined.yml +# Copyright 2023 Stacklok, Inc +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: apps/v1 +kind: Deployment +metadata: + name: mediator + labels: + # This includes a newline, so ko sees this as valid yaml + # + app.kubernetes.io/instance: minder + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: minder + app.kubernetes.io/version: "2023-07-31" + helm.sh/chart: minder-0.1.0 +spec: + # We'll use autoscaling, sometimes clamped to one instance + selector: + matchLabels: + app: 'minder' + template: + metadata: + labels: + app: 'minder' + annotations: + # This includes a newline, so ko sees this as valid yaml + # + prometheus.io/scrape: "true" + prometheus.io/port: "9090" + prometheus.io/path: "/metrics" + spec: + serviceAccountName: mediator + containers: + - name: mediator + # restricted security context: + # https://kubernetes.io/docs/concepts/security/pod-security-standards/ + securityContext: + allowPrivilegeEscalation: false + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + capabilities: + drop: + - ALL + image: server:latest@sha256:23918f251e61748d850296d1a475ad81f2315a628cfd47864e52f10e6d3f4920 + args: + - "serve" + - "--db-host=postgres.postgres.svc" + - "--config=/config/config.yaml" + # We use two config files, one with all the defaults, and one with + # additional override values from helm. (This is a viper feature.) + - "--config=/config/overrides.yaml" + - "--grpc-host=0.0.0.0" + - "--http-host=0.0.0.0" + - "--metric-host=0.0.0.0" + - "--github-client-id-file=/secrets/app/client_id" + - "--github-client-secret-file=/secrets/app/client_secret" + env: + - name: "AUTH_ACCESS_TOKEN_PRIVATE_KEY" + value: "/secrets/auth/access_token_rsa" + - name: "AUTH_ACCESS_TOKEN_PUBLIC_KEY" + value: "/secrets/auth/access_token_rsa.pub" + - name: "AUTH_REFRESH_TOKEN_PRIVATE_KEY" + value: "/secrets/auth/refresh_token_rsa" + - name: "AUTH_REFRESH_TOKEN_PUBLIC_KEY" + value: "/secrets/auth/refresh_token_rsa.pub" + - name: "AUTH_TOKEN_KEY" + value: "/secrets/auth/token_key_passphrase" + # ko will always specify a digest, so we don't need to worry about + # CRI image caching + imagePullPolicy: IfNotPresent + ports: + - name: http + containerPort: !!int "8080" + protocol: TCP + - name: grpc + containerPort: !!int "8090" + protocol: TCP + - name: metric + containerPort: !!int "9090" + protocol: TCP + livenessProbe: + httpGet: + path: /api/v1/health + port: http + readinessProbe: + httpGet: + path: /api/v1/health + port: http + resources: + requests: + cpu: 1 + memory: 1Gi + limits: + cpu: 4 + memory: 1.5Gi + volumeMounts: + - name: config + mountPath: /config + - name: auth-secrets + mountPath: /secrets/auth + - name: app-secrets + mountPath: /secrets/app + volumes: + - name: config + configMap: + name: mediator-config + items: + - key: config.yaml + path: config.yaml + - key: overrides.yaml + path: overrides.yaml + - name: auth-secrets + secret: + secretName: mediator-auth-secrets + - name: app-secrets + secret: + secretName: mediator-github-secrets +--- # Source: minder/templates/deployment.yaml # Copyright 2023 Stacklok, Inc # @@ -402,6 +819,49 @@ spec: sizeLimit: 1Mi name: db-password --- +# Source: minder/templates/combined.yml +# Copyright 2023 Stacklok, Inc +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + name: mediator + labels: + # This includes a newline, so ko sees this as valid yaml + # + app.kubernetes.io/instance: minder + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: minder + app.kubernetes.io/version: "2023-07-31" + helm.sh/chart: minder-0.1.0 +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: mediator + minReplicas: 1 + # Clamp to 1 at the moment + maxReplicas: 1 + metrics: + - type: Resource + resource: + name: cpu + target: + type: Utilization + averageUtilization: 60 +--- # Source: minder/templates/hpa.yaml # Copyright 2023 Stacklok, Inc # @@ -443,6 +903,153 @@ spec: type: Utilization averageUtilization: 60 --- +# Source: minder/templates/combined.yml +# Copyright 2023 Stacklok, Inc +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: mediator + labels: + # This includes a newline, so ko sees this as valid yaml + # + app.kubernetes.io/instance: minder + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: minder + app.kubernetes.io/version: "2023-07-31" + helm.sh/chart: minder-0.1.0 + annotations: + alb.ingress.kubernetes.io/group.name: mediator-vip + alb.ingress.kubernetes.io/group.order: '200' + alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80},{"HTTPS":443}]' + alb.ingress.kubernetes.io/scheme: internet-facing + alb.ingress.kubernetes.io/ssl-redirect: "443" + alb.ingress.kubernetes.io/target-type: ip + # ALB doesn't use support cert-manager, but maybe someone else will benefit from it? + cert-manager.io/cluster-issuer: letsencrypt +spec: + # Don't set ingressClassName for now, assume default + tls: + - hosts: + - "minder-test.example.com" + secretName: mediator-tls + rules: + - host: "minder-test.example.com" + http: + paths: + # We use Prefix matches on gRPC service names because Ingress API + # doesn't support matching on Content-Type: application/grpc + - path: /grpc.reflection.v1alpha.ServerReflection + pathType: Prefix + backend: + service: + name: mediator-grpc + port: + name: grpc + - path: /mediator.v1.OAuthService + pathType: Prefix + backend: + service: + name: mediator-grpc + port: + name: grpc + - path: /mediator.v1.AuthService + pathType: Prefix + backend: + service: + name: mediator-grpc + port: + name: grpc + - path: /mediator.v1.VulnerabilitiesService + pathType: Prefix + backend: + service: + name: mediator-grpc + port: + name: grpc + - path: /mediator.v1.SecretsService + pathType: Prefix + backend: + service: + name: mediator-grpc + port: + name: grpc + - path: /mediator.v1.RepositoryService + pathType: Prefix + backend: + service: + name: mediator-grpc + port: + name: grpc + - path: /mediator.v1.BranchProtectionService + pathType: Prefix + backend: + service: + name: mediator-grpc + port: + name: grpc + - path: /mediator.v1.OrganizationService + pathType: Prefix + backend: + service: + name: mediator-grpc + port: + name: grpc + - path: /mediator.v1.GroupService + pathType: Prefix + backend: + service: + name: mediator-grpc + port: + name: grpc + - path: /mediator.v1.RoleService + pathType: Prefix + backend: + service: + name: mediator-grpc + port: + name: grpc + - path: /mediator.v1.UserService + pathType: Prefix + backend: + service: + name: mediator-grpc + port: + name: grpc + - path: /mediator.v1.PolicyService + pathType: Prefix + backend: + service: + name: mediator-grpc + port: + name: grpc + - path: /mediator.v1.KeyService + pathType: Prefix + backend: + service: + name: mediator-grpc + port: + name: grpc + - path: / + pathType: Prefix + backend: + service: + name: mediator-http + port: + name: http +--- # Source: minder/templates/ingress.yaml # Copyright 2023 Stacklok, Inc # @@ -638,6 +1245,193 @@ spec: # See the License for the specific language governing permissions and # limitations under the License. --- +# Source: minder/templates/combined.yml +# Copyright 2023 Stacklok, Inc +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# We need a separate service account for the db-update job, because +# it runs as a helm pre-install hook, and the mediator service account +# won't have been installed at that point. +apiVersion: v1 +kind: ServiceAccount +metadata: + name: db-update + annotations: + eks.amazonaws.com/role-arn: "arn:aws:iam::123456789012:role/" + helm.sh/hook-delete-policy: before-hook-creation + helm.sh/hook: pre-install,pre-upgrade + labels: + # This includes a newline, so ko sees this as valid yaml + # + app.kubernetes.io/instance: minder + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: minder + app.kubernetes.io/version: "2023-07-31" + helm.sh/chart: minder-0.1.0 +imagePullSecrets: + - name: mediator-pull-secret +--- +# Source: minder/templates/combined.yml +apiVersion: v1 +kind: ConfigMap +metadata: + name: db-update-config + annotations: + helm.sh/hook-delete-policy: before-hook-creation + helm.sh/hook: pre-install,pre-upgrade + labels: + helm.sh/chart: 'minder-0.1.0' + app.kubernetes.io/name: mediator + app.kubernetes.io/instance: "minder" + app.kubernetes.io/version: "2023-07-31" + app.kubernetes.io/managed-by: "Helm" +data: + config.yaml: | + + # + # Copyright 2023 Stacklok, Inc. + # + # Licensed under the Apache License, Version 2.0 (the "License"); + # you may not use this file except in compliance with the License. + # You may obtain a copy of the License at + # + # http://www.apache.org/licenses/LICENSE-2.0 + # + # Unless required by applicable law or agreed to in writing, software + # distributed under the License is distributed on an "AS IS" BASIS, + # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + # See the License for the specific language governing permissions and + # limitations under the License. + + # HTTP, gRPC & metrics server configuration + http_server: + host: "127.0.0.1" + port: 8080 + grpc_server: + host: "127.0.0.1" + port: 8090 + metric_server: + host: "127.0.0.1" + port: 9090 + + logging: + level: "debug" + format: "json" + #logFile: "/var/log/minder.log" + + tracing: + enabled: false + #sample_ratio: 0.1 + + metrics: + enabled: true + + database: + dbhost: "localhost" + dbport: 5432 + dbuser: postgres + dbpass: postgres + dbname: minder + sslmode: disable + + identity: + cli: + issuer_url: http://localhost:8081 + realm: stacklok + client_id: minder-cli + server: + issuer_url: http://keycloak:8080 # Use http://localhost:8081 instead for running minder outside of docker-compose + realm: stacklok + client_id: minder-server + client_secret: secret + + # Crypto (these should be ultimately stored in a secure vault) + # The token key can be generated with: + # openssl rand -base64 32 > .ssh/token_key_passphrase + auth: + token_key: "./.ssh/token_key_passphrase" + + # Password Salting, these values are using argon2id + # https://en.wikipedia.org/wiki/Argon2 + # Argon has resistance against side-channel timing attacks and tradeoff attacks + # but it is computationally expensive. + # If this is a problematic, we could use bcrypt instead. + # https://en.wikipedia.org/wiki/Bcrypt + salt: + # The amount of memory used by the algorithm (in kibibytes). + memory: 65536 + # the amount of iterations + iterations: 50 + # degree of parallelism (number of threads) + parallelism: 4 + # the length of the salt to be used + salt_length: 16 + # the desired number of returned bytes + key_length: 32 + + # Webhook Configuration + # change example.com to an exposed IP / domain + # webhook_secret is set withing the webhook sent to github. Github then signs + # the payload sent to minder and minder verifies. + webhook-config: + external_webhook_url: "https://example.com/api/v1/webhook/github" + external_ping_url: "https://example.com/api/v1/health" + webhook_secret: "your-password" + + # OAuth2 Configuration (used during enrollment) + # These values are to be set within the GitHub OAuth2 App page + github: + client_id: "abcde....." + client_secret: "abcde....." + payload_secret: "your-password" + redirect_uri: "http://localhost:8080/api/v1/auth/callback/github" + # [*] for all events. It can also be a list such as [push,branch_protection_rule]. + # Please check complete list on https://docs.github.com/es/webhooks-and-events/webhooks/webhook-events-and-payloads + events: ["*"] + + events: + driver: postgresql + router_close_timeout: 10 + go-channel: {} + + overrides.yaml: | + + database: + dbuser: minder + dbname: minder + sslmode: disabled + + identity: + server: + issuer_url: http://keycloak-deployment.keycloak.svc:80 + realm: minder + client_id: minder-server + + github: + redirect_uri: "https://minder-test.example.com/api/v1/auth/callback/github" + + webhook-config: + external_webhook_url: "https://minder-test.example.com/api/v1/webhook/github" + external_ping_url: "https://minder-test.example.com/api/v1/health" + webhook_secret: "this-is-unused" + + events: + driver: go-channel + router_close_timeout: 30 + go-channel: + buffer_size: 200 +--- # Source: minder/templates/job.yaml apiVersion: v1 kind: ConfigMap @@ -757,7 +1551,7 @@ data: events: ["*"] events: - driver: go-channel + driver: postgresql router_close_timeout: 10 go-channel: {} @@ -768,6 +1562,74 @@ data: dbname: minder sslmode: disabled --- +# Source: minder/templates/combined.yml +apiVersion: batch/v1 +kind: Job +metadata: + name: db-update + annotations: + helm.sh/hook-delete-policy: hook-succeeded + helm.sh/hook: pre-install,pre-upgrade + helm.sh/hook-weight: "5" + labels: + helm.sh/chart: 'minder-0.1.0' + app.kubernetes.io/name: mediator + app.kubernetes.io/instance: "minder" + app.kubernetes.io/version: "2023-07-31" + app.kubernetes.io/managed-by: "Helm" +spec: + template: + metadata: + labels: + app: db-init + spec: + serviceAccountName: db-update + restartPolicy: Never + containers: + - name: mediator-dbinit + # restricted security context: + # https://kubernetes.io/docs/concepts/security/pod-security-standards/ + securityContext: + allowPrivilegeEscalation: false + runAsNonRoot: true + seccompProfile: + type: RuntimeDefault + capabilities: + drop: + - ALL + image: server:latest@sha256:23918f251e61748d850296d1a475ad81f2315a628cfd47864e52f10e6d3f4920 + args: + - "migrate" + - "up" + - "--yes" + - "--db-host=postgres.postgres.svc" + - "--config=/config/config.yaml" + # We use two config files, one with all the defaults, and one with + # additional override values from helm. (This is a viper feature.) + - "--config=/config/overrides.yaml" + # ko will always specify a digest, so we don't need to worry about + # CRI image caching + imagePullPolicy: IfNotPresent + resources: + requests: + cpu: 200m + memory: 200Mi + limits: + cpu: 1 + memory: 300Mi + volumeMounts: + - name: config + mountPath: /config + volumes: + - name: config + configMap: + name: db-update-config + items: + - key: config.yaml + path: config.yaml + - key: overrides.yaml + path: overrides.yaml +--- # Source: minder/templates/job.yaml apiVersion: batch/v1 kind: Job From 627ec78b7b13b1e3f48b4f8c6b6e2ca047421ea5 Mon Sep 17 00:00:00 2001 From: Teodor Yanev Date: Fri, 17 Nov 2023 17:15:29 +0200 Subject: [PATCH 03/10] add-second-db-for-eventing --- cmd/server/app/serve.go | 21 +++++++++++++++++-- docker-compose.yaml | 20 ++++++++++++++++++ internal/config/config.go | 1 + internal/config/db.go | 35 +++++++++++++++++++++++++++++++- internal/eea/eea_test.go | 2 +- internal/engine/executor_test.go | 2 +- 6 files changed, 76 insertions(+), 5 deletions(-) diff --git a/cmd/server/app/serve.go b/cmd/server/app/serve.go index 1216661680..82791649eb 100644 --- a/cmd/server/app/serve.go +++ b/cmd/server/app/serve.go @@ -16,6 +16,7 @@ package app import ( + "database/sql" "fmt" "log" "net/url" @@ -65,13 +66,29 @@ var serveCmd = &cobra.Command{ if err != nil { return fmt.Errorf("unable to connect to database: %w", err) } - defer dbConn.Close() + defer func(dbConn *sql.DB) { + err := dbConn.Close() + if err != nil { + log.Printf("error closing database connection: %v", err) + } + }(dbConn) store := db.NewStore(dbConn) + dbConnEvents, _, err := cfg.DatabaseQueue.GetDBConnection(ctx) + if err != nil { + return fmt.Errorf("unable to connect to events database: %w", err) + } + defer func(dbConnEvents *sql.DB) { + err := dbConnEvents.Close() + if err != nil { + log.Printf("error closing events database connection: %v", err) + } + }(dbConnEvents) + errg, ctx := errgroup.WithContext(ctx) - evt, err := events.Setup(ctx, &cfg.Events, dbConn) + evt, err := events.Setup(ctx, &cfg.Events, dbConnEvents) if err != nil { log.Printf("Failed to set up eventer: %v", err) return err diff --git a/docker-compose.yaml b/docker-compose.yaml index 99a6f83415..5a6d43fa82 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -25,6 +25,7 @@ services: "--http-host=0.0.0.0", "--metric-host=0.0.0.0", "--db-host=postgres", + "--db-events-host=postgres_queue", "--config=/app/config.yaml", # If you don't want to store your GitHub client ID and secret in the main # config file, point to them here: @@ -60,6 +61,8 @@ services: depends_on: postgres: condition: service_healthy + postgres_queue: + condition: service_healthy keycloak: condition: service_healthy # migrate: @@ -109,6 +112,23 @@ services: retries: 5 networks: - app_net + postgres_queue: + container_name: postgres_queue_container + image: postgres:15-alpine + restart: always + environment: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres + POSTGRES_DB: minder-queue + networks: + - app_net + ports: + - "5433:5432" + healthcheck: + test: ["CMD-SHELL", "pg_isready"] + interval: 10s + timeout: 5s + retries: 5 keycloak: container_name: keycloak_container diff --git a/internal/config/config.go b/internal/config/config.go index 2d4182cfa3..4b5bcd72d7 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -36,6 +36,7 @@ type Config struct { Tracing TracingConfig `mapstructure:"tracing"` Metrics MetricsConfig `mapstructure:"metrics"` Database DatabaseConfig `mapstructure:"database"` + DatabaseQueue DatabaseConfig `mapstructure:"database_queue"` Identity IdentityConfig `mapstructure:"identity"` Salt CryptoConfig `mapstructure:"salt"` Auth AuthConfig `mapstructure:"auth"` diff --git a/internal/config/db.go b/internal/config/db.go index c00e8c4bdd..033f4be1d6 100644 --- a/internal/config/db.go +++ b/internal/config/db.go @@ -154,6 +154,39 @@ func RegisterDatabaseFlags(v *viper.Viper, flags *pflag.FlagSet) error { return err } - return util.BindConfigFlagWithShort( + err = util.BindConfigFlagWithShort( v, flags, "database.sslmode", "db-sslmode", "s", "disable", "Database sslmode", flags.StringP) + + err = util.BindConfigFlagWithShort( + v, flags, "database_queue.dbhost", "db-events-host", "Q", "localhost", "Database Events host", flags.StringP) + if err != nil { + return err + } + + err = util.BindConfigFlag( + v, flags, "database_queue.dbport", "db-events-port", 5432, "Database Events port", flags.Int) + if err != nil { + return err + } + + err = util.BindConfigFlagWithShort( + v, flags, "database_queue.dbuser", "db-events-user", "U", "postgres", "Database Events user", flags.StringP) + if err != nil { + return err + } + + err = util.BindConfigFlagWithShort( + v, flags, "database_queue.dbpass", "db-events-pass", "W", "postgres", "Database Events password", flags.StringP) + if err != nil { + return err + } + + err = util.BindConfigFlagWithShort( + v, flags, "database_queue.dbname", "db-events-name", "N", "minder-queue", "Database Events name", flags.StringP) + if err != nil { + return err + } + + return util.BindConfigFlagWithShort( + v, flags, "database_queue.sslmode", "db-events-sslmode", "M", "disable", "Database Events sslmode", flags.StringP) } diff --git a/internal/eea/eea_test.go b/internal/eea/eea_test.go index 6534c7a27b..e60b2136d3 100644 --- a/internal/eea/eea_test.go +++ b/internal/eea/eea_test.go @@ -56,7 +56,7 @@ func TestAggregator(t *testing.T) { BufferSize: concurrentEvents, BlockPublishUntilSubscriberAck: true, }, - }) + }, nil) require.NoError(t, err) // we'll wait 2 seconds for the lock to be available diff --git a/internal/engine/executor_test.go b/internal/engine/executor_test.go index 8d3f7c272f..08ef980785 100644 --- a/internal/engine/executor_test.go +++ b/internal/engine/executor_test.go @@ -265,7 +265,7 @@ default allow = true`, GoChannel: config.GoChannelEventConfig{ BlockPublishUntilSubscriberAck: true, }, - }) + }, nil) require.NoError(t, err, "failed to setup eventer") go func() { From 66ceb694df9e683408231fb3f339af5f7b9f99f1 Mon Sep 17 00:00:00 2001 From: Teodor Yanev Date: Fri, 17 Nov 2023 17:43:01 +0200 Subject: [PATCH 04/10] fix-helm-tests-2 --- deployment/helm_tests/basic.yaml-out | 872 +------------------------ deployment/helm_tests/sidecar.yaml-out | 872 +------------------------ 2 files changed, 10 insertions(+), 1734 deletions(-) diff --git a/deployment/helm_tests/basic.yaml-out b/deployment/helm_tests/basic.yaml-out index 342ba23276..80cfa00f3b 100644 --- a/deployment/helm_tests/basic.yaml-out +++ b/deployment/helm_tests/basic.yaml-out @@ -1,199 +1,4 @@ --- -# Source: minder/templates/combined.yml -# Copyright 2023 Stacklok, Inc -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -apiVersion: v1 -kind: ServiceAccount -metadata: - name: mediator - labels: - # This includes a newline, so ko sees this as valid yaml - # - app.kubernetes.io/instance: minder - app.kubernetes.io/managed-by: Helm - app.kubernetes.io/name: minder - app.kubernetes.io/version: "2023-07-31" - helm.sh/chart: minder-0.1.0 - annotations: - eks.amazonaws.com/role-arn: "arn:aws:iam::123456789012:role/" -imagePullSecrets: - - name: mediator-pull-secret ---- -# Source: minder/templates/combined.yml -# Copyright 2023 Stacklok, Inc -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -apiVersion: v1 -kind: ConfigMap -metadata: - name: mediator-config - labels: - # This includes a newline, so ko sees this as valid yaml - # - app.kubernetes.io/instance: minder - app.kubernetes.io/managed-by: Helm - app.kubernetes.io/name: minder - app.kubernetes.io/version: "2023-07-31" - helm.sh/chart: minder-0.1.0 -data: - config.yaml: | - - # - # Copyright 2023 Stacklok, Inc. - # - # Licensed under the Apache License, Version 2.0 (the "License"); - # you may not use this file except in compliance with the License. - # You may obtain a copy of the License at - # - # http://www.apache.org/licenses/LICENSE-2.0 - # - # Unless required by applicable law or agreed to in writing, software - # distributed under the License is distributed on an "AS IS" BASIS, - # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - # See the License for the specific language governing permissions and - # limitations under the License. - - # HTTP, gRPC & metrics server configuration - http_server: - host: "127.0.0.1" - port: 8080 - grpc_server: - host: "127.0.0.1" - port: 8090 - metric_server: - host: "127.0.0.1" - port: 9090 - - logging: - level: "debug" - format: "json" - #logFile: "/var/log/minder.log" - - tracing: - enabled: false - #sample_ratio: 0.1 - - metrics: - enabled: true - - database: - dbhost: "localhost" - dbport: 5432 - dbuser: postgres - dbpass: postgres - dbname: minder - sslmode: disable - - identity: - cli: - issuer_url: http://localhost:8081 - realm: stacklok - client_id: minder-cli - server: - issuer_url: http://keycloak:8080 # Use http://localhost:8081 instead for running minder outside of docker-compose - realm: stacklok - client_id: minder-server - client_secret: secret - - # Crypto (these should be ultimately stored in a secure vault) - # The token key can be generated with: - # openssl rand -base64 32 > .ssh/token_key_passphrase - auth: - token_key: "./.ssh/token_key_passphrase" - - # Password Salting, these values are using argon2id - # https://en.wikipedia.org/wiki/Argon2 - # Argon has resistance against side-channel timing attacks and tradeoff attacks - # but it is computationally expensive. - # If this is a problematic, we could use bcrypt instead. - # https://en.wikipedia.org/wiki/Bcrypt - salt: - # The amount of memory used by the algorithm (in kibibytes). - memory: 65536 - # the amount of iterations - iterations: 50 - # degree of parallelism (number of threads) - parallelism: 4 - # the length of the salt to be used - salt_length: 16 - # the desired number of returned bytes - key_length: 32 - - # Webhook Configuration - # change example.com to an exposed IP / domain - # webhook_secret is set withing the webhook sent to github. Github then signs - # the payload sent to minder and minder verifies. - webhook-config: - external_webhook_url: "https://example.com/api/v1/webhook/github" - external_ping_url: "https://example.com/api/v1/health" - webhook_secret: "your-password" - - # OAuth2 Configuration (used during enrollment) - # These values are to be set within the GitHub OAuth2 App page - github: - client_id: "abcde....." - client_secret: "abcde....." - payload_secret: "your-password" - redirect_uri: "http://localhost:8080/api/v1/auth/callback/github" - # [*] for all events. It can also be a list such as [push,branch_protection_rule]. - # Please check complete list on https://docs.github.com/es/webhooks-and-events/webhooks/webhook-events-and-payloads - events: ["*"] - - events: - driver: postgresql - router_close_timeout: 10 - go-channel: {} - - overrides.yaml: | - - database: - dbuser: minder - dbname: minder - sslmode: disabled - - identity: - server: - issuer_url: http://keycloak-deployment.keycloak.svc:80 - realm: minder - client_id: minder-server - - github: - redirect_uri: "https://minder-test.example.com/api/v1/auth/callback/github" - - webhook-config: - external_webhook_url: "https://minder-test.example.com/api/v1/webhook/github" - external_ping_url: "https://minder-test.example.com/api/v1/health" - webhook_secret: "this-is-unused" - - events: - driver: go-channel - router_close_timeout: 30 - go-channel: - buffer_size: 200 ---- # Source: minder/templates/configmap.yaml # Copyright 2023 Stacklok, Inc # @@ -356,97 +161,6 @@ data: go-channel: buffer_size: 200 --- -# Source: minder/templates/combined.yml -# Copyright 2023 Stacklok, Inc -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -apiVersion: v1 -kind: Service -metadata: - name: mediator-http - annotations: - alb.ingress.kubernetes.io/healthcheck-path: "/api/v1/health" - labels: - # This includes a newline, so ko sees this as valid yaml - # - app.kubernetes.io/instance: minder - app.kubernetes.io/managed-by: Helm - app.kubernetes.io/name: minder - app.kubernetes.io/version: "2023-07-31" - helm.sh/chart: minder-0.1.0 -spec: - type: ClusterIP - ports: - - port: !!int "8080" - targetPort: http - protocol: TCP - name: http - selector: - app: mediator ---- -# Source: minder/templates/combined.yml -apiVersion: v1 -kind: Service -metadata: - name: mediator-grpc - annotations: - alb.ingress.kubernetes.io/backend-protocol-version: "GRPC" - alb.ingress.kubernetes.io/healthcheck-protocol: "HTTP" - alb.ingress.kubernetes.io/healthcheck-path: "/mediator.v1.HealthService/CheckHealth" - # For some reason, ALB defaults to 12 (unimplemented) as a success code - alb.ingress.kubernetes.io/success-codes: "0" - labels: - # This includes a newline, so ko sees this as valid yaml - # - app.kubernetes.io/instance: minder - app.kubernetes.io/managed-by: Helm - app.kubernetes.io/name: minder - app.kubernetes.io/version: "2023-07-31" - helm.sh/chart: minder-0.1.0 -spec: - type: ClusterIP - ports: - - port: !!int "8090" - targetPort: grpc - protocol: TCP - name: grpc - selector: - app: mediator ---- -# Source: minder/templates/combined.yml -apiVersion: v1 -kind: Service -metadata: - name: mediator-metrics - labels: - # This includes a newline, so ko sees this as valid yaml - # - app.kubernetes.io/instance: minder - app.kubernetes.io/managed-by: Helm - app.kubernetes.io/name: minder - app.kubernetes.io/version: "2023-07-31" - helm.sh/chart: minder-0.1.0 -spec: - type: ClusterIP - ports: - - port: !!int "9090" - targetPort: http - protocol: TCP - name: metrics - selector: - app: mediator ---- # Source: minder/templates/service.yaml # Copyright 2023 Stacklok, Inc # @@ -535,137 +249,6 @@ spec: selector: app: minder --- -# Source: minder/templates/combined.yml -# Copyright 2023 Stacklok, Inc -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -apiVersion: apps/v1 -kind: Deployment -metadata: - name: mediator - labels: - # This includes a newline, so ko sees this as valid yaml - # - app.kubernetes.io/instance: minder - app.kubernetes.io/managed-by: Helm - app.kubernetes.io/name: minder - app.kubernetes.io/version: "2023-07-31" - helm.sh/chart: minder-0.1.0 -spec: - # We'll use autoscaling, sometimes clamped to one instance - selector: - matchLabels: - app: 'minder' - template: - metadata: - labels: - app: 'minder' - annotations: - # This includes a newline, so ko sees this as valid yaml - # - prometheus.io/scrape: "true" - prometheus.io/port: "9090" - prometheus.io/path: "/metrics" - spec: - serviceAccountName: mediator - containers: - - name: mediator - # restricted security context: - # https://kubernetes.io/docs/concepts/security/pod-security-standards/ - securityContext: - allowPrivilegeEscalation: false - runAsNonRoot: true - seccompProfile: - type: RuntimeDefault - capabilities: - drop: - - ALL - image: server:latest@sha256:23918f251e61748d850296d1a475ad81f2315a628cfd47864e52f10e6d3f4920 - args: - - "serve" - - "--db-host=postgres.postgres.svc" - - "--config=/config/config.yaml" - # We use two config files, one with all the defaults, and one with - # additional override values from helm. (This is a viper feature.) - - "--config=/config/overrides.yaml" - - "--grpc-host=0.0.0.0" - - "--http-host=0.0.0.0" - - "--metric-host=0.0.0.0" - - "--github-client-id-file=/secrets/app/client_id" - - "--github-client-secret-file=/secrets/app/client_secret" - env: - - name: "AUTH_ACCESS_TOKEN_PRIVATE_KEY" - value: "/secrets/auth/access_token_rsa" - - name: "AUTH_ACCESS_TOKEN_PUBLIC_KEY" - value: "/secrets/auth/access_token_rsa.pub" - - name: "AUTH_REFRESH_TOKEN_PRIVATE_KEY" - value: "/secrets/auth/refresh_token_rsa" - - name: "AUTH_REFRESH_TOKEN_PUBLIC_KEY" - value: "/secrets/auth/refresh_token_rsa.pub" - - name: "AUTH_TOKEN_KEY" - value: "/secrets/auth/token_key_passphrase" - # ko will always specify a digest, so we don't need to worry about - # CRI image caching - imagePullPolicy: IfNotPresent - ports: - - name: http - containerPort: !!int "8080" - protocol: TCP - - name: grpc - containerPort: !!int "8090" - protocol: TCP - - name: metric - containerPort: !!int "9090" - protocol: TCP - livenessProbe: - httpGet: - path: /api/v1/health - port: http - readinessProbe: - httpGet: - path: /api/v1/health - port: http - resources: - requests: - cpu: 1 - memory: 1Gi - limits: - cpu: 4 - memory: 1.5Gi - volumeMounts: - - name: config - mountPath: /config - - name: auth-secrets - mountPath: /secrets/auth - - name: app-secrets - mountPath: /secrets/app - volumes: - - name: config - configMap: - name: mediator-config - items: - - key: config.yaml - path: config.yaml - - key: overrides.yaml - path: overrides.yaml - - name: auth-secrets - secret: - secretName: mediator-auth-secrets - - name: app-secrets - secret: - secretName: mediator-github-secrets ---- # Source: minder/templates/deployment.yaml # Copyright 2023 Stacklok, Inc # @@ -794,54 +377,11 @@ spec: secret: secretName: minder-auth-secrets - name: app-secrets - secret: - secretName: minder-github-api-secrets - - name: identity-secrets - secret: - secretName: minder-identity-secrets ---- -# Source: minder/templates/combined.yml -# Copyright 2023 Stacklok, Inc -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -apiVersion: autoscaling/v2 -kind: HorizontalPodAutoscaler -metadata: - name: mediator - labels: - # This includes a newline, so ko sees this as valid yaml - # - app.kubernetes.io/instance: minder - app.kubernetes.io/managed-by: Helm - app.kubernetes.io/name: minder - app.kubernetes.io/version: "2023-07-31" - helm.sh/chart: minder-0.1.0 -spec: - scaleTargetRef: - apiVersion: apps/v1 - kind: Deployment - name: mediator - minReplicas: 1 - # Clamp to 1 at the moment - maxReplicas: 1 - metrics: - - type: Resource - resource: - name: cpu - target: - type: Utilization - averageUtilization: 60 + secret: + secretName: minder-github-api-secrets + - name: identity-secrets + secret: + secretName: minder-identity-secrets --- # Source: minder/templates/hpa.yaml # Copyright 2023 Stacklok, Inc @@ -884,153 +424,6 @@ spec: type: Utilization averageUtilization: 60 --- -# Source: minder/templates/combined.yml -# Copyright 2023 Stacklok, Inc -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: mediator - labels: - # This includes a newline, so ko sees this as valid yaml - # - app.kubernetes.io/instance: minder - app.kubernetes.io/managed-by: Helm - app.kubernetes.io/name: minder - app.kubernetes.io/version: "2023-07-31" - helm.sh/chart: minder-0.1.0 - annotations: - alb.ingress.kubernetes.io/group.name: mediator-vip - alb.ingress.kubernetes.io/group.order: '200' - alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80},{"HTTPS":443}]' - alb.ingress.kubernetes.io/scheme: internet-facing - alb.ingress.kubernetes.io/ssl-redirect: "443" - alb.ingress.kubernetes.io/target-type: ip - # ALB doesn't use support cert-manager, but maybe someone else will benefit from it? - cert-manager.io/cluster-issuer: letsencrypt -spec: - # Don't set ingressClassName for now, assume default - tls: - - hosts: - - "minder-test.example.com" - secretName: mediator-tls - rules: - - host: "minder-test.example.com" - http: - paths: - # We use Prefix matches on gRPC service names because Ingress API - # doesn't support matching on Content-Type: application/grpc - - path: /grpc.reflection.v1alpha.ServerReflection - pathType: Prefix - backend: - service: - name: mediator-grpc - port: - name: grpc - - path: /mediator.v1.OAuthService - pathType: Prefix - backend: - service: - name: mediator-grpc - port: - name: grpc - - path: /mediator.v1.AuthService - pathType: Prefix - backend: - service: - name: mediator-grpc - port: - name: grpc - - path: /mediator.v1.VulnerabilitiesService - pathType: Prefix - backend: - service: - name: mediator-grpc - port: - name: grpc - - path: /mediator.v1.SecretsService - pathType: Prefix - backend: - service: - name: mediator-grpc - port: - name: grpc - - path: /mediator.v1.RepositoryService - pathType: Prefix - backend: - service: - name: mediator-grpc - port: - name: grpc - - path: /mediator.v1.BranchProtectionService - pathType: Prefix - backend: - service: - name: mediator-grpc - port: - name: grpc - - path: /mediator.v1.OrganizationService - pathType: Prefix - backend: - service: - name: mediator-grpc - port: - name: grpc - - path: /mediator.v1.GroupService - pathType: Prefix - backend: - service: - name: mediator-grpc - port: - name: grpc - - path: /mediator.v1.RoleService - pathType: Prefix - backend: - service: - name: mediator-grpc - port: - name: grpc - - path: /mediator.v1.UserService - pathType: Prefix - backend: - service: - name: mediator-grpc - port: - name: grpc - - path: /mediator.v1.PolicyService - pathType: Prefix - backend: - service: - name: mediator-grpc - port: - name: grpc - - path: /mediator.v1.KeyService - pathType: Prefix - backend: - service: - name: mediator-grpc - port: - name: grpc - - path: / - pathType: Prefix - backend: - service: - name: mediator-http - port: - name: http ---- # Source: minder/templates/ingress.yaml # Copyright 2023 Stacklok, Inc # @@ -1226,193 +619,6 @@ spec: # See the License for the specific language governing permissions and # limitations under the License. --- -# Source: minder/templates/combined.yml -# Copyright 2023 Stacklok, Inc -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# We need a separate service account for the db-update job, because -# it runs as a helm pre-install hook, and the mediator service account -# won't have been installed at that point. -apiVersion: v1 -kind: ServiceAccount -metadata: - name: db-update - annotations: - eks.amazonaws.com/role-arn: "arn:aws:iam::123456789012:role/" - helm.sh/hook-delete-policy: before-hook-creation - helm.sh/hook: pre-install,pre-upgrade - labels: - # This includes a newline, so ko sees this as valid yaml - # - app.kubernetes.io/instance: minder - app.kubernetes.io/managed-by: Helm - app.kubernetes.io/name: minder - app.kubernetes.io/version: "2023-07-31" - helm.sh/chart: minder-0.1.0 -imagePullSecrets: - - name: mediator-pull-secret ---- -# Source: minder/templates/combined.yml -apiVersion: v1 -kind: ConfigMap -metadata: - name: db-update-config - annotations: - helm.sh/hook-delete-policy: before-hook-creation - helm.sh/hook: pre-install,pre-upgrade - labels: - helm.sh/chart: 'minder-0.1.0' - app.kubernetes.io/name: mediator - app.kubernetes.io/instance: "minder" - app.kubernetes.io/version: "2023-07-31" - app.kubernetes.io/managed-by: "Helm" -data: - config.yaml: | - - # - # Copyright 2023 Stacklok, Inc. - # - # Licensed under the Apache License, Version 2.0 (the "License"); - # you may not use this file except in compliance with the License. - # You may obtain a copy of the License at - # - # http://www.apache.org/licenses/LICENSE-2.0 - # - # Unless required by applicable law or agreed to in writing, software - # distributed under the License is distributed on an "AS IS" BASIS, - # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - # See the License for the specific language governing permissions and - # limitations under the License. - - # HTTP, gRPC & metrics server configuration - http_server: - host: "127.0.0.1" - port: 8080 - grpc_server: - host: "127.0.0.1" - port: 8090 - metric_server: - host: "127.0.0.1" - port: 9090 - - logging: - level: "debug" - format: "json" - #logFile: "/var/log/minder.log" - - tracing: - enabled: false - #sample_ratio: 0.1 - - metrics: - enabled: true - - database: - dbhost: "localhost" - dbport: 5432 - dbuser: postgres - dbpass: postgres - dbname: minder - sslmode: disable - - identity: - cli: - issuer_url: http://localhost:8081 - realm: stacklok - client_id: minder-cli - server: - issuer_url: http://keycloak:8080 # Use http://localhost:8081 instead for running minder outside of docker-compose - realm: stacklok - client_id: minder-server - client_secret: secret - - # Crypto (these should be ultimately stored in a secure vault) - # The token key can be generated with: - # openssl rand -base64 32 > .ssh/token_key_passphrase - auth: - token_key: "./.ssh/token_key_passphrase" - - # Password Salting, these values are using argon2id - # https://en.wikipedia.org/wiki/Argon2 - # Argon has resistance against side-channel timing attacks and tradeoff attacks - # but it is computationally expensive. - # If this is a problematic, we could use bcrypt instead. - # https://en.wikipedia.org/wiki/Bcrypt - salt: - # The amount of memory used by the algorithm (in kibibytes). - memory: 65536 - # the amount of iterations - iterations: 50 - # degree of parallelism (number of threads) - parallelism: 4 - # the length of the salt to be used - salt_length: 16 - # the desired number of returned bytes - key_length: 32 - - # Webhook Configuration - # change example.com to an exposed IP / domain - # webhook_secret is set withing the webhook sent to github. Github then signs - # the payload sent to minder and minder verifies. - webhook-config: - external_webhook_url: "https://example.com/api/v1/webhook/github" - external_ping_url: "https://example.com/api/v1/health" - webhook_secret: "your-password" - - # OAuth2 Configuration (used during enrollment) - # These values are to be set within the GitHub OAuth2 App page - github: - client_id: "abcde....." - client_secret: "abcde....." - payload_secret: "your-password" - redirect_uri: "http://localhost:8080/api/v1/auth/callback/github" - # [*] for all events. It can also be a list such as [push,branch_protection_rule]. - # Please check complete list on https://docs.github.com/es/webhooks-and-events/webhooks/webhook-events-and-payloads - events: ["*"] - - events: - driver: postgresql - router_close_timeout: 10 - go-channel: {} - - overrides.yaml: | - - database: - dbuser: minder - dbname: minder - sslmode: disabled - - identity: - server: - issuer_url: http://keycloak-deployment.keycloak.svc:80 - realm: minder - client_id: minder-server - - github: - redirect_uri: "https://minder-test.example.com/api/v1/auth/callback/github" - - webhook-config: - external_webhook_url: "https://minder-test.example.com/api/v1/webhook/github" - external_ping_url: "https://minder-test.example.com/api/v1/health" - webhook_secret: "this-is-unused" - - events: - driver: go-channel - router_close_timeout: 30 - go-channel: - buffer_size: 200 ---- # Source: minder/templates/job.yaml apiVersion: v1 kind: ConfigMap @@ -1543,74 +749,6 @@ data: dbname: minder sslmode: disabled --- -# Source: minder/templates/combined.yml -apiVersion: batch/v1 -kind: Job -metadata: - name: db-update - annotations: - helm.sh/hook-delete-policy: hook-succeeded - helm.sh/hook: pre-install,pre-upgrade - helm.sh/hook-weight: "5" - labels: - helm.sh/chart: 'minder-0.1.0' - app.kubernetes.io/name: mediator - app.kubernetes.io/instance: "minder" - app.kubernetes.io/version: "2023-07-31" - app.kubernetes.io/managed-by: "Helm" -spec: - template: - metadata: - labels: - app: db-init - spec: - serviceAccountName: db-update - restartPolicy: Never - containers: - - name: mediator-dbinit - # restricted security context: - # https://kubernetes.io/docs/concepts/security/pod-security-standards/ - securityContext: - allowPrivilegeEscalation: false - runAsNonRoot: true - seccompProfile: - type: RuntimeDefault - capabilities: - drop: - - ALL - image: server:latest@sha256:23918f251e61748d850296d1a475ad81f2315a628cfd47864e52f10e6d3f4920 - args: - - "migrate" - - "up" - - "--yes" - - "--db-host=postgres.postgres.svc" - - "--config=/config/config.yaml" - # We use two config files, one with all the defaults, and one with - # additional override values from helm. (This is a viper feature.) - - "--config=/config/overrides.yaml" - # ko will always specify a digest, so we don't need to worry about - # CRI image caching - imagePullPolicy: IfNotPresent - resources: - requests: - cpu: 200m - memory: 200Mi - limits: - cpu: 1 - memory: 300Mi - volumeMounts: - - name: config - mountPath: /config - volumes: - - name: config - configMap: - name: db-update-config - items: - - key: config.yaml - path: config.yaml - - key: overrides.yaml - path: overrides.yaml ---- # Source: minder/templates/job.yaml apiVersion: batch/v1 kind: Job diff --git a/deployment/helm_tests/sidecar.yaml-out b/deployment/helm_tests/sidecar.yaml-out index 3d48b97730..53d999b0e9 100644 --- a/deployment/helm_tests/sidecar.yaml-out +++ b/deployment/helm_tests/sidecar.yaml-out @@ -1,199 +1,4 @@ --- -# Source: minder/templates/combined.yml -# Copyright 2023 Stacklok, Inc -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -apiVersion: v1 -kind: ServiceAccount -metadata: - name: mediator - labels: - # This includes a newline, so ko sees this as valid yaml - # - app.kubernetes.io/instance: minder - app.kubernetes.io/managed-by: Helm - app.kubernetes.io/name: minder - app.kubernetes.io/version: "2023-07-31" - helm.sh/chart: minder-0.1.0 - annotations: - eks.amazonaws.com/role-arn: "arn:aws:iam::123456789012:role/" -imagePullSecrets: - - name: mediator-pull-secret ---- -# Source: minder/templates/combined.yml -# Copyright 2023 Stacklok, Inc -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -apiVersion: v1 -kind: ConfigMap -metadata: - name: mediator-config - labels: - # This includes a newline, so ko sees this as valid yaml - # - app.kubernetes.io/instance: minder - app.kubernetes.io/managed-by: Helm - app.kubernetes.io/name: minder - app.kubernetes.io/version: "2023-07-31" - helm.sh/chart: minder-0.1.0 -data: - config.yaml: | - - # - # Copyright 2023 Stacklok, Inc. - # - # Licensed under the Apache License, Version 2.0 (the "License"); - # you may not use this file except in compliance with the License. - # You may obtain a copy of the License at - # - # http://www.apache.org/licenses/LICENSE-2.0 - # - # Unless required by applicable law or agreed to in writing, software - # distributed under the License is distributed on an "AS IS" BASIS, - # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - # See the License for the specific language governing permissions and - # limitations under the License. - - # HTTP, gRPC & metrics server configuration - http_server: - host: "127.0.0.1" - port: 8080 - grpc_server: - host: "127.0.0.1" - port: 8090 - metric_server: - host: "127.0.0.1" - port: 9090 - - logging: - level: "debug" - format: "json" - #logFile: "/var/log/minder.log" - - tracing: - enabled: false - #sample_ratio: 0.1 - - metrics: - enabled: true - - database: - dbhost: "localhost" - dbport: 5432 - dbuser: postgres - dbpass: postgres - dbname: minder - sslmode: disable - - identity: - cli: - issuer_url: http://localhost:8081 - realm: stacklok - client_id: minder-cli - server: - issuer_url: http://keycloak:8080 # Use http://localhost:8081 instead for running minder outside of docker-compose - realm: stacklok - client_id: minder-server - client_secret: secret - - # Crypto (these should be ultimately stored in a secure vault) - # The token key can be generated with: - # openssl rand -base64 32 > .ssh/token_key_passphrase - auth: - token_key: "./.ssh/token_key_passphrase" - - # Password Salting, these values are using argon2id - # https://en.wikipedia.org/wiki/Argon2 - # Argon has resistance against side-channel timing attacks and tradeoff attacks - # but it is computationally expensive. - # If this is a problematic, we could use bcrypt instead. - # https://en.wikipedia.org/wiki/Bcrypt - salt: - # The amount of memory used by the algorithm (in kibibytes). - memory: 65536 - # the amount of iterations - iterations: 50 - # degree of parallelism (number of threads) - parallelism: 4 - # the length of the salt to be used - salt_length: 16 - # the desired number of returned bytes - key_length: 32 - - # Webhook Configuration - # change example.com to an exposed IP / domain - # webhook_secret is set withing the webhook sent to github. Github then signs - # the payload sent to minder and minder verifies. - webhook-config: - external_webhook_url: "https://example.com/api/v1/webhook/github" - external_ping_url: "https://example.com/api/v1/health" - webhook_secret: "your-password" - - # OAuth2 Configuration (used during enrollment) - # These values are to be set within the GitHub OAuth2 App page - github: - client_id: "abcde....." - client_secret: "abcde....." - payload_secret: "your-password" - redirect_uri: "http://localhost:8080/api/v1/auth/callback/github" - # [*] for all events. It can also be a list such as [push,branch_protection_rule]. - # Please check complete list on https://docs.github.com/es/webhooks-and-events/webhooks/webhook-events-and-payloads - events: ["*"] - - events: - driver: postgresql - router_close_timeout: 10 - go-channel: {} - - overrides.yaml: | - - database: - dbuser: minder - dbname: minder - sslmode: disabled - - identity: - server: - issuer_url: http://keycloak-deployment.keycloak.svc:80 - realm: minder - client_id: minder-server - - github: - redirect_uri: "https://minder-test.example.com/api/v1/auth/callback/github" - - webhook-config: - external_webhook_url: "https://minder-test.example.com/api/v1/webhook/github" - external_ping_url: "https://minder-test.example.com/api/v1/health" - webhook_secret: "this-is-unused" - - events: - driver: go-channel - router_close_timeout: 30 - go-channel: - buffer_size: 200 ---- # Source: minder/templates/configmap.yaml # Copyright 2023 Stacklok, Inc # @@ -356,97 +161,6 @@ data: go-channel: buffer_size: 200 --- -# Source: minder/templates/combined.yml -# Copyright 2023 Stacklok, Inc -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -apiVersion: v1 -kind: Service -metadata: - name: mediator-http - annotations: - alb.ingress.kubernetes.io/healthcheck-path: "/api/v1/health" - labels: - # This includes a newline, so ko sees this as valid yaml - # - app.kubernetes.io/instance: minder - app.kubernetes.io/managed-by: Helm - app.kubernetes.io/name: minder - app.kubernetes.io/version: "2023-07-31" - helm.sh/chart: minder-0.1.0 -spec: - type: ClusterIP - ports: - - port: !!int "8080" - targetPort: http - protocol: TCP - name: http - selector: - app: mediator ---- -# Source: minder/templates/combined.yml -apiVersion: v1 -kind: Service -metadata: - name: mediator-grpc - annotations: - alb.ingress.kubernetes.io/backend-protocol-version: "GRPC" - alb.ingress.kubernetes.io/healthcheck-protocol: "HTTP" - alb.ingress.kubernetes.io/healthcheck-path: "/mediator.v1.HealthService/CheckHealth" - # For some reason, ALB defaults to 12 (unimplemented) as a success code - alb.ingress.kubernetes.io/success-codes: "0" - labels: - # This includes a newline, so ko sees this as valid yaml - # - app.kubernetes.io/instance: minder - app.kubernetes.io/managed-by: Helm - app.kubernetes.io/name: minder - app.kubernetes.io/version: "2023-07-31" - helm.sh/chart: minder-0.1.0 -spec: - type: ClusterIP - ports: - - port: !!int "8090" - targetPort: grpc - protocol: TCP - name: grpc - selector: - app: mediator ---- -# Source: minder/templates/combined.yml -apiVersion: v1 -kind: Service -metadata: - name: mediator-metrics - labels: - # This includes a newline, so ko sees this as valid yaml - # - app.kubernetes.io/instance: minder - app.kubernetes.io/managed-by: Helm - app.kubernetes.io/name: minder - app.kubernetes.io/version: "2023-07-31" - helm.sh/chart: minder-0.1.0 -spec: - type: ClusterIP - ports: - - port: !!int "9090" - targetPort: http - protocol: TCP - name: metrics - selector: - app: mediator ---- # Source: minder/templates/service.yaml # Copyright 2023 Stacklok, Inc # @@ -535,137 +249,6 @@ spec: selector: app: minder --- -# Source: minder/templates/combined.yml -# Copyright 2023 Stacklok, Inc -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -apiVersion: apps/v1 -kind: Deployment -metadata: - name: mediator - labels: - # This includes a newline, so ko sees this as valid yaml - # - app.kubernetes.io/instance: minder - app.kubernetes.io/managed-by: Helm - app.kubernetes.io/name: minder - app.kubernetes.io/version: "2023-07-31" - helm.sh/chart: minder-0.1.0 -spec: - # We'll use autoscaling, sometimes clamped to one instance - selector: - matchLabels: - app: 'minder' - template: - metadata: - labels: - app: 'minder' - annotations: - # This includes a newline, so ko sees this as valid yaml - # - prometheus.io/scrape: "true" - prometheus.io/port: "9090" - prometheus.io/path: "/metrics" - spec: - serviceAccountName: mediator - containers: - - name: mediator - # restricted security context: - # https://kubernetes.io/docs/concepts/security/pod-security-standards/ - securityContext: - allowPrivilegeEscalation: false - runAsNonRoot: true - seccompProfile: - type: RuntimeDefault - capabilities: - drop: - - ALL - image: server:latest@sha256:23918f251e61748d850296d1a475ad81f2315a628cfd47864e52f10e6d3f4920 - args: - - "serve" - - "--db-host=postgres.postgres.svc" - - "--config=/config/config.yaml" - # We use two config files, one with all the defaults, and one with - # additional override values from helm. (This is a viper feature.) - - "--config=/config/overrides.yaml" - - "--grpc-host=0.0.0.0" - - "--http-host=0.0.0.0" - - "--metric-host=0.0.0.0" - - "--github-client-id-file=/secrets/app/client_id" - - "--github-client-secret-file=/secrets/app/client_secret" - env: - - name: "AUTH_ACCESS_TOKEN_PRIVATE_KEY" - value: "/secrets/auth/access_token_rsa" - - name: "AUTH_ACCESS_TOKEN_PUBLIC_KEY" - value: "/secrets/auth/access_token_rsa.pub" - - name: "AUTH_REFRESH_TOKEN_PRIVATE_KEY" - value: "/secrets/auth/refresh_token_rsa" - - name: "AUTH_REFRESH_TOKEN_PUBLIC_KEY" - value: "/secrets/auth/refresh_token_rsa.pub" - - name: "AUTH_TOKEN_KEY" - value: "/secrets/auth/token_key_passphrase" - # ko will always specify a digest, so we don't need to worry about - # CRI image caching - imagePullPolicy: IfNotPresent - ports: - - name: http - containerPort: !!int "8080" - protocol: TCP - - name: grpc - containerPort: !!int "8090" - protocol: TCP - - name: metric - containerPort: !!int "9090" - protocol: TCP - livenessProbe: - httpGet: - path: /api/v1/health - port: http - readinessProbe: - httpGet: - path: /api/v1/health - port: http - resources: - requests: - cpu: 1 - memory: 1Gi - limits: - cpu: 4 - memory: 1.5Gi - volumeMounts: - - name: config - mountPath: /config - - name: auth-secrets - mountPath: /secrets/auth - - name: app-secrets - mountPath: /secrets/app - volumes: - - name: config - configMap: - name: mediator-config - items: - - key: config.yaml - path: config.yaml - - key: overrides.yaml - path: overrides.yaml - - name: auth-secrets - secret: - secretName: mediator-auth-secrets - - name: app-secrets - secret: - secretName: mediator-github-secrets ---- # Source: minder/templates/deployment.yaml # Copyright 2023 Stacklok, Inc # @@ -813,54 +396,11 @@ spec: secretName: minder-github-api-secrets - name: identity-secrets secret: - secretName: minder-identity-secrets - - emptyDir: - medium: Memory - sizeLimit: 1Mi - name: db-password ---- -# Source: minder/templates/combined.yml -# Copyright 2023 Stacklok, Inc -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -apiVersion: autoscaling/v2 -kind: HorizontalPodAutoscaler -metadata: - name: mediator - labels: - # This includes a newline, so ko sees this as valid yaml - # - app.kubernetes.io/instance: minder - app.kubernetes.io/managed-by: Helm - app.kubernetes.io/name: minder - app.kubernetes.io/version: "2023-07-31" - helm.sh/chart: minder-0.1.0 -spec: - scaleTargetRef: - apiVersion: apps/v1 - kind: Deployment - name: mediator - minReplicas: 1 - # Clamp to 1 at the moment - maxReplicas: 1 - metrics: - - type: Resource - resource: - name: cpu - target: - type: Utilization - averageUtilization: 60 + secretName: minder-identity-secrets + - emptyDir: + medium: Memory + sizeLimit: 1Mi + name: db-password --- # Source: minder/templates/hpa.yaml # Copyright 2023 Stacklok, Inc @@ -903,153 +443,6 @@ spec: type: Utilization averageUtilization: 60 --- -# Source: minder/templates/combined.yml -# Copyright 2023 Stacklok, Inc -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: mediator - labels: - # This includes a newline, so ko sees this as valid yaml - # - app.kubernetes.io/instance: minder - app.kubernetes.io/managed-by: Helm - app.kubernetes.io/name: minder - app.kubernetes.io/version: "2023-07-31" - helm.sh/chart: minder-0.1.0 - annotations: - alb.ingress.kubernetes.io/group.name: mediator-vip - alb.ingress.kubernetes.io/group.order: '200' - alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80},{"HTTPS":443}]' - alb.ingress.kubernetes.io/scheme: internet-facing - alb.ingress.kubernetes.io/ssl-redirect: "443" - alb.ingress.kubernetes.io/target-type: ip - # ALB doesn't use support cert-manager, but maybe someone else will benefit from it? - cert-manager.io/cluster-issuer: letsencrypt -spec: - # Don't set ingressClassName for now, assume default - tls: - - hosts: - - "minder-test.example.com" - secretName: mediator-tls - rules: - - host: "minder-test.example.com" - http: - paths: - # We use Prefix matches on gRPC service names because Ingress API - # doesn't support matching on Content-Type: application/grpc - - path: /grpc.reflection.v1alpha.ServerReflection - pathType: Prefix - backend: - service: - name: mediator-grpc - port: - name: grpc - - path: /mediator.v1.OAuthService - pathType: Prefix - backend: - service: - name: mediator-grpc - port: - name: grpc - - path: /mediator.v1.AuthService - pathType: Prefix - backend: - service: - name: mediator-grpc - port: - name: grpc - - path: /mediator.v1.VulnerabilitiesService - pathType: Prefix - backend: - service: - name: mediator-grpc - port: - name: grpc - - path: /mediator.v1.SecretsService - pathType: Prefix - backend: - service: - name: mediator-grpc - port: - name: grpc - - path: /mediator.v1.RepositoryService - pathType: Prefix - backend: - service: - name: mediator-grpc - port: - name: grpc - - path: /mediator.v1.BranchProtectionService - pathType: Prefix - backend: - service: - name: mediator-grpc - port: - name: grpc - - path: /mediator.v1.OrganizationService - pathType: Prefix - backend: - service: - name: mediator-grpc - port: - name: grpc - - path: /mediator.v1.GroupService - pathType: Prefix - backend: - service: - name: mediator-grpc - port: - name: grpc - - path: /mediator.v1.RoleService - pathType: Prefix - backend: - service: - name: mediator-grpc - port: - name: grpc - - path: /mediator.v1.UserService - pathType: Prefix - backend: - service: - name: mediator-grpc - port: - name: grpc - - path: /mediator.v1.PolicyService - pathType: Prefix - backend: - service: - name: mediator-grpc - port: - name: grpc - - path: /mediator.v1.KeyService - pathType: Prefix - backend: - service: - name: mediator-grpc - port: - name: grpc - - path: / - pathType: Prefix - backend: - service: - name: mediator-http - port: - name: http ---- # Source: minder/templates/ingress.yaml # Copyright 2023 Stacklok, Inc # @@ -1245,193 +638,6 @@ spec: # See the License for the specific language governing permissions and # limitations under the License. --- -# Source: minder/templates/combined.yml -# Copyright 2023 Stacklok, Inc -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# We need a separate service account for the db-update job, because -# it runs as a helm pre-install hook, and the mediator service account -# won't have been installed at that point. -apiVersion: v1 -kind: ServiceAccount -metadata: - name: db-update - annotations: - eks.amazonaws.com/role-arn: "arn:aws:iam::123456789012:role/" - helm.sh/hook-delete-policy: before-hook-creation - helm.sh/hook: pre-install,pre-upgrade - labels: - # This includes a newline, so ko sees this as valid yaml - # - app.kubernetes.io/instance: minder - app.kubernetes.io/managed-by: Helm - app.kubernetes.io/name: minder - app.kubernetes.io/version: "2023-07-31" - helm.sh/chart: minder-0.1.0 -imagePullSecrets: - - name: mediator-pull-secret ---- -# Source: minder/templates/combined.yml -apiVersion: v1 -kind: ConfigMap -metadata: - name: db-update-config - annotations: - helm.sh/hook-delete-policy: before-hook-creation - helm.sh/hook: pre-install,pre-upgrade - labels: - helm.sh/chart: 'minder-0.1.0' - app.kubernetes.io/name: mediator - app.kubernetes.io/instance: "minder" - app.kubernetes.io/version: "2023-07-31" - app.kubernetes.io/managed-by: "Helm" -data: - config.yaml: | - - # - # Copyright 2023 Stacklok, Inc. - # - # Licensed under the Apache License, Version 2.0 (the "License"); - # you may not use this file except in compliance with the License. - # You may obtain a copy of the License at - # - # http://www.apache.org/licenses/LICENSE-2.0 - # - # Unless required by applicable law or agreed to in writing, software - # distributed under the License is distributed on an "AS IS" BASIS, - # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - # See the License for the specific language governing permissions and - # limitations under the License. - - # HTTP, gRPC & metrics server configuration - http_server: - host: "127.0.0.1" - port: 8080 - grpc_server: - host: "127.0.0.1" - port: 8090 - metric_server: - host: "127.0.0.1" - port: 9090 - - logging: - level: "debug" - format: "json" - #logFile: "/var/log/minder.log" - - tracing: - enabled: false - #sample_ratio: 0.1 - - metrics: - enabled: true - - database: - dbhost: "localhost" - dbport: 5432 - dbuser: postgres - dbpass: postgres - dbname: minder - sslmode: disable - - identity: - cli: - issuer_url: http://localhost:8081 - realm: stacklok - client_id: minder-cli - server: - issuer_url: http://keycloak:8080 # Use http://localhost:8081 instead for running minder outside of docker-compose - realm: stacklok - client_id: minder-server - client_secret: secret - - # Crypto (these should be ultimately stored in a secure vault) - # The token key can be generated with: - # openssl rand -base64 32 > .ssh/token_key_passphrase - auth: - token_key: "./.ssh/token_key_passphrase" - - # Password Salting, these values are using argon2id - # https://en.wikipedia.org/wiki/Argon2 - # Argon has resistance against side-channel timing attacks and tradeoff attacks - # but it is computationally expensive. - # If this is a problematic, we could use bcrypt instead. - # https://en.wikipedia.org/wiki/Bcrypt - salt: - # The amount of memory used by the algorithm (in kibibytes). - memory: 65536 - # the amount of iterations - iterations: 50 - # degree of parallelism (number of threads) - parallelism: 4 - # the length of the salt to be used - salt_length: 16 - # the desired number of returned bytes - key_length: 32 - - # Webhook Configuration - # change example.com to an exposed IP / domain - # webhook_secret is set withing the webhook sent to github. Github then signs - # the payload sent to minder and minder verifies. - webhook-config: - external_webhook_url: "https://example.com/api/v1/webhook/github" - external_ping_url: "https://example.com/api/v1/health" - webhook_secret: "your-password" - - # OAuth2 Configuration (used during enrollment) - # These values are to be set within the GitHub OAuth2 App page - github: - client_id: "abcde....." - client_secret: "abcde....." - payload_secret: "your-password" - redirect_uri: "http://localhost:8080/api/v1/auth/callback/github" - # [*] for all events. It can also be a list such as [push,branch_protection_rule]. - # Please check complete list on https://docs.github.com/es/webhooks-and-events/webhooks/webhook-events-and-payloads - events: ["*"] - - events: - driver: postgresql - router_close_timeout: 10 - go-channel: {} - - overrides.yaml: | - - database: - dbuser: minder - dbname: minder - sslmode: disabled - - identity: - server: - issuer_url: http://keycloak-deployment.keycloak.svc:80 - realm: minder - client_id: minder-server - - github: - redirect_uri: "https://minder-test.example.com/api/v1/auth/callback/github" - - webhook-config: - external_webhook_url: "https://minder-test.example.com/api/v1/webhook/github" - external_ping_url: "https://minder-test.example.com/api/v1/health" - webhook_secret: "this-is-unused" - - events: - driver: go-channel - router_close_timeout: 30 - go-channel: - buffer_size: 200 ---- # Source: minder/templates/job.yaml apiVersion: v1 kind: ConfigMap @@ -1562,74 +768,6 @@ data: dbname: minder sslmode: disabled --- -# Source: minder/templates/combined.yml -apiVersion: batch/v1 -kind: Job -metadata: - name: db-update - annotations: - helm.sh/hook-delete-policy: hook-succeeded - helm.sh/hook: pre-install,pre-upgrade - helm.sh/hook-weight: "5" - labels: - helm.sh/chart: 'minder-0.1.0' - app.kubernetes.io/name: mediator - app.kubernetes.io/instance: "minder" - app.kubernetes.io/version: "2023-07-31" - app.kubernetes.io/managed-by: "Helm" -spec: - template: - metadata: - labels: - app: db-init - spec: - serviceAccountName: db-update - restartPolicy: Never - containers: - - name: mediator-dbinit - # restricted security context: - # https://kubernetes.io/docs/concepts/security/pod-security-standards/ - securityContext: - allowPrivilegeEscalation: false - runAsNonRoot: true - seccompProfile: - type: RuntimeDefault - capabilities: - drop: - - ALL - image: server:latest@sha256:23918f251e61748d850296d1a475ad81f2315a628cfd47864e52f10e6d3f4920 - args: - - "migrate" - - "up" - - "--yes" - - "--db-host=postgres.postgres.svc" - - "--config=/config/config.yaml" - # We use two config files, one with all the defaults, and one with - # additional override values from helm. (This is a viper feature.) - - "--config=/config/overrides.yaml" - # ko will always specify a digest, so we don't need to worry about - # CRI image caching - imagePullPolicy: IfNotPresent - resources: - requests: - cpu: 200m - memory: 200Mi - limits: - cpu: 1 - memory: 300Mi - volumeMounts: - - name: config - mountPath: /config - volumes: - - name: config - configMap: - name: db-update-config - items: - - key: config.yaml - path: config.yaml - - key: overrides.yaml - path: overrides.yaml ---- # Source: minder/templates/job.yaml apiVersion: batch/v1 kind: Job From 341d77e9a3cf09f65d99fb8f1bd04fcb80b50bec Mon Sep 17 00:00:00 2001 From: Teodor Yanev Date: Fri, 17 Nov 2023 17:57:34 +0200 Subject: [PATCH 05/10] check-unchecked-err-db --- internal/config/db.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/internal/config/db.go b/internal/config/db.go index 033f4be1d6..5614abb364 100644 --- a/internal/config/db.go +++ b/internal/config/db.go @@ -156,6 +156,9 @@ func RegisterDatabaseFlags(v *viper.Viper, flags *pflag.FlagSet) error { err = util.BindConfigFlagWithShort( v, flags, "database.sslmode", "db-sslmode", "s", "disable", "Database sslmode", flags.StringP) + if err != nil { + return err + } err = util.BindConfigFlagWithShort( v, flags, "database_queue.dbhost", "db-events-host", "Q", "localhost", "Database Events host", flags.StringP) From e8df075a33e6429bff4bec03472cd2bd6e273149 Mon Sep 17 00:00:00 2001 From: Teodor Yanev Date: Tue, 21 Nov 2023 17:02:18 +0200 Subject: [PATCH 06/10] refactoring --- cmd/server/app/serve.go | 23 +++++++++++++++-------- config/config.yaml.example | 2 +- deployment/helm/templates/deployment.yaml | 5 +++++ deployment/helm_tests/basic.yaml-out | 9 +++++++-- deployment/helm_tests/sidecar.yaml-out | 9 +++++++-- internal/config/config.go | 1 - internal/config/db.go | 12 ++++++------ internal/config/events.go | 2 ++ internal/events/eventer.go | 7 +++++-- 9 files changed, 48 insertions(+), 22 deletions(-) diff --git a/cmd/server/app/serve.go b/cmd/server/app/serve.go index 82791649eb..9ddfa68945 100644 --- a/cmd/server/app/serve.go +++ b/cmd/server/app/serve.go @@ -75,16 +75,23 @@ var serveCmd = &cobra.Command{ store := db.NewStore(dbConn) - dbConnEvents, _, err := cfg.DatabaseQueue.GetDBConnection(ctx) - if err != nil { - return fmt.Errorf("unable to connect to events database: %w", err) - } - defer func(dbConnEvents *sql.DB) { - err := dbConnEvents.Close() + // Get a separate database connection for eventing. This is done to separate concerns from the main database. + // It is used for the lifetime of the application, hence it is initialised here. + // This is not ideal from a Clean Code perspective, but it is the simplest way to + // ensure that the connection is closed when the application exits. + var dbConnEvents *sql.DB + if cfg.Events.Driver == events.SQLDriver { + dbConnEvents, _, err = cfg.Events.SQLPubSub.GetDBConnection(ctx) if err != nil { - log.Printf("error closing events database connection: %v", err) + return fmt.Errorf("unable to connect to events database: %w", err) } - }(dbConnEvents) + defer func(dbConnEvents *sql.DB) { + err := dbConnEvents.Close() + if err != nil { + log.Printf("error closing events database connection: %v", err) + } + }(dbConnEvents) + } errg, ctx := errgroup.WithContext(ctx) diff --git a/config/config.yaml.example b/config/config.yaml.example index ccf1a5d066..0aebdb0f9f 100644 --- a/config/config.yaml.example +++ b/config/config.yaml.example @@ -100,6 +100,6 @@ github: events: ["*"] events: - driver: postgresql + driver: go-channel router_close_timeout: 10 go-channel: {} diff --git a/deployment/helm/templates/deployment.yaml b/deployment/helm/templates/deployment.yaml index 85ef8c3e37..963e382c2f 100644 --- a/deployment/helm/templates/deployment.yaml +++ b/deployment/helm/templates/deployment.yaml @@ -66,6 +66,11 @@ spec: value: "{{ .Values.trusty.endpoint }}" - name: "SIGSTORE_NO_CACHE" value: "true" + - name: "MINDER_DB_PASSWORD" + valueFrom: + secretKeyRef: + name: minder-identity-secrets + key: password {{- if .Values.deploymentSettings.extraEnv }} {{- toYaml .Values.deploymentSettings.extraEnv | nindent 10 }} {{- end }} diff --git a/deployment/helm_tests/basic.yaml-out b/deployment/helm_tests/basic.yaml-out index 80cfa00f3b..539800a184 100644 --- a/deployment/helm_tests/basic.yaml-out +++ b/deployment/helm_tests/basic.yaml-out @@ -130,7 +130,7 @@ data: events: ["*"] events: - driver: postgresql + driver: go-channel router_close_timeout: 10 go-channel: {} @@ -326,6 +326,11 @@ spec: value: "http://pi.pi:8000" - name: "SIGSTORE_NO_CACHE" value: "true" + - name: "MINDER_DB_PASSWORD" + valueFrom: + secretKeyRef: + name: minder-identity-secrets + key: password # ko will always specify a digest, so we don't need to worry about # CRI image caching @@ -738,7 +743,7 @@ data: events: ["*"] events: - driver: postgresql + driver: go-channel router_close_timeout: 10 go-channel: {} diff --git a/deployment/helm_tests/sidecar.yaml-out b/deployment/helm_tests/sidecar.yaml-out index 53d999b0e9..4ce6d88d98 100644 --- a/deployment/helm_tests/sidecar.yaml-out +++ b/deployment/helm_tests/sidecar.yaml-out @@ -130,7 +130,7 @@ data: events: ["*"] events: - driver: postgresql + driver: go-channel router_close_timeout: 10 go-channel: {} @@ -326,6 +326,11 @@ spec: value: "http://pi.pi:8000" - name: "SIGSTORE_NO_CACHE" value: "true" + - name: "MINDER_DB_PASSWORD" + valueFrom: + secretKeyRef: + name: minder-identity-secrets + key: password - name: PGPASSFILE value: /secrets/db/.pgpass @@ -757,7 +762,7 @@ data: events: ["*"] events: - driver: postgresql + driver: go-channel router_close_timeout: 10 go-channel: {} diff --git a/internal/config/config.go b/internal/config/config.go index 4b5bcd72d7..2d4182cfa3 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -36,7 +36,6 @@ type Config struct { Tracing TracingConfig `mapstructure:"tracing"` Metrics MetricsConfig `mapstructure:"metrics"` Database DatabaseConfig `mapstructure:"database"` - DatabaseQueue DatabaseConfig `mapstructure:"database_queue"` Identity IdentityConfig `mapstructure:"identity"` Salt CryptoConfig `mapstructure:"salt"` Auth AuthConfig `mapstructure:"auth"` diff --git a/internal/config/db.go b/internal/config/db.go index 5614abb364..6da466e07e 100644 --- a/internal/config/db.go +++ b/internal/config/db.go @@ -161,35 +161,35 @@ func RegisterDatabaseFlags(v *viper.Viper, flags *pflag.FlagSet) error { } err = util.BindConfigFlagWithShort( - v, flags, "database_queue.dbhost", "db-events-host", "Q", "localhost", "Database Events host", flags.StringP) + v, flags, "events.sql.dbhost", "db-events-host", "Q", "localhost", "Database Events host", flags.StringP) if err != nil { return err } err = util.BindConfigFlag( - v, flags, "database_queue.dbport", "db-events-port", 5432, "Database Events port", flags.Int) + v, flags, "events.sql.dbport", "db-events-port", 5432, "Database Events port", flags.Int) if err != nil { return err } err = util.BindConfigFlagWithShort( - v, flags, "database_queue.dbuser", "db-events-user", "U", "postgres", "Database Events user", flags.StringP) + v, flags, "events.sql.dbuser", "db-events-user", "U", "postgres", "Database Events user", flags.StringP) if err != nil { return err } err = util.BindConfigFlagWithShort( - v, flags, "database_queue.dbpass", "db-events-pass", "W", "postgres", "Database Events password", flags.StringP) + v, flags, "events.sql.dbpass", "db-events-pass", "W", "postgres", "Database Events password", flags.StringP) if err != nil { return err } err = util.BindConfigFlagWithShort( - v, flags, "database_queue.dbname", "db-events-name", "N", "minder-queue", "Database Events name", flags.StringP) + v, flags, "events.sql.dbname", "db-events-name", "N", "minder-queue", "Database Events name", flags.StringP) if err != nil { return err } return util.BindConfigFlagWithShort( - v, flags, "database_queue.sslmode", "db-events-sslmode", "M", "disable", "Database Events sslmode", flags.StringP) + v, flags, "events.sql.sslmode", "db-events-sslmode", "M", "disable", "Database Events sslmode", flags.StringP) } diff --git a/internal/config/events.go b/internal/config/events.go index 46bdf8fadc..0e029b7e19 100644 --- a/internal/config/events.go +++ b/internal/config/events.go @@ -23,6 +23,8 @@ type EventConfig struct { RouterCloseTimeout int64 `mapstructure:"router_close_timeout" default:"10"` // GoChannel is the configuration for the go channel event driver GoChannel GoChannelEventConfig `mapstructure:"go-channel" default:"{}"` + // SQLPubSub is the configuration for the database event driver + SQLPubSub DatabaseConfig `mapstructure:"sql" default:"{}"` // Aggregator is the configuration for the event aggregator middleware Aggregator AggregatorConfig `mapstructure:"aggregator" default:"{}"` } diff --git a/internal/events/eventer.go b/internal/events/eventer.go index 4738f68460..39e8cd1d38 100644 --- a/internal/events/eventer.go +++ b/internal/events/eventer.go @@ -45,6 +45,9 @@ const ( ProviderTypeKey = "provider" ProviderSourceKey = "source" GithubWebhookEventTypeKey = "type" + + GoChannelDriver = "go-channel" + SQLDriver = "sql" ) const ( @@ -163,9 +166,9 @@ func Setup(ctx context.Context, cfg *config.EventConfig, db *sql.DB) (*Eventer, func instantiateDriver(driver string, cfg *config.EventConfig, db *sql.DB) (message.Publisher, message.Subscriber, error) { switch driver { - case "go-channel": + case GoChannelDriver: return buildGoChannelDriver(cfg) - case "postgresql": + case SQLDriver: return buildPostgreSQLDriver(db) default: return nil, nil, fmt.Errorf("unknown driver %s", driver) From 345af2961983cde604a89265d34abf7a06652843 Mon Sep 17 00:00:00 2001 From: Teodor Yanev Date: Tue, 21 Nov 2023 17:05:35 +0200 Subject: [PATCH 07/10] revert testing docker changes --- docker-compose.yaml | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/docker-compose.yaml b/docker-compose.yaml index 5a6d43fa82..99a6f83415 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -25,7 +25,6 @@ services: "--http-host=0.0.0.0", "--metric-host=0.0.0.0", "--db-host=postgres", - "--db-events-host=postgres_queue", "--config=/app/config.yaml", # If you don't want to store your GitHub client ID and secret in the main # config file, point to them here: @@ -61,8 +60,6 @@ services: depends_on: postgres: condition: service_healthy - postgres_queue: - condition: service_healthy keycloak: condition: service_healthy # migrate: @@ -112,23 +109,6 @@ services: retries: 5 networks: - app_net - postgres_queue: - container_name: postgres_queue_container - image: postgres:15-alpine - restart: always - environment: - POSTGRES_USER: postgres - POSTGRES_PASSWORD: postgres - POSTGRES_DB: minder-queue - networks: - - app_net - ports: - - "5433:5432" - healthcheck: - test: ["CMD-SHELL", "pg_isready"] - interval: 10s - timeout: 5s - retries: 5 keycloak: container_name: keycloak_container From 063435c141cb7f120223fac6fc8ba340b728e23e Mon Sep 17 00:00:00 2001 From: Teodor Yanev Date: Tue, 21 Nov 2023 17:22:45 +0200 Subject: [PATCH 08/10] update env var name --- deployment/helm/templates/deployment.yaml | 2 +- deployment/helm_tests/basic.yaml-out | 2 +- deployment/helm_tests/sidecar.yaml-out | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/deployment/helm/templates/deployment.yaml b/deployment/helm/templates/deployment.yaml index 963e382c2f..ff644c252e 100644 --- a/deployment/helm/templates/deployment.yaml +++ b/deployment/helm/templates/deployment.yaml @@ -66,7 +66,7 @@ spec: value: "{{ .Values.trusty.endpoint }}" - name: "SIGSTORE_NO_CACHE" value: "true" - - name: "MINDER_DB_PASSWORD" + - name: "MINDER_DB_PASS" valueFrom: secretKeyRef: name: minder-identity-secrets diff --git a/deployment/helm_tests/basic.yaml-out b/deployment/helm_tests/basic.yaml-out index 539800a184..b4d52c515d 100644 --- a/deployment/helm_tests/basic.yaml-out +++ b/deployment/helm_tests/basic.yaml-out @@ -326,7 +326,7 @@ spec: value: "http://pi.pi:8000" - name: "SIGSTORE_NO_CACHE" value: "true" - - name: "MINDER_DB_PASSWORD" + - name: "MINDER_DB_PASS" valueFrom: secretKeyRef: name: minder-identity-secrets diff --git a/deployment/helm_tests/sidecar.yaml-out b/deployment/helm_tests/sidecar.yaml-out index 4ce6d88d98..b273243b19 100644 --- a/deployment/helm_tests/sidecar.yaml-out +++ b/deployment/helm_tests/sidecar.yaml-out @@ -326,7 +326,7 @@ spec: value: "http://pi.pi:8000" - name: "SIGSTORE_NO_CACHE" value: "true" - - name: "MINDER_DB_PASSWORD" + - name: "MINDER_DB_PASS" valueFrom: secretKeyRef: name: minder-identity-secrets From 9241ff4400c50aa444d16b17c3a57586c541bf1f Mon Sep 17 00:00:00 2001 From: Juan Antonio Osorio Date: Tue, 21 Nov 2023 18:47:51 +0200 Subject: [PATCH 09/10] Do database queue connection initialization on eventer (#1708) This removes the boilerplate on other parts of the code and instead moves the responsibility to eventer. --- cmd/server/app/serve.go | 20 +------ internal/config/events.go | 9 +++- internal/controlplane/handlers_user_test.go | 4 +- internal/controlplane/server_test.go | 2 +- internal/eea/eea_test.go | 2 +- internal/engine/executor_test.go | 2 +- internal/events/eventer.go | 58 +++++++++++++++------ internal/events/eventer_test.go | 2 +- 8 files changed, 57 insertions(+), 42 deletions(-) diff --git a/cmd/server/app/serve.go b/cmd/server/app/serve.go index 9ddfa68945..1751182594 100644 --- a/cmd/server/app/serve.go +++ b/cmd/server/app/serve.go @@ -75,27 +75,9 @@ var serveCmd = &cobra.Command{ store := db.NewStore(dbConn) - // Get a separate database connection for eventing. This is done to separate concerns from the main database. - // It is used for the lifetime of the application, hence it is initialised here. - // This is not ideal from a Clean Code perspective, but it is the simplest way to - // ensure that the connection is closed when the application exits. - var dbConnEvents *sql.DB - if cfg.Events.Driver == events.SQLDriver { - dbConnEvents, _, err = cfg.Events.SQLPubSub.GetDBConnection(ctx) - if err != nil { - return fmt.Errorf("unable to connect to events database: %w", err) - } - defer func(dbConnEvents *sql.DB) { - err := dbConnEvents.Close() - if err != nil { - log.Printf("error closing events database connection: %v", err) - } - }(dbConnEvents) - } - errg, ctx := errgroup.WithContext(ctx) - evt, err := events.Setup(ctx, &cfg.Events, dbConnEvents) + evt, err := events.Setup(ctx, &cfg.Events) if err != nil { log.Printf("Failed to set up eventer: %v", err) return err diff --git a/internal/config/events.go b/internal/config/events.go index 0e029b7e19..163818cc1d 100644 --- a/internal/config/events.go +++ b/internal/config/events.go @@ -24,7 +24,7 @@ type EventConfig struct { // GoChannel is the configuration for the go channel event driver GoChannel GoChannelEventConfig `mapstructure:"go-channel" default:"{}"` // SQLPubSub is the configuration for the database event driver - SQLPubSub DatabaseConfig `mapstructure:"sql" default:"{}"` + SQLPubSub SQLEventConfig `mapstructure:"sql" default:"{}"` // Aggregator is the configuration for the event aggregator middleware Aggregator AggregatorConfig `mapstructure:"aggregator" default:"{}"` } @@ -41,6 +41,13 @@ type GoChannelEventConfig struct { BlockPublishUntilSubscriberAck bool `mapstructure:"block_publish_until_subscriber_ack" default:"false"` } +// SQLEventConfig is the configuration for the database event driver +type SQLEventConfig struct { + // InitSchema is whether or not to initialize the schema + InitSchema bool `mapstructure:"init_schema" default:"true"` + Connection DatabaseConfig `mapstructure:"connection" default:"{}"` +} + // AggregatorConfig is the configuration for the event aggregator middleware type AggregatorConfig struct { // LockInterval is the interval for locking events in seconds. diff --git a/internal/controlplane/handlers_user_test.go b/internal/controlplane/handlers_user_test.go index 6ff3d05f05..52afbda5bd 100644 --- a/internal/controlplane/handlers_user_test.go +++ b/internal/controlplane/handlers_user_test.go @@ -261,7 +261,7 @@ func TestCreateUser_gRPC(t *testing.T) { evt, err := events.Setup(context.Background(), &config.EventConfig{ Driver: "go-channel", GoChannel: config.GoChannelEventConfig{}, - }, nil) + }) require.NoError(t, err, "failed to setup eventer") server, err := NewServer(mockStore, evt, NewMetrics(), &config.Config{ Salt: config.DefaultConfigForTest().Salt, @@ -468,7 +468,7 @@ func TestDeleteUser_gRPC(t *testing.T) { evt, err := events.Setup(context.Background(), &config.EventConfig{ Driver: "go-channel", GoChannel: config.GoChannelEventConfig{}, - }, nil) + }) require.NoError(t, err, "failed to setup eventer") server, err := NewServer(mockStore, evt, NewMetrics(), &config.Config{ Salt: config.DefaultConfigForTest().Salt, diff --git a/internal/controlplane/server_test.go b/internal/controlplane/server_test.go index 72eda3278a..440af1e2c9 100644 --- a/internal/controlplane/server_test.go +++ b/internal/controlplane/server_test.go @@ -73,7 +73,7 @@ func newDefaultServer(t *testing.T, mockStore *mockdb.MockStore) *Server { evt, err := events.Setup(context.Background(), &config.EventConfig{ Driver: "go-channel", GoChannel: config.GoChannelEventConfig{}, - }, nil) + }) require.NoError(t, err, "failed to setup eventer") var c *config.Config diff --git a/internal/eea/eea_test.go b/internal/eea/eea_test.go index e60b2136d3..6534c7a27b 100644 --- a/internal/eea/eea_test.go +++ b/internal/eea/eea_test.go @@ -56,7 +56,7 @@ func TestAggregator(t *testing.T) { BufferSize: concurrentEvents, BlockPublishUntilSubscriberAck: true, }, - }, nil) + }) require.NoError(t, err) // we'll wait 2 seconds for the lock to be available diff --git a/internal/engine/executor_test.go b/internal/engine/executor_test.go index 08ef980785..8d3f7c272f 100644 --- a/internal/engine/executor_test.go +++ b/internal/engine/executor_test.go @@ -265,7 +265,7 @@ default allow = true`, GoChannel: config.GoChannelEventConfig{ BlockPublishUntilSubscriberAck: true, }, - }, nil) + }) require.NoError(t, err, "failed to setup eventer") go func() { diff --git a/internal/events/eventer.go b/internal/events/eventer.go index 39e8cd1d38..f523f19bcc 100644 --- a/internal/events/eventer.go +++ b/internal/events/eventer.go @@ -19,9 +19,9 @@ package events import ( "context" - "database/sql" "errors" "fmt" + "log" "reflect" "runtime" "time" @@ -87,6 +87,8 @@ type AggregatorMiddleware interface { AggregateMiddleware(h message.HandlerFunc) message.HandlerFunc } +type driverCloser func() + // Eventer is a wrapper over the relevant eventing objects in such // a way that they can be easily accessible and configurable. type Eventer struct { @@ -96,6 +98,8 @@ type Eventer struct { // webhookSubscriber will subscribe to the webhook topic and handle incoming events webhookSubscriber message.Subscriber // TODO: We'll have a Final publisher that will publish to the final topic + + closer driverCloser } var _ Registrar = (*Eventer)(nil) @@ -103,7 +107,7 @@ var _ message.Publisher = (*Eventer)(nil) // Setup creates an Eventer object which isolates the watermill setup code // TODO: pass in logger -func Setup(ctx context.Context, cfg *config.EventConfig, db *sql.DB) (*Eventer, error) { +func Setup(ctx context.Context, cfg *config.EventConfig) (*Eventer, error) { if cfg == nil { return nil, errors.New("event config is nil") } @@ -142,7 +146,7 @@ func Setup(ctx context.Context, cfg *config.EventConfig, db *sql.DB) (*Eventer, middleware.Recoverer, ) - pub, sub, err := instantiateDriver(cfg.Driver, cfg, db) + pub, sub, cl, err := instantiateDriver(ctx, cfg.Driver, cfg) if err != nil { return nil, fmt.Errorf("failed instantiating driver: %w", err) } @@ -161,30 +165,50 @@ func Setup(ctx context.Context, cfg *config.EventConfig, db *sql.DB) (*Eventer, router: router, webhookPublisher: pubWithMetrics, webhookSubscriber: subWithMetrics, + closer: func() { + //nolint:gosec // It's fine if there's an error as long as we close the router + pubWithMetrics.Close() + //nolint:gosec // It's fine if there's an error as long as we close the router + subWithMetrics.Close() + // driver close + cl() + }, }, nil } -func instantiateDriver(driver string, cfg *config.EventConfig, db *sql.DB) (message.Publisher, message.Subscriber, error) { +func instantiateDriver( + ctx context.Context, + driver string, + cfg *config.EventConfig, +) (message.Publisher, message.Subscriber, driverCloser, error) { switch driver { case GoChannelDriver: return buildGoChannelDriver(cfg) case SQLDriver: - return buildPostgreSQLDriver(db) + return buildPostgreSQLDriver(ctx, cfg) default: - return nil, nil, fmt.Errorf("unknown driver %s", driver) + return nil, nil, nil, fmt.Errorf("unknown driver %s", driver) } } -func buildGoChannelDriver(cfg *config.EventConfig) (message.Publisher, message.Subscriber, error) { +func buildGoChannelDriver(cfg *config.EventConfig) (message.Publisher, message.Subscriber, driverCloser, error) { pubsub := gochannel.NewGoChannel(gochannel.Config{ OutputChannelBuffer: cfg.GoChannel.BufferSize, Persistent: cfg.GoChannel.PersistEvents, }, nil) - return pubsub, pubsub, nil + return pubsub, pubsub, func() {}, nil } -func buildPostgreSQLDriver(db *sql.DB) (message.Publisher, message.Subscriber, error) { +func buildPostgreSQLDriver( + ctx context.Context, + cfg *config.EventConfig, +) (message.Publisher, message.Subscriber, driverCloser, error) { + db, _, err := cfg.SQLPubSub.Connection.GetDBConnection(ctx) + if err != nil { + return nil, nil, nil, fmt.Errorf("unable to connect to events database: %w", err) + } + publisher, err := watermillsql.NewPublisher( db, watermillsql.PublisherConfig{ @@ -194,7 +218,7 @@ func buildPostgreSQLDriver(db *sql.DB) (message.Publisher, message.Subscriber, e watermill.NewStdLogger(false, false), ) if err != nil { - return nil, nil, fmt.Errorf("failed to create SQL publisher: %w", err) + return nil, nil, nil, fmt.Errorf("failed to create SQL publisher: %w", err) } subscriber, err := watermillsql.NewSubscriber( @@ -207,18 +231,20 @@ func buildPostgreSQLDriver(db *sql.DB) (message.Publisher, message.Subscriber, e watermill.NewStdLogger(false, false), ) if err != nil { - return nil, nil, fmt.Errorf("failed to create SQL subscriber: %w", err) + return nil, nil, nil, fmt.Errorf("failed to create SQL subscriber: %w", err) } - return publisher, subscriber, nil + return publisher, subscriber, func() { + err := db.Close() + if err != nil { + log.Printf("error closing events database connection: %v", err) + } + }, nil } // Close closes the router func (e *Eventer) Close() error { - //nolint:gosec // It's fine if there's an error as long as we close the router - e.webhookPublisher.Close() - //nolint:gosec // It's fine if there's an error as long as we close the router - e.webhookSubscriber.Close() + e.closer() return e.router.Close() } diff --git a/internal/events/eventer_test.go b/internal/events/eventer_test.go index 17bc735938..8a76b8177c 100644 --- a/internal/events/eventer_test.go +++ b/internal/events/eventer_test.go @@ -126,7 +126,7 @@ func TestEventer(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) defer cancel() - eventer, err := events.Setup(ctx, driverConfig(), nil) + eventer, err := events.Setup(ctx, driverConfig()) if err != nil { t.Errorf("Setup() error = %v", err) return From 96bce223a545923f154b4880108538625875a687 Mon Sep 17 00:00:00 2001 From: Teodor Yanev Date: Tue, 21 Nov 2023 20:22:28 +0200 Subject: [PATCH 10/10] remove redundant bindings and env var Env var will be added as an extraEnv in the mediator-app.yaml in infra --- deployment/helm/templates/deployment.yaml | 5 --- deployment/helm_tests/basic.yaml-out | 5 --- deployment/helm_tests/sidecar.yaml-out | 5 --- internal/config/db.go | 38 +---------------------- 4 files changed, 1 insertion(+), 52 deletions(-) diff --git a/deployment/helm/templates/deployment.yaml b/deployment/helm/templates/deployment.yaml index ff644c252e..85ef8c3e37 100644 --- a/deployment/helm/templates/deployment.yaml +++ b/deployment/helm/templates/deployment.yaml @@ -66,11 +66,6 @@ spec: value: "{{ .Values.trusty.endpoint }}" - name: "SIGSTORE_NO_CACHE" value: "true" - - name: "MINDER_DB_PASS" - valueFrom: - secretKeyRef: - name: minder-identity-secrets - key: password {{- if .Values.deploymentSettings.extraEnv }} {{- toYaml .Values.deploymentSettings.extraEnv | nindent 10 }} {{- end }} diff --git a/deployment/helm_tests/basic.yaml-out b/deployment/helm_tests/basic.yaml-out index b4d52c515d..2e84562374 100644 --- a/deployment/helm_tests/basic.yaml-out +++ b/deployment/helm_tests/basic.yaml-out @@ -326,11 +326,6 @@ spec: value: "http://pi.pi:8000" - name: "SIGSTORE_NO_CACHE" value: "true" - - name: "MINDER_DB_PASS" - valueFrom: - secretKeyRef: - name: minder-identity-secrets - key: password # ko will always specify a digest, so we don't need to worry about # CRI image caching diff --git a/deployment/helm_tests/sidecar.yaml-out b/deployment/helm_tests/sidecar.yaml-out index b273243b19..bbd763dd64 100644 --- a/deployment/helm_tests/sidecar.yaml-out +++ b/deployment/helm_tests/sidecar.yaml-out @@ -326,11 +326,6 @@ spec: value: "http://pi.pi:8000" - name: "SIGSTORE_NO_CACHE" value: "true" - - name: "MINDER_DB_PASS" - valueFrom: - secretKeyRef: - name: minder-identity-secrets - key: password - name: PGPASSFILE value: /secrets/db/.pgpass diff --git a/internal/config/db.go b/internal/config/db.go index 6da466e07e..c00e8c4bdd 100644 --- a/internal/config/db.go +++ b/internal/config/db.go @@ -154,42 +154,6 @@ func RegisterDatabaseFlags(v *viper.Viper, flags *pflag.FlagSet) error { return err } - err = util.BindConfigFlagWithShort( - v, flags, "database.sslmode", "db-sslmode", "s", "disable", "Database sslmode", flags.StringP) - if err != nil { - return err - } - - err = util.BindConfigFlagWithShort( - v, flags, "events.sql.dbhost", "db-events-host", "Q", "localhost", "Database Events host", flags.StringP) - if err != nil { - return err - } - - err = util.BindConfigFlag( - v, flags, "events.sql.dbport", "db-events-port", 5432, "Database Events port", flags.Int) - if err != nil { - return err - } - - err = util.BindConfigFlagWithShort( - v, flags, "events.sql.dbuser", "db-events-user", "U", "postgres", "Database Events user", flags.StringP) - if err != nil { - return err - } - - err = util.BindConfigFlagWithShort( - v, flags, "events.sql.dbpass", "db-events-pass", "W", "postgres", "Database Events password", flags.StringP) - if err != nil { - return err - } - - err = util.BindConfigFlagWithShort( - v, flags, "events.sql.dbname", "db-events-name", "N", "minder-queue", "Database Events name", flags.StringP) - if err != nil { - return err - } - return util.BindConfigFlagWithShort( - v, flags, "events.sql.sslmode", "db-events-sslmode", "M", "disable", "Database Events sslmode", flags.StringP) + v, flags, "database.sslmode", "db-sslmode", "s", "disable", "Database sslmode", flags.StringP) }