From a3c2f5256c9cb12eb703eb623022454aa9f73ed2 Mon Sep 17 00:00:00 2001 From: Milan Pavlik Date: Wed, 11 Jan 2023 13:56:58 +0000 Subject: [PATCH] [openfga] Configure cloud-sql-proxy sidecar --- .../pkg/components/openfga/constants.go | 2 + .../pkg/components/openfga/deployment.go | 186 ++++++++++++------ .../config/v1/experimental/experimental.go | 9 + 3 files changed, 132 insertions(+), 65 deletions(-) diff --git a/install/installer/pkg/components/openfga/constants.go b/install/installer/pkg/components/openfga/constants.go index c66bda1a0c90f6..75064805001019 100644 --- a/install/installer/pkg/components/openfga/constants.go +++ b/install/installer/pkg/components/openfga/constants.go @@ -21,4 +21,6 @@ const ( ImageTag = "v0.3.1" ContainerName = "openfga" + + CloudSQLProxyPort = 3306 ) diff --git a/install/installer/pkg/components/openfga/deployment.go b/install/installer/pkg/components/openfga/deployment.go index 34c8263ec11d40..40e1e934e21b37 100644 --- a/install/installer/pkg/components/openfga/deployment.go +++ b/install/installer/pkg/components/openfga/deployment.go @@ -5,8 +5,11 @@ package openfga import ( + "fmt" + "github.com/gitpod-io/gitpod/installer/pkg/cluster" "github.com/gitpod-io/gitpod/installer/pkg/common" + "github.com/gitpod-io/gitpod/installer/pkg/components/database/cloudsql" appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" @@ -20,6 +23,122 @@ import ( func deployment(ctx *common.RenderContext) ([]runtime.Object, error) { labels := common.CustomizeLabel(ctx, Component, common.TypeMetaDeployment) + cfg := getExperimentalOpenFGAConfig(ctx) + if cfg == nil || !cfg.Enabled { + return nil, nil + } + + containers := []corev1.Container{ + { + Name: ContainerName, + Image: ctx.ImageName(common.ThirdPartyContainerRepo(ctx.Config.Repository, RegistryRepo), RegistryImage, ImageTag), + ImagePullPolicy: corev1.PullIfNotPresent, + Args: []string{ + "run", + "--log-format=json", + "--log-level=warn", + }, + Env: common.CustomizeEnvvar(ctx, Component, common.MergeEnv( + common.DefaultEnv(&ctx.Config), + )), + Ports: []corev1.ContainerPort{ + { + ContainerPort: ContainerGRPCPort, + Name: ContainerGRPCName, + Protocol: *common.TCPProtocol, + }, + { + ContainerPort: ContainerHTTPPort, + Name: ContainerHTTPName, + Protocol: *common.TCPProtocol, + }, + { + ContainerPort: ContainerPlaygroundPort, + Name: ContainerPlaygroundName, + Protocol: *common.TCPProtocol, + }, + }, + Resources: common.ResourceRequirements(ctx, Component, ContainerName, corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + "cpu": resource.MustParse("1m"), + "memory": resource.MustParse("30Mi"), + }, + }), + SecurityContext: &corev1.SecurityContext{ + RunAsGroup: pointer.Int64(65532), + RunAsNonRoot: pointer.Bool(true), + RunAsUser: pointer.Int64(65532), + }, + LivenessProbe: &corev1.Probe{ + ProbeHandler: corev1.ProbeHandler{ + HTTPGet: &corev1.HTTPGetAction{ + Path: "/healthz", + Port: intstr.IntOrString{IntVal: ContainerHTTPPort}, + Scheme: corev1.URISchemeHTTP, + }, + }, + FailureThreshold: 3, + SuccessThreshold: 1, + TimeoutSeconds: 1, + }, + ReadinessProbe: &corev1.Probe{ + ProbeHandler: corev1.ProbeHandler{ + HTTPGet: &corev1.HTTPGetAction{ + Path: "/healthz", + Port: intstr.IntOrString{IntVal: ContainerHTTPPort}, + Scheme: corev1.URISchemeHTTP, + }, + }, + FailureThreshold: 3, + SuccessThreshold: 1, + TimeoutSeconds: 1, + }, + }, + } + + var volumes []corev1.Volume + + if cfg.CloudSQL != nil { + containers = append(containers, corev1.Container{ + Name: "cloud-sql-proxy", + SecurityContext: &corev1.SecurityContext{ + Privileged: pointer.Bool(false), + RunAsNonRoot: pointer.Bool(false), + AllowPrivilegeEscalation: pointer.Bool(false), + }, + Image: ctx.ImageName(cloudsql.ImageRepo, cloudsql.ImageName, cloudsql.ImageVersion), + Command: []string{ + "/cloud_sql_proxy", + "-dir=/cloudsql", + fmt.Sprintf("-instances=%s=tcp:0.0.0.0:%d", cfg.CloudSQL.Instance, CloudSQLProxyPort), + "-credential_file=/credentials/credentials.json", + }, + Ports: []corev1.ContainerPort{{ + ContainerPort: CloudSQLProxyPort, + }}, + VolumeMounts: []corev1.VolumeMount{{ + MountPath: "/cloudsql", + Name: "cloudsql", + }, { + MountPath: "/credentials", + Name: "gcloud-sql-token", + }}, + Env: common.CustomizeEnvvar(ctx, Component, []corev1.EnvVar{}), + }) + + volumes = append(volumes, []corev1.Volume{ + { + Name: "cloudsql", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{}}, + }, { + Name: "gcloud-sql-token", + VolumeSource: corev1.VolumeSource{Secret: &corev1.SecretVolumeSource{ + SecretName: cfg.CloudSQL.ProxySecretRef, + }}, + }, + }...) + } + return []runtime.Object{ &appsv1.Deployment{ TypeMeta: common.TypeMetaDeployment, @@ -51,71 +170,8 @@ func deployment(ctx *common.RenderContext) ([]runtime.Object, error) { SecurityContext: &corev1.PodSecurityContext{ RunAsNonRoot: pointer.Bool(false), }, - Containers: []corev1.Container{{ - Name: ContainerName, - Image: ctx.ImageName(common.ThirdPartyContainerRepo(ctx.Config.Repository, RegistryRepo), RegistryImage, ImageTag), - ImagePullPolicy: corev1.PullIfNotPresent, - Args: []string{ - "run", - "--log-format=json", - "--log-level=warn", - }, - Env: common.CustomizeEnvvar(ctx, Component, common.MergeEnv( - common.DefaultEnv(&ctx.Config), - )), - Ports: []corev1.ContainerPort{ - { - ContainerPort: ContainerGRPCPort, - Name: ContainerGRPCName, - Protocol: *common.TCPProtocol, - }, - { - ContainerPort: ContainerHTTPPort, - Name: ContainerHTTPName, - Protocol: *common.TCPProtocol, - }, - { - ContainerPort: ContainerPlaygroundPort, - Name: ContainerPlaygroundName, - Protocol: *common.TCPProtocol, - }, - }, - Resources: common.ResourceRequirements(ctx, Component, ContainerName, corev1.ResourceRequirements{ - Requests: corev1.ResourceList{ - "cpu": resource.MustParse("1m"), - "memory": resource.MustParse("30Mi"), - }, - }), - SecurityContext: &corev1.SecurityContext{ - RunAsGroup: pointer.Int64(65532), - RunAsNonRoot: pointer.Bool(true), - RunAsUser: pointer.Int64(65532), - }, - LivenessProbe: &corev1.Probe{ - ProbeHandler: corev1.ProbeHandler{ - HTTPGet: &corev1.HTTPGetAction{ - Path: "/healthz", - Port: intstr.IntOrString{IntVal: ContainerHTTPPort}, - Scheme: corev1.URISchemeHTTP, - }, - }, - FailureThreshold: 3, - SuccessThreshold: 1, - TimeoutSeconds: 1, - }, - ReadinessProbe: &corev1.Probe{ - ProbeHandler: corev1.ProbeHandler{ - HTTPGet: &corev1.HTTPGetAction{ - Path: "/healthz", - Port: intstr.IntOrString{IntVal: ContainerHTTPPort}, - Scheme: corev1.URISchemeHTTP, - }, - }, - FailureThreshold: 3, - SuccessThreshold: 1, - TimeoutSeconds: 1, - }, - }}, + Containers: containers, + Volumes: volumes, }, }, }, diff --git a/install/installer/pkg/config/v1/experimental/experimental.go b/install/installer/pkg/config/v1/experimental/experimental.go index 42d298649106d7..2ab2c8052ca8a1 100644 --- a/install/installer/pkg/config/v1/experimental/experimental.go +++ b/install/installer/pkg/config/v1/experimental/experimental.go @@ -190,6 +190,15 @@ type IAMConfig struct { type OpenFGAConfig struct { Enabled bool `json:"enabled"` + + CloudSQL *struct { + Instance string `json:"instance"` + Database string `json:"database"` + // Credentials for CloudSQL proxy to authenticate with GCP + ProxySecretRef string `json:"proxySecretRef"` + // Username/Password to authenticate with the database + DatabaseSecretRef string `json:"databaseSecretRef"` + } `json:"cloudSql,omitempty"` } type WebAppConfig struct {