From a5e72622edaad1d0cf3838d93550d8ca285ab0e3 Mon Sep 17 00:00:00 2001 From: Jonathan Hess Date: Wed, 7 Dec 2022 18:52:50 -0700 Subject: [PATCH 01/10] chore: bump version.txt to next dev version, 0.0.4-dev --- version.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version.txt b/version.txt index bcab45af..c08daabd 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -0.0.3 +0.0.4-dev From 2944831649d87e4978f13ffd5ea20630bb32621b Mon Sep 17 00:00:00 2001 From: Jonathan Hess Date: Wed, 7 Dec 2022 19:17:26 -0700 Subject: [PATCH 02/10] chore: update generated code with new dev version. --- installer/cloud-sql-proxy-operator.yaml | 2 +- installer/install.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/installer/cloud-sql-proxy-operator.yaml b/installer/cloud-sql-proxy-operator.yaml index 34887752..34d92cd3 100644 --- a/installer/cloud-sql-proxy-operator.yaml +++ b/installer/cloud-sql-proxy-operator.yaml @@ -1427,7 +1427,7 @@ spec: - --leader-elect command: - /manager - image: gcr.io/cloud-sql-connectors/cloud-sql-operator-dev/cloud-sql-proxy-operator:0.0.3 + image: gcr.io/cloud-sql-connectors/cloud-sql-operator-dev/cloud-sql-proxy-operator:0.0.4-dev livenessProbe: httpGet: path: /healthz diff --git a/installer/install.sh b/installer/install.sh index 71a837b5..0c8ccd3f 100644 --- a/installer/install.sh +++ b/installer/install.sh @@ -16,7 +16,7 @@ set -euxo # exit 1 from the script when command fails -VERSION="v0.0.3" +VERSION="v0.0.4-dev" CERT_MANAGER_VERSION="v1.9.1" if ! which kubectl ; then From 2c26d50650f815739a3b884b82a36a473c2869a5 Mon Sep 17 00:00:00 2001 From: "Jonathan Hess (he/him)" <103529393+hessjcg@users.noreply.github.com> Date: Thu, 8 Dec 2022 14:24:31 -0700 Subject: [PATCH 03/10] chore: only run Code Generation on the release-please PRs (#137) This change simplifies the github workflow that runs on release PRs. This workflow ensures that the generated code in the tagged release is consistent with version.txt. --- .github/workflows/release-please-updates.yaml | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/release-please-updates.yaml b/.github/workflows/release-please-updates.yaml index 57ef40a0..449d4104 100644 --- a/.github/workflows/release-please-updates.yaml +++ b/.github/workflows/release-please-updates.yaml @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -name: Release PRs +name: Release PR on: pull_request: types: [opened, synchronize, reopened, labeled] @@ -20,11 +20,8 @@ jobs: build: name: "Code Generation" runs-on: ubuntu-latest + if: "${{ github.actor == 'release-please[bot]' }}" steps: - - name: Print Actor - uses: actions/github-script@v6 - with: - script: console.log("The github actor is ${{github.actor}}"); - name: Setup Go uses: actions/setup-go@v3 with: @@ -35,5 +32,4 @@ jobs: ref: ${{ github.event.pull_request.head.ref }} repository: ${{ github.event.pull_request.head.repo.full_name }} - name: Generate code and commit differences - if: "${{ github.actor == 'release-please[bot]' }}" run: tools/release-pr-generate.sh From a475dd934a59469e9ef38fd9934593d7d7c3b0e6 Mon Sep 17 00:00:00 2001 From: "Jonathan Hess (he/him)" <103529393+hessjcg@users.noreply.github.com> Date: Thu, 8 Dec 2022 15:18:30 -0700 Subject: [PATCH 04/10] fix: change memory resource to match recommendations Cloud SQL Proxy (#139) The Cloud SQL Proxy project recommends 2Gi for ram. This changes the default resource requirements to match. --- internal/workload/podspec_updates.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/workload/podspec_updates.go b/internal/workload/podspec_updates.go index 08ee1a7d..540ba14e 100644 --- a/internal/workload/podspec_updates.go +++ b/internal/workload/podspec_updates.go @@ -121,7 +121,7 @@ func (e *ConfigErrorDetail) Error() string { var defaultContainerResources = corev1.ResourceRequirements{ Requests: corev1.ResourceList{ "cpu": resource.MustParse("1.0"), - "memory": resource.MustParse("1Gi"), + "memory": resource.MustParse("2Gi"), }, } From 154ba087885d01712c4a9c3bbdc8fe231b2c7315 Mon Sep 17 00:00:00 2001 From: "Jonathan Hess (he/him)" <103529393+hessjcg@users.noreply.github.com> Date: Mon, 12 Dec 2022 11:15:17 -0700 Subject: [PATCH 05/10] chore: remove '-dev' from installer and operator image url (#136) The URL for the released image version 0.0.5 now will be: cloud-sql-connectors/cloud-sql-operator/cloud-sql-proxy-operator:0.0.5 And the installer URL will now be: https://storage.googleapis.com/cloud-sql-connectors/cloud-sql-proxy-operator/v0.0.5/install.sh --- Makefile | 2 +- installer/cloud-sql-proxy-operator.yaml | 2 +- tools/publish-installer.sh | 11 ++++++++--- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/Makefile b/Makefile index f675bfbf..f2414136 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ # Global settings ## RELEASE_TAG is the public image tag for the operator -RELEASE_TAG_PATH=cloud-sql-connectors/cloud-sql-operator-dev/cloud-sql-proxy-operator:$(VERSION) +RELEASE_TAG_PATH=cloud-sql-connectors/cloud-sql-operator/cloud-sql-proxy-operator:$(VERSION) RELEASE_TAG=gcr.io/$(RELEASE_TAG_PATH) # When the environment variable IS_RELEASE_BUILD is set, the IMG will be set diff --git a/installer/cloud-sql-proxy-operator.yaml b/installer/cloud-sql-proxy-operator.yaml index 34d92cd3..24fc36e2 100644 --- a/installer/cloud-sql-proxy-operator.yaml +++ b/installer/cloud-sql-proxy-operator.yaml @@ -1427,7 +1427,7 @@ spec: - --leader-elect command: - /manager - image: gcr.io/cloud-sql-connectors/cloud-sql-operator-dev/cloud-sql-proxy-operator:0.0.4-dev + image: gcr.io/cloud-sql-connectors/cloud-sql-operator/cloud-sql-proxy-operator:0.0.4-dev livenessProbe: httpGet: path: /healthz diff --git a/tools/publish-installer.sh b/tools/publish-installer.sh index d63a62bc..7e7f2b69 100755 --- a/tools/publish-installer.sh +++ b/tools/publish-installer.sh @@ -13,15 +13,20 @@ # See the License for the specific language governing permissions and # limitations under the License. -RELEASE_PROJECT_ID="cloud-sql-connectors" -BUCKET_PATH="gs://cloud-sql-connectors/cloud-sql-proxy-operator-dev" - set -euxo SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) PROJECT_DIR=$( dirname "$SCRIPT_DIR") cd "$PROJECT_DIR" + +RELEASE_PROJECT_ID="cloud-sql-connectors" +if [[ -n "${IS_RELEASE_BUILD:-}" ]] ; then + BUCKET_PATH="gs://cloud-sql-connectors/cloud-sql-proxy-operator" +else + BUCKET_PATH="gs://cloud-sql-connectors/cloud-sql-proxy-operator-dev" +fi + ## # Release Process if [[ -n ${RELEASE_TEST_BUILD_ID:-} ]] ; then From 891d6d8ab75b6aa944f64ed9b19e20fb920c1146 Mon Sep 17 00:00:00 2001 From: "Jonathan Hess (he/him)" <103529393+hessjcg@users.noreply.github.com> Date: Mon, 12 Dec 2022 11:22:25 -0700 Subject: [PATCH 06/10] doc: Add quickstart guide to README (#126) Adds quickstart instructions to the README. This tells the user how to follow the existing Cloud SQL Quickstart on GKE guide, adding a few extra steps in the middle, to try out the operator. --- Makefile | 8 +- README.md | 84 ++++++++++--- docs/dev.md | 33 +++++ docs/examples/deployment-postgres-tcp.yaml | 115 ++++++++++++++++++ docs/quick-start.md | 135 +++++++++++++++++++++ 5 files changed, 354 insertions(+), 21 deletions(-) create mode 100644 docs/dev.md create mode 100644 docs/examples/deployment-postgres-tcp.yaml create mode 100644 docs/quick-start.md diff --git a/Makefile b/Makefile index f2414136..b0f059b8 100644 --- a/Makefile +++ b/Makefile @@ -85,7 +85,7 @@ help: ## Display this help. install_tools: remove_tools all_tools ## Installs all development tools .PHONY: generate -generate: ctrl_generate ctrl_manifests go_lint tf_lint installer reset_image add_copyright_header go_fmt yaml_fmt ## Runs code generation, format, and validation tools +generate: ctrl_generate ctrl_manifests go_lint tf_lint installer reset_image add_copyright_header update_version_in_docs go_fmt yaml_fmt ## Runs code generation, format, and validation tools .PHONY: build build: generate build_push_docker ## Builds and pushes the docker image to tag defined in envvar IMG @@ -125,6 +125,12 @@ yaml_fmt: # Automatically formats all yaml files add_copyright_header: # Add the copyright header go run github.com/google/addlicense@latest * +.PHONY: update_version_in_docs +update_version_in_docs: # Fix version numbers that appear in the markdown documentation + # Update links to the install script + find . -name '*.md' | xargs sed -i.bak -E 's|storage.googleapis.com/cloud-sql-connectors/cloud-sql-proxy-operator/[^/]+/install.sh|storage.googleapis.com/cloud-sql-connectors/cloud-sql-proxy-operator/v$(VERSION)/install.sh|g' && \ + find . -name '*.md.bak' | xargs rm -f + .PHONY: build_push_docker build_push_docker: # Build docker image with the operator. set IMG env var before running: `IMG=example.com/img:1.0 make build` @test -n "$(IMG)" || ( echo "IMG environment variable must be set to the public repo where you want to push the image" ; exit 1) diff --git a/README.md b/README.md index 8f543f47..2e1d4704 100644 --- a/README.md +++ b/README.md @@ -9,34 +9,78 @@ which specifies the Cloud SQL Auth Proxy configuration for a workload. The opera reads this resource and adds a properly configured Cloud SQL Auth Proxy container to the matching workload pods. -## Setting up the initial project -These commands will be run to initialize the kubebuilder project +## Installation +Check for the latest version on the [releases page][releases] and use the +following instructions. -``` -# Get the kubebuilder binary -mkdir -p .bin -curl -L -o .bin/kubebuilder "https://github.com/kubernetes-sigs/kubebuilder/releases/download/v3.6.0/kubebuilder_$(go env GOOS)_$(go env GOARCH)" -chmod a+x .bin/kubebuilder +Confirm that kubectl can connect to your kubernetes cluster. -# Clean up the root dir for kubebuilder -rm -rf Makefile main.go go.mod go.sum cover.out +```shell +kubectl cluster-info +``` -mkdir -p .bin/tmp/ -mv docs .bin/tmp/ -mv version.txt .bin/tmp/ +Run the following command to install the cloud sql proxy operator into +your kubernetes cluster: -rm -rf bin -.bin/kubebuilder init --owner "Google LLC" --project-name "cloud-sql-proxy-operator" --domain cloud.google.com --repo github.com/GoogleCloudPlatform/cloud-sql-proxy-operator +```shell +curl https://storage.googleapis.com/cloud-sql-connectors/cloud-sql-proxy-operator/v0.0.4-dev/install.sh | bash +``` -mv .bin/tmp/* . +Confirm that the operator is installed and running by listing its pods: +```shell +kubectl get pods -n cloud-sql-proxy-operator-system ``` -Then, to create the CRD for Workload -``` -.bin/kubebuilder create api --group cloudsql --version v1alpha1 --kind AuthProxyWorkload --controller --resource --force -.bin/kubebuilder create webhook --group cloudsql --version v1alpha1 --kind AuthProxyWorkload --defaulting --programmatic-validation -``` +## Usage + +See the [Quick Start Guide](docs/quick-start.md) for a description of basic usage. +Additional usage may be found in the [Examples](docs/examples/). + +## Frequently Asked Questions + +### Why would I use the Cloud SQL Auth Proxy Operator? + +The Cloud SQL Auth Proxy Operator gives you an easy way to add a proxy container +to your kubernetes workloads, configured correctly for production use. + +Writing the kubernetes configuration for a proxy to the production level requires +a great deal of deep kubernetes and proxy knowledge. The Cloud SQL Proxy team has +worked to encapsulate that knowledge in this operator. This saves you from having +to know all the details to configure your proxy. + +## Reference Documentation +- [Quick Start Guide](docs/quick-start.md) +- [Cloud SQL Proxy](/GoogleCloudPlatform/cloud-sql-proxy) +- [Developer Getting Started](docs/dev.md) +- [Developing End-to-End tests](docs/e2e-tests.md) +- [Contributing](docs/contributing.md) +- [Code of Conduct](docs/code-of-conduct.md) +- [Examples](docs/examples/) + +## Support policy + +### Major version lifecycle + +This project uses [semantic versioning](https://semver.org/), and uses the +following lifecycle regarding support for a major version: + +**Active** - Active versions get all new features and security fixes (that +wouldn’t otherwise introduce a breaking change). New major versions are +guaranteed to be "active" for a minimum of 1 year. +**Deprecated** - Deprecated versions continue to receive security and critical +bug fixes, but do not receive new features. Deprecated versions will be publicly +supported for 1 year. +**Unsupported** - Any major version that has been deprecated for >=1 year is +considered publicly unsupported. + +## Contributing + +Contributions are welcome. Please, see the [CONTRIBUTING][contributing] document +for details. +Please note that this project is released with a Contributor Code of Conduct. +By participating in this project you agree to abide by its terms. See +[Contributor Code of Conduct][code-of-conduct] for more information. diff --git a/docs/dev.md b/docs/dev.md new file mode 100644 index 00000000..7a5b362f --- /dev/null +++ b/docs/dev.md @@ -0,0 +1,33 @@ +# Development + +# How this project was created +This project was initially scaffolded by `kubebuilder` 3.6.0. These are the +commands initially used to set up the project. + +``` +# Get the kubebuilder binary +mkdir -p .bin +curl -L -o .bin/kubebuilder "https://github.com/kubernetes-sigs/kubebuilder/releases/download/v3.6.0/kubebuilder_$(go env GOOS)_$(go env GOARCH)" +chmod a+x .bin/kubebuilder + +# Clean up the root dir for kubebuilder +rm -rf Makefile main.go go.mod go.sum cover.out + +mkdir -p .bin/tmp/ +mv docs .bin/tmp/ +mv version.txt .bin/tmp/ + +rm -rf bin +.bin/kubebuilder init --owner "Google LLC" --project-name "cloud-sql-proxy-operator" --domain cloud.google.com --repo github.com/GoogleCloudPlatform/cloud-sql-proxy-operator + +mv .bin/tmp/* . + +``` + +Then, to create the CRD for Workload +``` +.bin/kubebuilder create api --group cloudsql --version v1alpha1 --kind AuthProxyWorkload --controller --resource --force +.bin/kubebuilder create webhook --group cloudsql --version v1alpha1 --kind AuthProxyWorkload --defaulting --programmatic-validation +``` + + diff --git a/docs/examples/deployment-postgres-tcp.yaml b/docs/examples/deployment-postgres-tcp.yaml new file mode 100644 index 00000000..3c86a0d7 --- /dev/null +++ b/docs/examples/deployment-postgres-tcp.yaml @@ -0,0 +1,115 @@ +# Copyright 2022 Google LLC. +# +# 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. + +### +# This example demonstrates how to use environment variables set by the +# Cloud SQL Proxy Operator to connect to your database. + +## +# Create an AuthProxyWorkload to hold the configuration for your +# Cloud SQL Proxy containers. + +apiVersion: cloudsql.cloud.google.com/v1alpha1 +kind: AuthProxyWorkload +metadata: + name: authproxyworkload-sample +spec: + workloadSelector: + kind: "Deployment" # Applies to a "Deployment" + name: "gke-cloud-sql-app" # named 'gke-cloud-sql-app' + instances: + - connectionString: "my-project:us-central1:instance" # from your Cloud SQL Database instance + portEnvName: "DB_PORT" # Will set an env var named 'DB_PORT' to the database port + hostEnvName: "DB_HOST" # Will set an env var named 'DB_HOST' to the proxy's host, 127.0.0.1 +--- +## +# Put the database name, username, and password into a kubernetes secret +# Update the values below as needed for your environment +# +# WARNING: Do not store passwords in a source code file. It is a bad +# way to keep your secrets safe. +# +# Instead, use kubectl to create the secret using an interactive command +# so that your password is not stored in your source code. +# +# kubectl create secret generic gke-cloud-sql-operator-demo \ +# --from-literal=DB_NAME=your_db_name \ +# --from-literal=DB_USER=your_db_user \ +# --from-literal=DB_PASS=your_db_password +# +apiVersion: v1 +kind: Secret +metadata: + name: gke-cloud-sql-operator-demo +type: Opaque +data: + DB_PASS: cGFzc3dvcmQ= # "password" + DB_NAME: cG9zdGdyZXM= # "postgres" + DB_USER: dGVzdHVzZXI= # "testuser" +--- +## +# Create a deployment for your application that uses environment variables +# set by the proxy to connect to the database. +apiVersion: apps/v1 +kind: Deployment +metadata: + name: gke-cloud-sql-app +spec: + selector: + matchLabels: + app: gke-cloud-sql-app + template: + metadata: + labels: + app: gke-cloud-sql-app + spec: + containers: + - name: gke-cloud-sql-app + image: postgres + livenessProbe: + initialDelaySeconds: 60 + periodSeconds: 30 + failureThreshold: 3 + exec: + command: ["/bin/sh", "-c", "psql --host=$DB_HOST --port=$DB_PORT --username=$DB_USER '--command=select 1' --echo-queries --dbname=$DB_NAME"] + command: + - "/bin/sh" + - "-e" + - "-c" + - "sleep 10 ; psql --host=$DB_HOST --port=$DB_PORT --username=$DB_USER '--command=select 1' --echo-queries --dbname=$DB_NAME ; sleep 3600" + env: + - name: DB_HOST + value: "set-by-operator" + - name: DB_PORT + value: "set-by-operator" + - name: DB_USER + valueFrom: + secretKeyRef: + name: gke-cloud-sql-operator-demo + key: DB_USER + - name: DB_USER + valueFrom: + secretKeyRef: + name: gke-cloud-sql-operator-demo + key: DB_USER + - name: PGPASSWORD # The env name PGPASSWORD is specific to the psql command. + valueFrom: + secretKeyRef: + name: gke-cloud-sql-operator-demo + key: DB_PASS + - name: DB_NAME + valueFrom: + secretKeyRef: + name: gke-cloud-sql-operator-demo + key: DB_NAME diff --git a/docs/quick-start.md b/docs/quick-start.md new file mode 100644 index 00000000..54ce21a4 --- /dev/null +++ b/docs/quick-start.md @@ -0,0 +1,135 @@ +# Quick Start + +Follow the instructions in the Quick Start Guide for Cloud SQL: +[Connect to Cloud SQL for PostgreSQL from Google Kubernetes Engine]( +https://cloud.google.com/sql/docs/postgres/connect-instance-kubernetes) +through the end of the step named [Build the Sample App]( +https://cloud.google.com/sql/docs/postgres/connect-instance-kubernetes#build_the_sample_app). + +Then, continue following these instructions: + +## Install the Cloud SQL Proxy Operator + +Confirm that kubectl can connect to the cluster. + +```shell +kubectl cluster-info +``` + +Run the following command to install the cloud sql proxy operator into +your kuberentes cluster: + +```shell +curl https://storage.googleapis.com/cloud-sql-connectors/cloud-sql-proxy-operator/v0.0.4-dev/install.sh | bash +``` + +Confirm that the operator is installed and running by listing its pods: + +```shell +kubectl get pods -n cloud-sql-proxy-operator-system +``` + +## Configure Cloud SQL Proxy for the quick start app + +Get the Cloud SQL instance connection name by running the gcloud sql instances describe command: + +```shell +gcloud sql instances describe quickstart-instance --format='value(connectionName)' +``` + +Create a new file named `authproxyworkload.yaml` containing the following: + +```yaml +apiVersion: cloudsql.cloud.google.com/v1alpha1 +kind: AuthProxyWorkload +metadata: + name: authproxyworkload-sample + -spec: + workloadSelector: + kind: "Deployment" + name: "gke-cloud-sql-quickstart" + instances: + - connectionString: "" + portEnvName: "DB_PORT" + hostEnvName: "INSTANCE_HOST" +``` + +Update with the Cloud SQL instance connection name +retrieved from the gcloud command on the previous step. The format is +project_id:region:instance_name. The instance connection name is also visible +in the Cloud SQL instance Overview page. + +Apply the proxy configuration to to kubernetes: + +```shell +kubectl apply -f authproxyworkload.yaml +``` + +### Deploy the sample app + +Proceed with the quickstart guide step [Deploy the sample app]( +https://cloud.google.com/sql/docs/postgres/connect-instance-kubernetes#deploy_the_sample_app). +In step 2, use this YAML as your template. + +Note that this template has only one container for the application. In the published +quickstart guide, there are two containers, one for the application, and one for the +proxy. + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: gke-cloud-sql-quickstart + -spec: + selector: + matchLabels: + app: gke-cloud-sql-app + template: + metadata: + labels: + app: gke-cloud-sql-app + spec: + serviceAccountName: + containers: + - name: gke-cloud-sql-app + # Replace with your Artifact Registry location (e.g., us-central1). + # Replace with your project ID. + image: -docker.pkg.dev//gke-cloud-sql-repo/gke-sql:latest + # This app listens on port 8080 for web traffic by default. + ports: + - containerPort: 8080 + env: + - name: PORT + value: "8080" + - name: INSTANCE_HOST + value: "set-by-proxy" + - name: DB_PORT + value: "set-by-proxy" + - name: DB_USER + valueFrom: + secretKeyRef: + name: + key: username + - name: DB_PASS + valueFrom: + secretKeyRef: + name: + key: password + - name: DB_NAME + valueFrom: + secretKeyRef: + name: + key: database +``` + +### Inspect the container managed by the proxy operator +Finally, after completing the steps in the quickstart guide, inspect the pods +for the application to see the proxy container. + +```shell +kubectl describe pods -l app=gke-cloud-sql-app +``` + +Note that there are now two containers in the pods, while there is only one +container in the deployment. The operator adds a second proxy container configured +using the settings in the `AuthProxyWorkload` resource. From 803446d4766fe556cb149725100f7e955bd8c8d0 Mon Sep 17 00:00:00 2001 From: Eno Compton Date: Mon, 12 Dec 2022 14:37:11 -0700 Subject: [PATCH 07/10] feat: add user agent to proxy invocation (#122) Add the operator version to the proxy's user agent, so that we can track how many people are using the operator. Fixes #67. Co-authored-by: Jonathan Hess --- Makefile | 4 +++- .../authproxyworkload_controller_test.go | 2 +- internal/controller/setup.go | 4 ++-- internal/testintegration/setup.go | 2 +- internal/workload/podspec_updates.go | 12 ++++++++---- internal/workload/podspec_updates_test.go | 18 ++++++++++-------- main.go | 11 ++++++----- tests/setup_test.go | 3 ++- 8 files changed, 33 insertions(+), 23 deletions(-) diff --git a/Makefile b/Makefile index b0f059b8..6f7eb5d3 100644 --- a/Makefile +++ b/Makefile @@ -222,7 +222,9 @@ E2E_KUBECTL = $(E2E_KUBECTL_ENV) $(KUBECTL) # This is the file where Terraform will write the URL to the e2e container registry E2E_DOCKER_URL_FILE :=$(PWD)/bin/gcloud-docker-repo.url E2E_DOCKER_URL=$(shell cat $(E2E_DOCKER_URL_FILE) | tr -d '\n') -E2E_PROXY_URL ?= "gcr.io/cloud-sql-connectors/cloud-sql-proxy:2.0.0-preview.2" + +# Default value in the Makefile blank. When blank tests will use workload.DefaultProxyImage +E2E_PROXY_URL ?= "" E2E_WORK_DIR=$(PWD)/bin/e2e $(E2E_WORK_DIR): diff --git a/internal/controller/authproxyworkload_controller_test.go b/internal/controller/authproxyworkload_controller_test.go index a8920e8d..7e852cb8 100644 --- a/internal/controller/authproxyworkload_controller_test.go +++ b/internal/controller/authproxyworkload_controller_test.go @@ -256,7 +256,7 @@ func reconciler(p *v1alpha1.AuthProxyWorkload, cb client.Client) (*AuthProxyWork r := &AuthProxyWorkloadReconciler{ Client: cb, recentlyDeleted: &recentlyDeletedCache{}, - updater: workload.NewUpdater(), + updater: workload.NewUpdater("cloud-sql-proxy-operator/dev"), } req := ctrl.Request{ NamespacedName: types.NamespacedName{ diff --git a/internal/controller/setup.go b/internal/controller/setup.go index 1b8b1640..5b378d88 100644 --- a/internal/controller/setup.go +++ b/internal/controller/setup.go @@ -38,8 +38,8 @@ func InitScheme(scheme *runtime.Scheme) { // SetupManagers was moved out of ../main.go to here so that it can be invoked // from the testintegration tests AND from the actual operator. -func SetupManagers(mgr manager.Manager) error { - u := workload.NewUpdater() +func SetupManagers(mgr manager.Manager, userAgent string) error { + u := workload.NewUpdater(userAgent) setupLog.Info("Configuring reconcilers...") var err error diff --git a/internal/testintegration/setup.go b/internal/testintegration/setup.go index 40af0892..a684026d 100644 --- a/internal/testintegration/setup.go +++ b/internal/testintegration/setup.go @@ -143,7 +143,7 @@ func EnvTestSetup() (func(), error) { return teardownFunc, fmt.Errorf("unable to start kuberenetes envtest %v", err) } - err = controller.SetupManagers(mgr) + err = controller.SetupManagers(mgr, "cloud-sql-proxy-operator/dev") if err != nil { return teardownFunc, fmt.Errorf("unable to start kuberenetes envtest %v", err) } diff --git a/internal/workload/podspec_updates.go b/internal/workload/podspec_updates.go index 540ba14e..63d5b8cf 100644 --- a/internal/workload/podspec_updates.go +++ b/internal/workload/podspec_updates.go @@ -34,7 +34,7 @@ import ( // package and documented here so that they appear in the godoc. These also // need to be documented in the CRD const ( - DefaultProxyImage = "gcr.io/cloud-sql-connectors/cloud-sql-proxy:2.0.0-preview.2" + DefaultProxyImage = "gcr.io/cloud-sql-connectors/cloud-sql-proxy:2.0.0-preview.4" // DefaultFirstPort is the first port number chose for an instance listener by the // proxy. @@ -49,12 +49,14 @@ var l = logf.Log.WithName("internal.workload") // Updater holds global state used while reconciling workloads. type Updater struct { + // userAgent is the userAgent of the operator + userAgent string } // NewUpdater creates a new instance of Updater with a supplier // that loads the default proxy impage from the public docker registry -func NewUpdater() *Updater { - return &Updater{} +func NewUpdater(userAgent string) *Updater { + return &Updater{userAgent: userAgent} } // ConfigError is an error with extra details about why an AuthProxyWorkload @@ -456,7 +458,9 @@ func (s *updateState) updateContainer(p *cloudsqlapi.AuthProxyWorkload, wl Workl fmt.Sprintf("--http-port=%d", healthcheckPort), "--http-address=0.0.0.0", "--health-check", - "--structured-logs") + "--structured-logs", + fmt.Sprintf("--user-agent=%v", s.updater.userAgent), + ) c.Name = ContainerName(p) c.ImagePullPolicy = "IfNotPresent" diff --git a/internal/workload/podspec_updates_test.go b/internal/workload/podspec_updates_test.go index 175b3d5a..55ef0156 100644 --- a/internal/workload/podspec_updates_test.go +++ b/internal/workload/podspec_updates_test.go @@ -137,7 +137,7 @@ func TestUpdatePodWorkload(t *testing.T) { wantContainerName = "csql-default-" + wantsName wantsInstanceName = "project:server:db" wantsInstanceArg = fmt.Sprintf("%s?port=%d", wantsInstanceName, wantsPort) - u = workload.NewUpdater() + u = workload.NewUpdater("cloud-sql-proxy-operator/dev") ) var err error @@ -192,7 +192,7 @@ func TestUpdateWorkloadFixedPort(t *testing.T) { "DB_HOST": "127.0.0.1", "DB_PORT": strconv.Itoa(int(wantsPort)), } - u = workload.NewUpdater() + u = workload.NewUpdater("cloud-sql-proxy-operator/dev") ) // Create a pod @@ -260,7 +260,7 @@ func TestWorkloadNoPortSet(t *testing.T) { "DB_PORT": strconv.Itoa(int(wantsPort)), } ) - u := workload.NewUpdater() + u := workload.NewUpdater("cloud-sql-proxy-operator/dev") // Create a pod wl := podWorkload() @@ -324,7 +324,7 @@ func TestWorkloadUnixVolume(t *testing.T) { wantWorkloadEnv = map[string]string{ "DB_SOCKET_PATH": wantsUnixDir, } - u = workload.NewUpdater() + u = workload.NewUpdater("cloud-sql-proxy-operator/dev") ) // Create a pod @@ -399,7 +399,7 @@ func TestContainerImageChanged(t *testing.T) { var ( wantsInstanceName = "project:server:db" wantImage = "custom-image:latest" - u = workload.NewUpdater() + u = workload.NewUpdater("cloud-sql-proxy-operator/dev") ) // Create a pod @@ -441,7 +441,7 @@ func TestContainerImageEmpty(t *testing.T) { var ( wantsInstanceName = "project:server:db" wantImage = workload.DefaultProxyImage - u = workload.NewUpdater() + u = workload.NewUpdater("cloud-sql-proxy-operator/dev") ) // Create a AuthProxyWorkload that matches the deployment @@ -500,7 +500,7 @@ func TestContainerReplaced(t *testing.T) { wantContainer = &corev1.Container{ Name: "sample", Image: "debian:latest", Command: []string{"/bin/bash"}, } - u = workload.NewUpdater() + u = workload.NewUpdater("cloud-sql-proxy-operator/dev") ) // Create a pod @@ -570,6 +570,8 @@ func TestProxyCLIArgs(t *testing.T) { "--structured-logs", "--health-check", fmt.Sprintf("--http-port=%d", workload.DefaultHealthCheckPort), + "--http-address=0.0.0.0", + "--user-agent=cloud-sql-proxy-operator/dev", }, }, { @@ -742,7 +744,7 @@ func TestProxyCLIArgs(t *testing.T) { for i := 0; i < len(testcases); i++ { tc := &testcases[i] t.Run(tc.desc, func(t *testing.T) { - u := workload.NewUpdater() + u := workload.NewUpdater("cloud-sql-proxy-operator/dev") // Create a pod wl := &workload.PodWorkload{Pod: &corev1.Pod{ diff --git a/main.go b/main.go index 81716cb2..ffefb148 100644 --- a/main.go +++ b/main.go @@ -32,10 +32,11 @@ import ( ) var ( - scheme = k8sruntime.NewScheme() - setupLog = ctrl.Log.WithName("setup") - version = "unknown" - buildID = "unknown" + scheme = k8sruntime.NewScheme() + setupLog = ctrl.Log.WithName("setup") + version = "unknown" + buildID = "unknown" + userAgent = "cloud-sql-proxy-operator/" + version ) func init() { @@ -86,7 +87,7 @@ func main() { os.Exit(1) } - err = controller.SetupManagers(mgr) + err = controller.SetupManagers(mgr, userAgent) if err != nil { setupLog.Error(err, "unable to set up the controllers") os.Exit(1) diff --git a/tests/setup_test.go b/tests/setup_test.go index c6854b2c..ed43a87e 100644 --- a/tests/setup_test.go +++ b/tests/setup_test.go @@ -26,6 +26,7 @@ import ( "github.com/GoogleCloudPlatform/cloud-sql-proxy-operator/internal/controller" "github.com/GoogleCloudPlatform/cloud-sql-proxy-operator/internal/testhelpers" + "github.com/GoogleCloudPlatform/cloud-sql-proxy-operator/internal/workload" "github.com/go-logr/logr" "go.uber.org/zap/zapcore" appsv1 "k8s.io/api/apps/v1" @@ -96,7 +97,7 @@ func setupTests() (func(), error) { } // Read e2e test configuration - proxyImageURL = loadValue("PROXY_IMAGE_URL", "../bin/last-proxy-image-url.txt", "gcr.io/cloud-sql-connectors/cloud-sql-proxy:2.0.0-preview.2") + proxyImageURL = loadValue("PROXY_IMAGE_URL", "../bin/last-proxy-image-url.txt", workload.DefaultProxyImage) operatorURL = loadValue("OPERATOR_IMAGE_URL", "../bin/last-gcloud-operator-url.txt", "operator:latest") testInfraPath := loadValue("TEST_INFRA_JSON", "", "../bin/testinfra.json") ti, err := loadTestInfra(testInfraPath) From 386762120f386a459c57c6e3e090e6795f53886f Mon Sep 17 00:00:00 2001 From: "Jonathan Hess (he/him)" <103529393+hessjcg@users.noreply.github.com> Date: Mon, 12 Dec 2022 14:53:32 -0700 Subject: [PATCH 08/10] fix: remove unsupported CRD fields and associated code from the project. (#141) Removes fields from the CRD and associated code that converts those fields into configuration on the proxy container. I removed fields that were unused in existing code (like FUSE), fields that were unnecessary for minimum viable use of the proxy (like telemetry args), and fields related to unix sockets, since that connection method does not yet have an automated e2e test, and proxy V2 preview 4 does not use the ?unix-socket=/path exactly as expected. --- ...l.cloud.google.com_authproxyworkloads.yaml | 63 ------- installer/cloud-sql-proxy-operator.yaml | 63 ------- .../api/v1alpha1/authproxyworkload_types.go | 127 +------------- .../api/v1alpha1/zz_generated.deepcopy.go | 85 --------- internal/workload/podspec_updates.go | 165 +++--------------- internal/workload/podspec_updates_test.go | 121 +------------ 6 files changed, 33 insertions(+), 591 deletions(-) diff --git a/config/crd/bases/cloudsql.cloud.google.com_authproxyworkloads.yaml b/config/crd/bases/cloudsql.cloud.google.com_authproxyworkloads.yaml index 233ca84a..9262663f 100644 --- a/config/crd/bases/cloudsql.cloud.google.com_authproxyworkloads.yaml +++ b/config/crd/bases/cloudsql.cloud.google.com_authproxyworkloads.yaml @@ -829,12 +829,6 @@ spec: required: - name type: object - fuseDir: - description: FUSEDir is the path where the FUSE volume will be mounted. This sets the proxy container's CLI argument `--fuse` and will mount the FUSE volume at this path on all containers in the workload. - type: string - fuseTempDir: - description: FUSETempDir is the path for the temp dir for Unix sockets created with FUSE. This sets the proxy container's CLI argument `--fuse-tmp-dir` and will mount the FUSE temp volume at this path on all containers in the workload. - type: string image: description: Image is the URL to the proxy image. Optional, by default the operator will use the latest known compatible proxy image. type: string @@ -871,51 +865,6 @@ spec: sqlAdminAPIEndpoint: description: SQLAdminAPIEndpoint is a debugging parameter that when specified will change the Google Cloud api endpoint used by the proxy. type: string - telemetry: - description: Telemetry specifies how the proxy should expose telemetry. Optional, by default - properties: - disableMetrics: - description: DisableMetrics disables Cloud Monitoring testintegration (used with telemetryProject) This sets the proxy container's CLI argument `--disable-metrics` - type: boolean - disableTraces: - description: DisableTraces disables Cloud Trace testintegration (used with telemetryProject) This sets the proxy container's CLI argument `--disable-traces` - type: boolean - httpPort: - description: HTTPPort the port for Prometheus and health check server. This sets the proxy container's CLI argument `--http-port` - format: int32 - type: integer - prometheus: - description: Prometheus Enables Prometheus HTTP endpoint /metrics on localhost This sets the proxy container's CLI argument `--prometheus` - type: boolean - prometheusNamespace: - description: PrometheusNamespace is used the provided Prometheus namespace for metrics This sets the proxy container's CLI argument `--prometheus-namespace` - type: string - quotaProject: - description: QuotaProject Specifies the project to use for Cloud SQL Admin API quota tracking. The IAM principal must have the "serviceusage.services.use" permission for the given project. See https://cloud.google.com/service-usage/docs/overview and https://cloud.google.com/storage/docs/requester-pays This sets the proxy container's CLI argument `--quota-project` - type: string - telemetryPrefix: - description: TelemetryPrefix is the prefix for Cloud Monitoring metrics. This sets the proxy container's CLI argument `--telemetry-prefix` - type: string - telemetryProject: - description: TelemetryProject enables Cloud Monitoring and Cloud Trace with the provided project ID. This sets the proxy container's CLI argument `--telemetry-project` - type: string - telemetrySampleRate: - description: TelemetrySampleRate is the Cloud Trace sample rate. A smaller number means more traces. This sets the proxy container's CLI argument `--telemetry-sample-rate` - type: integer - type: object - type: object - authentication: - description: Authentication describes how to authenticate the Auth Proxy container to Google Cloud - properties: - credentialsFileKey: - description: CredentialsFileKey The key within the kubernetes secret containing the credentials file. This sets the Cloud SQL Proxy container's CLI argument `--credentials-file` - type: string - credentialsFileSecret: - description: CredentialsFileSecret the "name" or "namespace/name" for the secret. This sets the Cloud SQL Proxy container's CLI argument `--credentials-file` - type: string - gcloudAuth: - description: GCloudAuth true when we should use the Google Cloud metadata server to authenticate. This sets the Cloud SQL Proxy container's CLI argument `--gcloud-auth` - type: boolean type: object instances: description: Instances lists the Cloud SQL instances to connect @@ -941,18 +890,6 @@ spec: privateIP: description: PrivateIP Enable connection to the Cloud SQL instance's private ip for this instance. Optional, default false. type: boolean - socketType: - description: 'SocketType declares what type of socket to create for this database. Allowed values: "tcp" or "unix"' - enum: - - tcp - - unix - type: string - unixSocketPath: - description: UnixSocketPath is the directory to mount the unix socket for this instance. When set, this directory will be mounted on all containers in the workload. - type: string - unixSocketPathEnvName: - description: UnixSocketPathEnvName the name of the environment variable containing the unix socket path Optional, when set this environment variable will be added to all containers in the workload. - type: string type: object minItems: 1 type: array diff --git a/installer/cloud-sql-proxy-operator.yaml b/installer/cloud-sql-proxy-operator.yaml index 24fc36e2..7a896ebb 100644 --- a/installer/cloud-sql-proxy-operator.yaml +++ b/installer/cloud-sql-proxy-operator.yaml @@ -847,12 +847,6 @@ spec: required: - name type: object - fuseDir: - description: FUSEDir is the path where the FUSE volume will be mounted. This sets the proxy container's CLI argument `--fuse` and will mount the FUSE volume at this path on all containers in the workload. - type: string - fuseTempDir: - description: FUSETempDir is the path for the temp dir for Unix sockets created with FUSE. This sets the proxy container's CLI argument `--fuse-tmp-dir` and will mount the FUSE temp volume at this path on all containers in the workload. - type: string image: description: Image is the URL to the proxy image. Optional, by default the operator will use the latest known compatible proxy image. type: string @@ -889,51 +883,6 @@ spec: sqlAdminAPIEndpoint: description: SQLAdminAPIEndpoint is a debugging parameter that when specified will change the Google Cloud api endpoint used by the proxy. type: string - telemetry: - description: Telemetry specifies how the proxy should expose telemetry. Optional, by default - properties: - disableMetrics: - description: DisableMetrics disables Cloud Monitoring testintegration (used with telemetryProject) This sets the proxy container's CLI argument `--disable-metrics` - type: boolean - disableTraces: - description: DisableTraces disables Cloud Trace testintegration (used with telemetryProject) This sets the proxy container's CLI argument `--disable-traces` - type: boolean - httpPort: - description: HTTPPort the port for Prometheus and health check server. This sets the proxy container's CLI argument `--http-port` - format: int32 - type: integer - prometheus: - description: Prometheus Enables Prometheus HTTP endpoint /metrics on localhost This sets the proxy container's CLI argument `--prometheus` - type: boolean - prometheusNamespace: - description: PrometheusNamespace is used the provided Prometheus namespace for metrics This sets the proxy container's CLI argument `--prometheus-namespace` - type: string - quotaProject: - description: QuotaProject Specifies the project to use for Cloud SQL Admin API quota tracking. The IAM principal must have the "serviceusage.services.use" permission for the given project. See https://cloud.google.com/service-usage/docs/overview and https://cloud.google.com/storage/docs/requester-pays This sets the proxy container's CLI argument `--quota-project` - type: string - telemetryPrefix: - description: TelemetryPrefix is the prefix for Cloud Monitoring metrics. This sets the proxy container's CLI argument `--telemetry-prefix` - type: string - telemetryProject: - description: TelemetryProject enables Cloud Monitoring and Cloud Trace with the provided project ID. This sets the proxy container's CLI argument `--telemetry-project` - type: string - telemetrySampleRate: - description: TelemetrySampleRate is the Cloud Trace sample rate. A smaller number means more traces. This sets the proxy container's CLI argument `--telemetry-sample-rate` - type: integer - type: object - type: object - authentication: - description: Authentication describes how to authenticate the Auth Proxy container to Google Cloud - properties: - credentialsFileKey: - description: CredentialsFileKey The key within the kubernetes secret containing the credentials file. This sets the Cloud SQL Proxy container's CLI argument `--credentials-file` - type: string - credentialsFileSecret: - description: CredentialsFileSecret the "name" or "namespace/name" for the secret. This sets the Cloud SQL Proxy container's CLI argument `--credentials-file` - type: string - gcloudAuth: - description: GCloudAuth true when we should use the Google Cloud metadata server to authenticate. This sets the Cloud SQL Proxy container's CLI argument `--gcloud-auth` - type: boolean type: object instances: description: Instances lists the Cloud SQL instances to connect @@ -959,18 +908,6 @@ spec: privateIP: description: PrivateIP Enable connection to the Cloud SQL instance's private ip for this instance. Optional, default false. type: boolean - socketType: - description: 'SocketType declares what type of socket to create for this database. Allowed values: "tcp" or "unix"' - enum: - - tcp - - unix - type: string - unixSocketPath: - description: UnixSocketPath is the directory to mount the unix socket for this instance. When set, this directory will be mounted on all containers in the workload. - type: string - unixSocketPathEnvName: - description: UnixSocketPathEnvName the name of the environment variable containing the unix socket path Optional, when set this environment variable will be added to all containers in the workload. - type: string type: object minItems: 1 type: array diff --git a/internal/api/v1alpha1/authproxyworkload_types.go b/internal/api/v1alpha1/authproxyworkload_types.go index d8616857..01b427ff 100644 --- a/internal/api/v1alpha1/authproxyworkload_types.go +++ b/internal/api/v1alpha1/authproxyworkload_types.go @@ -28,10 +28,6 @@ const ( // ErrorCodeEnvConflict occurs when an the environment code does not work. ErrorCodeEnvConflict = "EnvVarConflict" - // ErrorCodeFUSENotSupported occurs when any FUSE configuration is set, - // because fuse is not yet supported. - ErrorCodeFUSENotSupported = "FUSENotSupported" - // AnnotationPrefix is used as the prefix for all annotations added to a domain object. // to hold metadata related to this operator. AnnotationPrefix = "cloudsql.cloud.google.com" @@ -57,10 +53,6 @@ const ( // has properly processed the latest generation of an AuthProxyInstance ConditionWorkloadUpToDate = "WorkloadUpToDate" - // ReasonNeedsUpdate relates to condition WorkloadUpToDate, this reason is set - // when there are no workloads related to this AuthProxyWorkload resource. - ReasonNeedsUpdate = "NeedsUpdate" - // ReasonUpToDate relates to condition WorkloadUpToDate, this reason is set // when there are no workloads related to this AuthProxyWorkload resource. ReasonUpToDate = "UpToDate" @@ -72,10 +64,6 @@ type AuthProxyWorkloadSpec struct { //+kubebuilder:validation:Required Workload WorkloadSelectorSpec `json:"workloadSelector"` - // Authentication describes how to authenticate the Auth Proxy container to Google Cloud - //+kubebuilder:validation:Optional - Authentication *AuthenticationSpec `json:"authentication,omitempty"` - // AuthProxyContainer describes the resources and config for the Auth Proxy container //+kubebuilder:validation:Optional AuthProxyContainer *AuthProxyContainerSpec `json:"authProxyContainer,omitempty"` @@ -124,32 +112,6 @@ func (s *WorkloadSelectorSpec) LabelsSelector() (labels.Selector, error) { return metav1.LabelSelectorAsSelector(s.Selector) } -// AuthenticationSpec describes how the proxy should get its Google Cloud identity -// to authenticate to the Google Cloud api. The proxy can get its Google Cloud -// identity in one of two ways: -// -// 1. Using the Google Cloud metadata server, in which case the AuthenticationSpec -// would set the GCloudAuth field to true. e.g. `{gcloudAuth:true}` -// 2. Using a IAM credential key file stored in a kubernetes secret, in which -// case the AuthenticationSpec would set CredentialFileSecret and CredentialFileKey. -// e.g. `{credentialFileSecret: "default/gcloud-cred", credentialFileKey="gcloud.json"}` -type AuthenticationSpec struct { - // CredentialsFileSecret the "name" or "namespace/name" for the secret. - // This sets the Cloud SQL Proxy container's CLI argument `--credentials-file` - //+kubebuilder:validation:Optional - CredentialsFileSecret string `json:"credentialsFileSecret,omitempty"` - - // CredentialsFileKey The key within the kubernetes secret containing the credentials file. - // This sets the Cloud SQL Proxy container's CLI argument `--credentials-file` - //+kubebuilder:validation:Optional - CredentialsFileKey string `json:"credentialsFileKey,omitempty"` - - // GCloudAuth true when we should use the Google Cloud metadata server to authenticate. - // This sets the Cloud SQL Proxy container's CLI argument `--gcloud-auth` - //+kubebuilder:validation:Optional - GCloudAuth bool `json:"gcloudAuth,omitempty"` -} - // AuthProxyContainerSpec specifies configuration for the proxy container. type AuthProxyContainerSpec struct { @@ -162,11 +124,6 @@ type AuthProxyContainerSpec struct { //+kubebuilder:validation:Optional Resources *v1.ResourceRequirements `json:"resources,omitempty"` - // Telemetry specifies how the proxy should expose telemetry. - // Optional, by default - //+kubebuilder:validation:Optional - Telemetry *TelemetrySpec `json:"telemetry,omitempty"` - // MaxConnections limits the number of connections. Default value is no limit. // This sets the proxy container's CLI argument `--max-connections` //+kubebuilder:validation:Optional @@ -178,77 +135,15 @@ type AuthProxyContainerSpec struct { //+kubebuilder:validation:Optional MaxSigtermDelay *int64 `json:"maxSigtermDelay,omitempty"` - // FUSEDir is the path where the FUSE volume will be mounted. - // This sets the proxy container's CLI argument `--fuse` and - // will mount the FUSE volume at this path on all containers in the workload. - //+kubebuilder:validation:Optional - FUSEDir string `json:"fuseDir,omitempty"` - - // FUSETempDir is the path for the temp dir for Unix sockets created with FUSE. - // This sets the proxy container's CLI argument `--fuse-tmp-dir` and - // will mount the FUSE temp volume at this path on all containers in the workload. - //+kubebuilder:validation:Optional - FUSETempDir string `json:"fuseTempDir,omitempty"` - // Image is the URL to the proxy image. Optional, by default the operator - // will use the latest known compatible proxy image. - //+kubebuilder:validation:Optional - Image string `json:"image,omitempty"` - // SQLAdminAPIEndpoint is a debugging parameter that when specified will // change the Google Cloud api endpoint used by the proxy. //+kubebuilder:validation:Optional SQLAdminAPIEndpoint string `json:"sqlAdminAPIEndpoint,omitempty"` -} - -// TelemetrySpec specifies how the proxy container will expose telemetry. -type TelemetrySpec struct { - // QuotaProject Specifies the project to use for Cloud SQL Admin API quota tracking. - // The IAM principal must have the "serviceusage.services.use" permission - // for the given project. See https://cloud.google.com/service-usage/docs/overview and - // https://cloud.google.com/storage/docs/requester-pays - // This sets the proxy container's CLI argument `--quota-project` - //+kubebuilder:validation:Optional - QuotaProject *string `json:"quotaProject,omitempty"` - - // Prometheus Enables Prometheus HTTP endpoint /metrics on localhost - // This sets the proxy container's CLI argument `--prometheus` - //+kubebuilder:validation:Optional - Prometheus *bool `json:"prometheus,omitempty"` - - // PrometheusNamespace is used the provided Prometheus namespace for metrics - // This sets the proxy container's CLI argument `--prometheus-namespace` - //+kubebuilder:validation:Optional - PrometheusNamespace *string `json:"prometheusNamespace,omitempty"` - - // TelemetryProject enables Cloud Monitoring and Cloud Trace with the provided project ID. - // This sets the proxy container's CLI argument `--telemetry-project` - //+kubebuilder:validation:Optional - TelemetryProject *string `json:"telemetryProject,omitempty"` - - // TelemetryPrefix is the prefix for Cloud Monitoring metrics. - // This sets the proxy container's CLI argument `--telemetry-prefix` - //+kubebuilder:validation:Optional - TelemetryPrefix *string `json:"telemetryPrefix,omitempty"` - - // TelemetrySampleRate is the Cloud Trace sample rate. A smaller number means more traces. - // This sets the proxy container's CLI argument `--telemetry-sample-rate` - //+kubebuilder:validation:Optional - TelemetrySampleRate *int `json:"telemetrySampleRate,omitempty"` - - // HTTPPort the port for Prometheus and health check server. - // This sets the proxy container's CLI argument `--http-port` - //+kubebuilder:validation:Optional - HTTPPort *int32 `json:"httpPort,omitempty"` - // DisableTraces disables Cloud Trace testintegration (used with telemetryProject) - // This sets the proxy container's CLI argument `--disable-traces` - //+kubebuilder:validation:Optional - DisableTraces *bool `json:"disableTraces,omitempty"` - - // DisableMetrics disables Cloud Monitoring testintegration (used with telemetryProject) - // This sets the proxy container's CLI argument `--disable-metrics` + // Image is the URL to the proxy image. Optional, by default the operator + // will use the latest known compatible proxy image. //+kubebuilder:validation:Optional - DisableMetrics *bool `json:"disableMetrics,omitempty"` + Image string `json:"image,omitempty"` } // InstanceSpec describes the configuration for how the proxy should expose @@ -293,12 +188,6 @@ type InstanceSpec struct { //+kubebuilder:validation:Required ConnectionString string `json:"connectionString,omitempty"` - // SocketType declares what type of socket to create for this database. Allowed - // values: "tcp" or "unix" - //+kubebuilder:validation:Enum=tcp;unix - //+kubebuilder:validation:Optional - SocketType string `json:"socketType,omitempty"` - // Port sets the tcp port for this instance. Optional, if not set, a value will // be automatically assigned by the operator and set as an environment variable // on all containers in the workload named according to PortEnvName. The operator will choose @@ -306,11 +195,6 @@ type InstanceSpec struct { //+kubebuilder:validation:Optional Port *int32 `json:"port,omitempty"` - // UnixSocketPath is the directory to mount the unix socket for this instance. - // When set, this directory will be mounted on all containers in the workload. - //+kubebuilder:validation:Optional - UnixSocketPath string `json:"unixSocketPath,omitempty"` - // AutoIAMAuthN Enables IAM Authentication for this instance. Optional, default // false. //+kubebuilder:validation:Optional @@ -330,11 +214,6 @@ type InstanceSpec struct { // Optional, when set this environment variable will be added to all containers in the workload. //+kubebuilder:validation:Optional HostEnvName string `json:"hostEnvName,omitempty"` - - // UnixSocketPathEnvName the name of the environment variable containing the unix socket path - // Optional, when set this environment variable will be added to all containers in the workload. - //+kubebuilder:validation:Optional - UnixSocketPathEnvName string `json:"unixSocketPathEnvName,omitempty"` } // AuthProxyWorkloadStatus presents the observed state of AuthProxyWorkload using diff --git a/internal/api/v1alpha1/zz_generated.deepcopy.go b/internal/api/v1alpha1/zz_generated.deepcopy.go index 209777a7..e0340fe6 100644 --- a/internal/api/v1alpha1/zz_generated.deepcopy.go +++ b/internal/api/v1alpha1/zz_generated.deepcopy.go @@ -38,11 +38,6 @@ func (in *AuthProxyContainerSpec) DeepCopyInto(out *AuthProxyContainerSpec) { *out = new(corev1.ResourceRequirements) (*in).DeepCopyInto(*out) } - if in.Telemetry != nil { - in, out := &in.Telemetry, &out.Telemetry - *out = new(TelemetrySpec) - (*in).DeepCopyInto(*out) - } if in.MaxConnections != nil { in, out := &in.MaxConnections, &out.MaxConnections *out = new(int64) @@ -128,11 +123,6 @@ func (in *AuthProxyWorkloadList) DeepCopyObject() runtime.Object { func (in *AuthProxyWorkloadSpec) DeepCopyInto(out *AuthProxyWorkloadSpec) { *out = *in in.Workload.DeepCopyInto(&out.Workload) - if in.Authentication != nil { - in, out := &in.Authentication, &out.Authentication - *out = new(AuthenticationSpec) - **out = **in - } if in.AuthProxyContainer != nil { in, out := &in.AuthProxyContainer, &out.AuthProxyContainer *out = new(AuthProxyContainerSpec) @@ -194,21 +184,6 @@ func (in *AuthProxyWorkloadStatus) DeepCopy() *AuthProxyWorkloadStatus { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *AuthenticationSpec) DeepCopyInto(out *AuthenticationSpec) { - *out = *in -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new AuthenticationSpec. -func (in *AuthenticationSpec) DeepCopy() *AuthenticationSpec { - if in == nil { - return nil - } - out := new(AuthenticationSpec) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *InstanceSpec) DeepCopyInto(out *InstanceSpec) { *out = *in @@ -239,66 +214,6 @@ func (in *InstanceSpec) DeepCopy() *InstanceSpec { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *TelemetrySpec) DeepCopyInto(out *TelemetrySpec) { - *out = *in - if in.QuotaProject != nil { - in, out := &in.QuotaProject, &out.QuotaProject - *out = new(string) - **out = **in - } - if in.Prometheus != nil { - in, out := &in.Prometheus, &out.Prometheus - *out = new(bool) - **out = **in - } - if in.PrometheusNamespace != nil { - in, out := &in.PrometheusNamespace, &out.PrometheusNamespace - *out = new(string) - **out = **in - } - if in.TelemetryProject != nil { - in, out := &in.TelemetryProject, &out.TelemetryProject - *out = new(string) - **out = **in - } - if in.TelemetryPrefix != nil { - in, out := &in.TelemetryPrefix, &out.TelemetryPrefix - *out = new(string) - **out = **in - } - if in.TelemetrySampleRate != nil { - in, out := &in.TelemetrySampleRate, &out.TelemetrySampleRate - *out = new(int) - **out = **in - } - if in.HTTPPort != nil { - in, out := &in.HTTPPort, &out.HTTPPort - *out = new(int32) - **out = **in - } - if in.DisableTraces != nil { - in, out := &in.DisableTraces, &out.DisableTraces - *out = new(bool) - **out = **in - } - if in.DisableMetrics != nil { - in, out := &in.DisableMetrics, &out.DisableMetrics - *out = new(bool) - **out = **in - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TelemetrySpec. -func (in *TelemetrySpec) DeepCopy() *TelemetrySpec { - if in == nil { - return nil - } - out := new(TelemetrySpec) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *WorkloadSelectorSpec) DeepCopyInto(out *WorkloadSelectorSpec) { *out = *in diff --git a/internal/workload/podspec_updates.go b/internal/workload/podspec_updates.go index 63d5b8cf..b4f1118e 100644 --- a/internal/workload/podspec_updates.go +++ b/internal/workload/podspec_updates.go @@ -239,23 +239,6 @@ type workloadMods struct { Ports []*managedPort `json:"ports"` } -func (s *updateState) addVolumeMount(p *cloudsqlapi.AuthProxyWorkload, is *cloudsqlapi.InstanceSpec, m corev1.VolumeMount, v corev1.Volume) { - key := dbInst(p.Namespace, p.Name, is.ConnectionString) - vol := &managedVolume{ - Instance: key, - Volume: v, - VolumeMount: m, - } - - for i, mount := range s.mods.VolumeMounts { - if mount.Instance == key { - s.mods.VolumeMounts[i] = vol - return - } - } - s.mods.VolumeMounts = append(s.mods.VolumeMounts, vol) -} - func (s *updateState) addInUsePort(p int32, containerName string) { s.addPort(p, containerName, types.NamespacedName{}, "") } @@ -419,12 +402,6 @@ func (s *updateState) update(wl *PodWorkload, matches []*cloudsqlapi.AuthProxyWo for i := range podSpec.Containers { c := &podSpec.Containers[i] s.updateContainerEnv(c) - for _, mount := range s.mods.VolumeMounts { - c.VolumeMounts = append(c.VolumeMounts, mount.VolumeMount) - } - } - for _, mount := range s.mods.VolumeMounts { - podSpec.Volumes = append(podSpec.Volumes, mount.Volume) } // only return ConfigError if there were reported @@ -453,21 +430,15 @@ func (s *updateState) updateContainer(p *cloudsqlapi.AuthProxyWorkload, wl Workl var cliArgs []string // always enable http port healthchecks on 0.0.0.0 and structured logs - healthcheckPort := s.addHealthCheck(p, c) - cliArgs = append(cliArgs, - fmt.Sprintf("--http-port=%d", healthcheckPort), - "--http-address=0.0.0.0", - "--health-check", - "--structured-logs", - fmt.Sprintf("--user-agent=%v", s.updater.userAgent), - ) + cliArgs = s.addHealthCheck(p, c, cliArgs) + + // add the user agent + cliArgs = append(cliArgs, fmt.Sprintf("--user-agent=%v", s.updater.userAgent)) c.Name = ContainerName(p) c.ImagePullPolicy = "IfNotPresent" cliArgs = s.applyContainerSpec(p, c, cliArgs) - cliArgs = s.applyTelemetrySpec(p, cliArgs) - cliArgs = s.applyAuthenticationSpec(p, c, cliArgs) // Instances for i := range p.Spec.Instances { @@ -475,43 +446,20 @@ func (s *updateState) updateContainer(p *cloudsqlapi.AuthProxyWorkload, wl Workl params := map[string]string{} // if it is a TCP socket - if inst.SocketType == "tcp" || - (inst.SocketType == "" && inst.UnixSocketPath == "") { - port := s.useInstancePort(p, inst) - params["port"] = fmt.Sprint(port) - if inst.HostEnvName != "" { - s.addWorkloadEnvVar(p, inst, corev1.EnvVar{ - Name: inst.HostEnvName, - Value: "127.0.0.1", - }) - } - if inst.PortEnvName != "" { - s.addWorkloadEnvVar(p, inst, corev1.EnvVar{ - Name: inst.PortEnvName, - Value: fmt.Sprint(port), - }) - } - } else { - // else if it is a unix socket - params["unix-socket"] = inst.UnixSocketPath - mountName := VolumeName(p, inst, "unix") - s.addVolumeMount(p, inst, - corev1.VolumeMount{ - Name: mountName, - ReadOnly: false, - MountPath: inst.UnixSocketPath, - }, - corev1.Volume{ - Name: mountName, - VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{}}, - }) - if inst.UnixSocketPathEnvName != "" { - s.addWorkloadEnvVar(p, inst, corev1.EnvVar{ - Name: inst.UnixSocketPathEnvName, - Value: inst.UnixSocketPath, - }) - } + port := s.useInstancePort(p, inst) + params["port"] = fmt.Sprint(port) + if inst.HostEnvName != "" { + s.addWorkloadEnvVar(p, inst, corev1.EnvVar{ + Name: inst.HostEnvName, + Value: "127.0.0.1", + }) + } + if inst.PortEnvName != "" { + s.addWorkloadEnvVar(p, inst, corev1.EnvVar{ + Name: inst.PortEnvName, + Value: fmt.Sprint(port), + }) } if inst.AutoIAMAuthN != nil { @@ -558,12 +506,6 @@ func (s *updateState) applyContainerSpec(p *cloudsqlapi.AuthProxyWorkload, c *co return cliArgs } - // Fuse - if p.Spec.AuthProxyContainer.FUSEDir != "" || p.Spec.AuthProxyContainer.FUSETempDir != "" { - s.addError(cloudsqlapi.ErrorCodeFUSENotSupported, "the FUSE filesystem is not yet supported", p) - // if FUSE is used, we need to use the 'buster' or 'alpine' image. - } - if p.Spec.AuthProxyContainer.Image != "" { c.Image = p.Spec.AuthProxyContainer.Image } @@ -587,42 +529,6 @@ func (s *updateState) applyContainerSpec(p *cloudsqlapi.AuthProxyWorkload, c *co return cliArgs } -// applyTelemetrySpec applies settings from cloudsqlapi.TelemetrySpec -// to the container -func (s *updateState) applyTelemetrySpec(p *cloudsqlapi.AuthProxyWorkload, cliArgs []string) []string { - if p.Spec.AuthProxyContainer == nil || p.Spec.AuthProxyContainer.Telemetry == nil { - return cliArgs - } - tel := p.Spec.AuthProxyContainer.Telemetry - - if tel.TelemetrySampleRate != nil { - cliArgs = append(cliArgs, fmt.Sprintf("--telemetry-sample-rate=%d", *tel.TelemetrySampleRate)) - } - if tel.DisableTraces != nil && *tel.DisableTraces { - cliArgs = append(cliArgs, "--disable-traces") - } - if tel.DisableMetrics != nil && *tel.DisableMetrics { - cliArgs = append(cliArgs, "--disable-metrics") - } - if tel.PrometheusNamespace != nil || (tel.Prometheus != nil && *tel.Prometheus) { - cliArgs = append(cliArgs, "--prometheus") - } - if tel.PrometheusNamespace != nil { - cliArgs = append(cliArgs, fmt.Sprintf("--prometheus-namespace=%s", *tel.PrometheusNamespace)) - } - if tel.TelemetryProject != nil { - cliArgs = append(cliArgs, fmt.Sprintf("--telemetry-project=%s", *tel.TelemetryProject)) - } - if tel.TelemetryPrefix != nil { - cliArgs = append(cliArgs, fmt.Sprintf("--telemetry-prefix=%s", *tel.TelemetryPrefix)) - } - if tel.QuotaProject != nil { - cliArgs = append(cliArgs, fmt.Sprintf("--quota-project=%s", *tel.QuotaProject)) - } - - return cliArgs -} - // updateContainerEnv applies global container state to all containers func (s *updateState) updateContainerEnv(c *corev1.Container) { for i := 0; i < len(s.mods.EnvVars); i++ { @@ -643,22 +549,10 @@ func (s *updateState) updateContainerEnv(c *corev1.Container) { } // addHealthCheck adds the health check declaration to this workload. -func (s *updateState) addHealthCheck(p *cloudsqlapi.AuthProxyWorkload, c *corev1.Container) int32 { - var port int32 - - cs := p.Spec.AuthProxyContainer - // if the TelemetrySpec.HTTPPort is explicitly set - if cs != nil && cs.Telemetry != nil && cs.Telemetry.HTTPPort != nil { - port = *cs.Telemetry.HTTPPort - if s.isPortInUse(port) { - s.addError(cloudsqlapi.ErrorCodePortConflict, - fmt.Sprintf("telemetry httpPort %d is already in use", port), p) - } - } else { - port = DefaultHealthCheckPort - for s.isPortInUse(port) { - port++ - } +func (s *updateState) addHealthCheck(_ *cloudsqlapi.AuthProxyWorkload, c *corev1.Container, cliArgs []string) []string { + port := DefaultHealthCheckPort + for s.isPortInUse(port) { + port++ } c.StartupProbe = &corev1.Probe{ @@ -682,23 +576,18 @@ func (s *updateState) addHealthCheck(p *cloudsqlapi.AuthProxyWorkload, c *corev1 }}, PeriodSeconds: 30, } - return port + cliArgs = append(cliArgs, + fmt.Sprintf("--http-port=%d", port), + "--http-address=0.0.0.0", + "--health-check", + "--structured-logs") + return cliArgs } func (s *updateState) addError(errorCode, description string, p *cloudsqlapi.AuthProxyWorkload) { s.err.add(errorCode, description, p) } -func (s *updateState) applyAuthenticationSpec(proxy *cloudsqlapi.AuthProxyWorkload, _ *corev1.Container, args []string) []string { - if proxy.Spec.Authentication == nil { - return args - } - // Authentication needs end-to-end test in place before we can check - // that it is implemented correctly. - // --credentials-file - return args -} - func (s *updateState) defaultProxyImage() string { return DefaultProxyImage } diff --git a/internal/workload/podspec_updates_test.go b/internal/workload/podspec_updates_test.go index 55ef0156..b4db0e9e 100644 --- a/internal/workload/podspec_updates_test.go +++ b/internal/workload/podspec_updates_test.go @@ -314,87 +314,6 @@ func TestWorkloadNoPortSet(t *testing.T) { } -func TestWorkloadUnixVolume(t *testing.T) { - var ( - wantsInstanceName = "project:server:db" - wantsUnixDir = "/mnt/db" - wantContainerArgs = []string{ - fmt.Sprintf("%s?unix-socket=%s", wantsInstanceName, wantsUnixDir), - } - wantWorkloadEnv = map[string]string{ - "DB_SOCKET_PATH": wantsUnixDir, - } - u = workload.NewUpdater("cloud-sql-proxy-operator/dev") - ) - - // Create a pod - wl := podWorkload() - wl.Pod.Spec.Containers[0].Ports = - []corev1.ContainerPort{{Name: "http", ContainerPort: 8080}} - - // Create a AuthProxyWorkload that matches the deployment - csqls := []*v1alpha1.AuthProxyWorkload{ - authProxyWorkload("instance1", []v1alpha1.InstanceSpec{{ - ConnectionString: wantsInstanceName, - UnixSocketPath: wantsUnixDir, - UnixSocketPathEnvName: "DB_SOCKET_PATH", - }}), - } - - // update the containers - err := configureProxies(u, wl, csqls) - if err != nil { - t.Fatal(err) - } - - // ensure that the new container exists - if len(wl.Pod.Spec.Containers) != 2 { - t.Fatalf("got %v, wants 1. deployment containers length", len(wl.Pod.Spec.Containers)) - } - - // test that the instancename matches the new expected instance name. - csqlContainer, err := findContainer(wl, fmt.Sprintf("csql-default-%s", csqls[0].GetName())) - if err != nil { - t.Fatal(err) - } - - // test that port cli args are set correctly - assertContainerArgsContains(t, csqlContainer.Args, wantContainerArgs) - - // Test that workload has the right env vars - for wantKey, wantValue := range wantWorkloadEnv { - gotEnvVar, err := findEnvVar(wl, "busybox", wantKey) - if err != nil { - t.Error(err) - logPodSpec(t, wl) - } else if gotEnvVar.Value != wantValue { - t.Errorf("got %v, wants %v workload env var %v", gotEnvVar, wantValue, wantKey) - - } - } - - // test that Volume exists - if want, got := 1, len(wl.Pod.Spec.Volumes); want != got { - t.Fatalf("got %v, wants %v. PodSpec.Volumes", got, want) - } - - // test that Volume mount exists on busybox - busyboxContainer, err := findContainer(wl, "busybox") - if err != nil { - t.Fatal(err) - } - if want, got := 1, len(busyboxContainer.VolumeMounts); want != got { - t.Fatalf("got %v, wants %v. Busybox Container.VolumeMounts", got, want) - } - if want, got := wantsUnixDir, busyboxContainer.VolumeMounts[0].MountPath; want != got { - t.Fatalf("got %v, wants %v. Busybox Container.VolumeMounts.MountPath", got, want) - } - if want, got := wl.Pod.Spec.Volumes[0].Name, busyboxContainer.VolumeMounts[0].Name; want != got { - t.Fatalf("got %v, wants %v. Busybox Container.VolumeMounts.MountPath", got, want) - } - -} - func TestContainerImageChanged(t *testing.T) { var ( wantsInstanceName = "project:server:db" @@ -585,19 +504,6 @@ func TestProxyCLIArgs(t *testing.T) { }, wantProxyArgContains: []string{"hello:world:db?port=5000"}, }, - { - desc: "fuse not supported error", - proxySpec: v1alpha1.AuthProxyWorkloadSpec{ - Instances: []v1alpha1.InstanceSpec{{ - ConnectionString: "hello:world:db", - }}, - AuthProxyContainer: &v1alpha1.AuthProxyContainerSpec{ - FUSEDir: "/fuse/db", - }, - }, - wantProxyArgContains: []string{"hello:world:db?port=5000"}, - wantErrorCodes: []string{v1alpha1.ErrorCodeFUSENotSupported}, - }, { desc: "port implicitly set and increments", proxySpec: v1alpha1.AuthProxyWorkloadSpec{ @@ -668,23 +574,12 @@ func TestProxyCLIArgs(t *testing.T) { fmt.Sprintf("hello:world:two?port=%d&private-ip=false", workload.DefaultFirstPort+1)}, }, { - desc: "telemetry flags", + desc: "global flags", proxySpec: v1alpha1.AuthProxyWorkloadSpec{ AuthProxyContainer: &v1alpha1.AuthProxyContainerSpec{ SQLAdminAPIEndpoint: "https://example.com", - Telemetry: &v1alpha1.TelemetrySpec{ - PrometheusNamespace: ptr("hello"), - TelemetryPrefix: ptr("telprefix"), - TelemetryProject: ptr("telproject"), - TelemetrySampleRate: ptr(200), - HTTPPort: ptr(int32(9091)), - DisableTraces: &wantTrue, - DisableMetrics: &wantTrue, - Prometheus: &wantTrue, - QuotaProject: ptr("qp"), - }, - MaxConnections: ptr(int64(10)), - MaxSigtermDelay: ptr(int64(20)), + MaxConnections: ptr(int64(10)), + MaxSigtermDelay: ptr(int64(20)), }, Instances: []v1alpha1.InstanceSpec{{ ConnectionString: "hello:world:one", @@ -693,16 +588,6 @@ func TestProxyCLIArgs(t *testing.T) { wantProxyArgContains: []string{ fmt.Sprintf("hello:world:one?port=%d", workload.DefaultFirstPort), "--sqladmin-api-endpoint=https://example.com", - "--telemetry-sample-rate=200", - "--prometheus-namespace=hello", - "--telemetry-project=telproject", - "--telemetry-prefix=telprefix", - "--http-port=9091", - "--health-check", - "--disable-traces", - "--disable-metrics", - "--prometheus", - "--quota-project=qp", "--max-connections=10", "--max-sigterm-delay=20", }, From 977266db5b0578d0af103bb1ddbf2cf36c5e1738 Mon Sep 17 00:00:00 2001 From: "Jonathan Hess (he/him)" <103529393+hessjcg@users.noreply.github.com> Date: Tue, 13 Dec 2022 08:06:26 -0700 Subject: [PATCH 09/10] test: add a test to cover resource requirements from spec. (#140) While pruning fields from the CRD, I found some uncovered code that needed a test. This adds a test case to make sure that when a customer sets the proxy container resource requirements in the CRD, the values are actually set on the container. --- internal/workload/podspec_updates_test.go | 47 +++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/internal/workload/podspec_updates_test.go b/internal/workload/podspec_updates_test.go index b4db0e9e..813fc06f 100644 --- a/internal/workload/podspec_updates_test.go +++ b/internal/workload/podspec_updates_test.go @@ -23,6 +23,7 @@ import ( "github.com/GoogleCloudPlatform/cloud-sql-proxy-operator/internal/api/v1alpha1" "github.com/GoogleCloudPlatform/cloud-sql-proxy-operator/internal/workload" corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "sigs.k8s.io/yaml" ) @@ -463,6 +464,52 @@ func ptr[T int | int32 | int64 | string](i T) *T { return &i } +func TestResourcesFromSpec(t *testing.T) { + var ( + wantsInstanceName = "project:server:db" + wantResources = &corev1.ResourceRequirements{ + Requests: corev1.ResourceList{ + "cpu": resource.MustParse("4.0"), + "memory": resource.MustParse("4Gi"), + }, + } + + u = workload.NewUpdater("cloud-sql-proxy-operator/dev") + ) + + // Create a pod + wl := podWorkload() + wl.Pod.Spec.Containers[0].Ports = + []corev1.ContainerPort{{Name: "http", ContainerPort: 8080}} + + // Create a AuthProxyWorkload that matches the deployment + csqls := []*v1alpha1.AuthProxyWorkload{simpleAuthProxy("instance1", wantsInstanceName)} + csqls[0].Spec.AuthProxyContainer = &v1alpha1.AuthProxyContainerSpec{Resources: wantResources} + + // update the containers + err := configureProxies(u, wl, csqls) + if err != nil { + t.Fatal(err) + } + + // ensure that the new container exists + if len(wl.Pod.Spec.Containers) != 2 { + t.Fatalf("got %v, wants 1. deployment containers length", len(wl.Pod.Spec.Containers)) + } + + // test that the instancename matches the new expected instance name. + csqlContainer, err := findContainer(wl, fmt.Sprintf("csql-default-%s", csqls[0].GetName())) + if err != nil { + t.Fatal(err) + } + + // test that resources was set + if !reflect.DeepEqual(csqlContainer.Resources.Requests, wantResources.Requests) { + t.Errorf("got %v, want %v for proxy container command", csqlContainer.Resources.Requests, wantResources.Requests) + } + +} + func TestProxyCLIArgs(t *testing.T) { type testParam struct { desc string From 4a88d0d4a33b808e064574b2f346b883abc532ba Mon Sep 17 00:00:00 2001 From: "release-please[bot]" <55107282+release-please[bot]@users.noreply.github.com> Date: Tue, 13 Dec 2022 10:01:10 -0700 Subject: [PATCH 10/10] chore(main): release 0.1.0 (#142) Co-authored-by: release-please[bot] <55107282+release-please[bot]@users.noreply.github.com> Co-authored-by: Release PR Generate Bot action release-please[bot] --- CHANGELOG.md | 13 +++++++++++++ README.md | 2 +- docs/quick-start.md | 2 +- installer/cloud-sql-proxy-operator.yaml | 2 +- installer/install.sh | 2 +- version.txt | 2 +- 6 files changed, 18 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 87c5af30..665349c1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## [0.1.0](https://github.com/GoogleCloudPlatform/cloud-sql-proxy-operator/compare/v0.0.3...v0.1.0) (2022-12-13) + + +### Features + +* add user agent to proxy invocation ([#122](https://github.com/GoogleCloudPlatform/cloud-sql-proxy-operator/issues/122)) ([803446d](https://github.com/GoogleCloudPlatform/cloud-sql-proxy-operator/commit/803446d4766fe556cb149725100f7e955bd8c8d0)) + + +### Bug Fixes + +* change memory resource to match recommendations Cloud SQL Proxy ([#139](https://github.com/GoogleCloudPlatform/cloud-sql-proxy-operator/issues/139)) ([a475dd9](https://github.com/GoogleCloudPlatform/cloud-sql-proxy-operator/commit/a475dd934a59469e9ef38fd9934593d7d7c3b0e6)) +* remove unsupported CRD fields and associated code from the project. ([#141](https://github.com/GoogleCloudPlatform/cloud-sql-proxy-operator/issues/141)) ([3867621](https://github.com/GoogleCloudPlatform/cloud-sql-proxy-operator/commit/386762120f386a459c57c6e3e090e6795f53886f)) + ## [0.0.3](https://github.com/GoogleCloudPlatform/cloud-sql-proxy-operator/compare/v0.0.1...v0.0.3) (2022-12-07) diff --git a/README.md b/README.md index 2e1d4704..86bcb4cb 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ Run the following command to install the cloud sql proxy operator into your kubernetes cluster: ```shell -curl https://storage.googleapis.com/cloud-sql-connectors/cloud-sql-proxy-operator/v0.0.4-dev/install.sh | bash +curl https://storage.googleapis.com/cloud-sql-connectors/cloud-sql-proxy-operator/v0.1.0/install.sh | bash ``` Confirm that the operator is installed and running by listing its pods: diff --git a/docs/quick-start.md b/docs/quick-start.md index 54ce21a4..ed92f820 100644 --- a/docs/quick-start.md +++ b/docs/quick-start.md @@ -20,7 +20,7 @@ Run the following command to install the cloud sql proxy operator into your kuberentes cluster: ```shell -curl https://storage.googleapis.com/cloud-sql-connectors/cloud-sql-proxy-operator/v0.0.4-dev/install.sh | bash +curl https://storage.googleapis.com/cloud-sql-connectors/cloud-sql-proxy-operator/v0.1.0/install.sh | bash ``` Confirm that the operator is installed and running by listing its pods: diff --git a/installer/cloud-sql-proxy-operator.yaml b/installer/cloud-sql-proxy-operator.yaml index 7a896ebb..13da76a2 100644 --- a/installer/cloud-sql-proxy-operator.yaml +++ b/installer/cloud-sql-proxy-operator.yaml @@ -1364,7 +1364,7 @@ spec: - --leader-elect command: - /manager - image: gcr.io/cloud-sql-connectors/cloud-sql-operator/cloud-sql-proxy-operator:0.0.4-dev + image: gcr.io/cloud-sql-connectors/cloud-sql-operator/cloud-sql-proxy-operator:0.1.0 livenessProbe: httpGet: path: /healthz diff --git a/installer/install.sh b/installer/install.sh index 0c8ccd3f..a8439efe 100644 --- a/installer/install.sh +++ b/installer/install.sh @@ -16,7 +16,7 @@ set -euxo # exit 1 from the script when command fails -VERSION="v0.0.4-dev" +VERSION="v0.1.0" CERT_MANAGER_VERSION="v1.9.1" if ! which kubectl ; then diff --git a/version.txt b/version.txt index c08daabd..6e8bf73a 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -0.0.4-dev +0.1.0