From 909ac671517ebabc37014a5e3175a3fdebf624fd Mon Sep 17 00:00:00 2001 From: Nitin Agarwal Date: Sat, 15 Oct 2022 00:12:14 +0000 Subject: [PATCH 1/3] Added cloud-spanner emulator add-on. --- cmd/minikube/cmd/config/addons_list_test.go | 2 +- deploy/addons/assets.go | 4 ++ deploy/addons/cloud-spanner/deployment.yaml | 45 ++++++++++++++++ pkg/addons/config.go | 5 ++ pkg/minikube/assets/addons.go | 7 +++ .../en/docs/handbook/addons/cloud-spanner.md | 53 +++++++++++++++++++ 6 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 deploy/addons/cloud-spanner/deployment.yaml create mode 100644 site/content/en/docs/handbook/addons/cloud-spanner.md diff --git a/cmd/minikube/cmd/config/addons_list_test.go b/cmd/minikube/cmd/config/addons_list_test.go index 1398508c2d60..f58b24439c5f 100644 --- a/cmd/minikube/cmd/config/addons_list_test.go +++ b/cmd/minikube/cmd/config/addons_list_test.go @@ -77,7 +77,7 @@ func TestAddonsList(t *testing.T) { Ambassador *interface{} `json:"ambassador"` } - b := make([]byte, 571) + b := make([]byte, 590) r, w, err := os.Pipe() if err != nil { t.Fatalf("failed to create pipe: %v", err) diff --git a/deploy/addons/assets.go b/deploy/addons/assets.go index 209f0560d4f4..4ea4b5baf486 100644 --- a/deploy/addons/assets.go +++ b/deploy/addons/assets.go @@ -151,4 +151,8 @@ var ( // HeadlampAssets assets for headlamp addon //go:embed headlamp/*.yaml headlamp/*.tmpl HeadlampAssets embed.FS + + // CloudSpanner assets for cloud-spanner addon + //go:embed cloud-spanner/*.yaml + CloudSpanner embed.FS ) diff --git a/deploy/addons/cloud-spanner/deployment.yaml b/deploy/addons/cloud-spanner/deployment.yaml new file mode 100644 index 000000000000..c95aca0343e0 --- /dev/null +++ b/deploy/addons/cloud-spanner/deployment.yaml @@ -0,0 +1,45 @@ +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: cloud-spanner-emulator + labels: + app: cloud-spanner-emulator + gcp-auth-skip-secret: "true" + kubernetes.io/minikube-addons-endpoint: cloud-spanner +spec: + replicas: 1 + selector: + matchLabels: + app: cloud-spanner-emulator + template: + metadata: + labels: + app: cloud-spanner-emulator + spec: + containers: + - name: cloud-spanner-emulator + image: gcr.io/cloud-spanner-emulator/emulator:latest + imagePullPolicy: IfNotPresent + ports: + - containerPort: 9020 + name: http + - containerPort: 9010 + name: grpc + +--- +apiVersion: v1 +kind: Service +metadata: + name: cloud-spanner-emulator + labels: + app: cloud-spanner-emulator +spec: + type: NodePort + ports: + - port: 9020 + name: http + - port: 9010 + name: grpc + selector: + app: cloud-spanner-emulator diff --git a/pkg/addons/config.go b/pkg/addons/config.go index 6aba241a0065..5e74c34606f8 100644 --- a/pkg/addons/config.go +++ b/pkg/addons/config.go @@ -207,4 +207,9 @@ var Addons = []*Addon{ set: SetBool, callbacks: []setFn{EnableOrDisableAddon}, }, + { + name: "cloud-spanner", + set: SetBool, + callbacks: []setFn{EnableOrDisableAddon}, + }, } diff --git a/pkg/minikube/assets/addons.go b/pkg/minikube/assets/addons.go index 915d497ffeaa..10659a9384d7 100644 --- a/pkg/minikube/assets/addons.go +++ b/pkg/minikube/assets/addons.go @@ -742,6 +742,13 @@ var Addons = map[string]*Addon{ map[string]string{ "Headlamp": "ghcr.io", }), + "cloud-spanner": NewAddon([]*BinAsset{ + MustBinAsset(addons.CloudSpanner, "cloud-spanner/deployment.yaml", vmpath.GuestAddonsDir, "deployment.yaml", "6040"), + }, false, "cloud-spanner", "Google", "", "https://minikube.sigs.k8s.io/docs/handbook/addons/cloud-spanner/", map[string]string{ + "CloudSpannerAddon": "cloud-spanner-emulator/emulator", + }, map[string]string{ + "CloudSpannerAddon": "gcr.io", + }), } // parseMapString creates a map based on `str` which is encoded as =,=,... diff --git a/site/content/en/docs/handbook/addons/cloud-spanner.md b/site/content/en/docs/handbook/addons/cloud-spanner.md new file mode 100644 index 000000000000..14489d3d8228 --- /dev/null +++ b/site/content/en/docs/handbook/addons/cloud-spanner.md @@ -0,0 +1,53 @@ +--- +title: "Using Cloud Spanner Addon" +linkTitle: "Cloud Spanner" +weight: 1 +date: 2022-10-14 +--- + +## Cloud Spanner Addon + +[Cloud Spanner](https://cloud.google.com/spanner) is a fully managed relational database. The Cloud Spanner addon provides a local emulator to test your local application without incurring the cost of an actual spanner instance. + +### Enable Cloud Spanner on minikube + +To enable this addon, simply run: +```shell script +minikube addons enable cloud-spanner +``` + +### Cloud Spanner Endpoints +Cloud Spanner provides two different ports, HTTP and GRPC. List Cloud Spanner emulator urls by running: +``` shell +minikube service cloud-spanner-emulator + +####################Sample Output######################### +|-----------|------------------------|-------------|---------------------------| +| NAMESPACE | NAME | TARGET PORT | URL | +|-----------|------------------------|-------------|---------------------------| +| default | cloud-spanner-emulator | http/9020 | http://192.168.49.2:30233 | +| | | grpc/9010 | http://192.168.49.2:30556 | +|-----------|------------------------|-------------|---------------------------| +[default cloud-spanner-emulator http/9020 +grpc/9010 http://192.168.49.2:30233 +http://192.168.49.2:30556] +``` + +### Using Cloud Spanner within a cluster +Cloud Spanner emulator can be used via endpoint `cloud-spanner-emulator:9020` for http clients and `cloud-spanner-emulator:9010` for grpc clients respectively. If you're using the standard client library for Cloud Spanner then set `SPANNER_EMULATOR_HOST` to the GRPC endpoint `cloud-spanner-emulator:9010`. + +### Testing installation + +```shell script +kubectl get pods -n cloud-spanner-emulator +``` + +If everything went well, there should be no errors about Cloud Spanner's installation in your minikube cluster. + +### Disable Cloud Spanner + +To disable this addon, simply run: + +```shell script +minikube addons disable cloud-spanner +``` \ No newline at end of file From 3536f0fb39c0c03bbe24920249487eeb973ad578 Mon Sep 17 00:00:00 2001 From: Steven Powell Date: Wed, 26 Oct 2022 10:27:47 -0700 Subject: [PATCH 2/3] add integration test for cloud-spanner addon --- site/content/en/docs/contrib/tests.en.md | 3 +++ test/integration/addons_test.go | 22 +++++++++++++++++++++- 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/site/content/en/docs/contrib/tests.en.md b/site/content/en/docs/contrib/tests.en.md index 5b375c64d514..b0913417341b 100644 --- a/site/content/en/docs/contrib/tests.en.md +++ b/site/content/en/docs/contrib/tests.en.md @@ -44,6 +44,9 @@ tests the GCP Auth addon with either phony or real credentials and makes sure th #### validateHeadlampAddon +#### validateCloudSpannerAddon +tests the cloud-spanner addon by ensuring the deployment and pod come up and addon disables + ## TestCertOptions makes sure minikube certs respect the --apiserver-ips and --apiserver-names parameters diff --git a/test/integration/addons_test.go b/test/integration/addons_test.go index ca123a98aec9..0936fadba1af 100644 --- a/test/integration/addons_test.go +++ b/test/integration/addons_test.go @@ -66,7 +66,7 @@ func TestAddons(t *testing.T) { t.Fatalf("Failed setting GOOGLE_CLOUD_PROJECT env var: %v", err) } - args := append([]string{"start", "-p", profile, "--wait=true", "--memory=4000", "--alsologtostderr", "--addons=registry", "--addons=metrics-server", "--addons=volumesnapshots", "--addons=csi-hostpath-driver", "--addons=gcp-auth"}, StartArgs()...) + args := append([]string{"start", "-p", profile, "--wait=true", "--memory=4000", "--alsologtostderr", "--addons=registry", "--addons=metrics-server", "--addons=volumesnapshots", "--addons=csi-hostpath-driver", "--addons=gcp-auth"}, "--addons=cloud-spanner", StartArgs()...) if !NoneDriver() { // none driver does not support ingress args = append(args, "--addons=ingress", "--addons=ingress-dns") } @@ -97,6 +97,7 @@ func TestAddons(t *testing.T) { {"Olm", validateOlmAddon}, {"CSI", validateCSIDriverAndSnapshots}, {"Headlamp", validateHeadlampAddon}, + {"CloudSpanner", validateCloudSpannerAddon}, } for _, tc := range tests { tc := tc @@ -743,3 +744,22 @@ func validateHeadlampAddon(ctx context.Context, t *testing.T, profile string) { t.Fatalf("failed waiting for headlamp pod: %v", err) } } + +// validateCloudSpannerAddon tests the cloud-spanner addon by ensuring the deployment and pod come up and addon disables +func validateCloudSpannerAddon(ctx context.Context, t *testing.T, profile string) { + defer PostMortemLogs(t, profile) + + client, err := kapi.Client(profile) + if err != nil { + t.Fatalf("failed to get Kubernetes client for %s: %v", profile, err) + } + if err := kapi.WaitForDeploymentToStabilize(client, "default", "cloud-spanner-emulator", Minutes(6)); err != nil { + t.Errorf("failed waiting for cloud-spanner-emulator deployment to stabilize: %v", err) + } + if _, err := PodWait(ctx, t, profile, "default", "app=cloud-spanner-emulator", Minutes(6)); err != nil { + t.Errorf("failed waiting for app=cloud-spanner-emulator pod: %v", err) + } + if rr, err = Run(t, exec.CommandContext(ctx, Target(), "addons", "disable", "cloud-spanner", "-p", profile)); err != nil { + t.Errorf("failed to disable cloud-spanner addon: args %q : %v", rr.Command(), err) + } +} From e4b7598fd8c3c07c1155bfa82e451ab501ea8beb Mon Sep 17 00:00:00 2001 From: Steven Powell Date: Wed, 26 Oct 2022 10:33:15 -0700 Subject: [PATCH 3/3] fix linting --- test/integration/addons_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/integration/addons_test.go b/test/integration/addons_test.go index 0936fadba1af..c87904763407 100644 --- a/test/integration/addons_test.go +++ b/test/integration/addons_test.go @@ -66,7 +66,7 @@ func TestAddons(t *testing.T) { t.Fatalf("Failed setting GOOGLE_CLOUD_PROJECT env var: %v", err) } - args := append([]string{"start", "-p", profile, "--wait=true", "--memory=4000", "--alsologtostderr", "--addons=registry", "--addons=metrics-server", "--addons=volumesnapshots", "--addons=csi-hostpath-driver", "--addons=gcp-auth"}, "--addons=cloud-spanner", StartArgs()...) + args := append([]string{"start", "-p", profile, "--wait=true", "--memory=4000", "--alsologtostderr", "--addons=registry", "--addons=metrics-server", "--addons=volumesnapshots", "--addons=csi-hostpath-driver", "--addons=gcp-auth", "--addons=cloud-spanner"}, StartArgs()...) if !NoneDriver() { // none driver does not support ingress args = append(args, "--addons=ingress", "--addons=ingress-dns") } @@ -759,7 +759,7 @@ func validateCloudSpannerAddon(ctx context.Context, t *testing.T, profile string if _, err := PodWait(ctx, t, profile, "default", "app=cloud-spanner-emulator", Minutes(6)); err != nil { t.Errorf("failed waiting for app=cloud-spanner-emulator pod: %v", err) } - if rr, err = Run(t, exec.CommandContext(ctx, Target(), "addons", "disable", "cloud-spanner", "-p", profile)); err != nil { + if rr, err := Run(t, exec.CommandContext(ctx, Target(), "addons", "disable", "cloud-spanner", "-p", profile)); err != nil { t.Errorf("failed to disable cloud-spanner addon: args %q : %v", rr.Command(), err) } }