cmd/pubsubhelper: move to Workload Identity

Create a new service account, and move the deployment over to the prod
namespace.

Update build image to Go 1.17, and use a GCS bucket for autocert cache
storage rather than a PD.

For golang/go#48263.

Change-Id: I33db02695f08ebdf9ef8b958bfd0b81567931b73
Reviewed-on: https://go-review.googlesource.com/c/build/+/348434
Trust: Heschi Kreinick <heschi@google.com>
Run-TryBot: Heschi Kreinick <heschi@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Dmitri Shuralyov <dmitshur@golang.org>
diff --git a/cmd/pubsubhelper/Dockerfile b/cmd/pubsubhelper/Dockerfile
index 1b93f02..9438f3c 100644
--- a/cmd/pubsubhelper/Dockerfile
+++ b/cmd/pubsubhelper/Dockerfile
@@ -2,12 +2,9 @@
 # Use of this source code is governed by a BSD-style
 # license that can be found in the LICENSE file.
 
-FROM golang:1.12 AS build
+FROM golang:1.17 AS build
 LABEL maintainer "golang-dev@googlegroups.com"
 
-ENV GO111MODULE=on
-ENV GOPROXY=https://proxy.golang.org
-
 RUN mkdir /gocache
 ENV GOCACHE /gocache
 
diff --git a/cmd/pubsubhelper/Makefile b/cmd/pubsubhelper/Makefile
index c8368a7..588a132 100644
--- a/cmd/pubsubhelper/Makefile
+++ b/cmd/pubsubhelper/Makefile
@@ -24,7 +24,7 @@
 
 deploy-prod: push-prod
 	go install golang.org/x/build/cmd/xb
-	xb --prod kubectl set image deployment/pubsubhelper-deployment pubsubhelper=$(IMAGE_PROD):$(VERSION)
+	xb --prod kubectl --namespace prod set image deployment/pubsubhelper-deployment pubsubhelper=$(IMAGE_PROD):$(VERSION)
 deploy-staging: push-staging
 	go install golang.org/x/build/cmd/xb
 	xb --staging kubectl set image deployment/pubsubhelper-deployment pubsubhelper=$(IMAGE_STAGING):$(VERSION)
diff --git a/cmd/pubsubhelper/cache-volume-prod.yaml b/cmd/pubsubhelper/cache-volume-prod.yaml
deleted file mode 100644
index 35e9905..0000000
--- a/cmd/pubsubhelper/cache-volume-prod.yaml
+++ /dev/null
@@ -1,12 +0,0 @@
-apiVersion: v1
-kind: PersistentVolume
-metadata:
-  name: pv-autocert-cache
-spec:
-  capacity:
-    storage: "10Gi"
-  accessModes:
-    - ReadWriteOnce
-  gcePersistentDisk:
-    fsType: "ext4"
-    pdName: "pubsubhelper-autocert-cache"
diff --git a/cmd/pubsubhelper/deployment-prod.yaml b/cmd/pubsubhelper/deployment-prod.yaml
index 17805bc..7d772a0 100644
--- a/cmd/pubsubhelper/deployment-prod.yaml
+++ b/cmd/pubsubhelper/deployment-prod.yaml
@@ -1,6 +1,7 @@
 apiVersion: apps/v1
 kind: Deployment
 metadata:
+  namespace: prod
   name: pubsubhelper-deployment
 spec:
   replicas: 1
@@ -15,19 +16,14 @@
         container.seccomp.security.alpha.kubernetes.io/pubsubhelper: docker/default
         container.apparmor.security.beta.kubernetes.io/pubsubhelper: runtime/default
     spec:
-      volumes:
-      - name: pv-autocert-cache
-        gcePersistentDisk:
-          pdName: pubsubhelper-autocert-cache
-          fsType: ext4
+      serviceAccountName: pubsubhelper
+      nodeSelector:
+        cloud.google.com/gke-nodepool: workload-identity-pool
       containers:
       - name: pubsubhelper
         image: gcr.io/symbolic-datum-552/pubsubhelper:latest
         imagePullPolicy: Always
-        command: ["/pubsubhelper"]
-        volumeMounts:
-        - mountPath: /autocert-cache
-          name: pv-autocert-cache
+        command: ["/pubsubhelper", "-autocert-bucket=golang-pubsubhelper-autocert"]
         ports:
         - containerPort: 25
         - containerPort: 80
diff --git a/cmd/pubsubhelper/pubsubhelper.go b/cmd/pubsubhelper/pubsubhelper.go
index 1f6ea98..c098d4e 100644
--- a/cmd/pubsubhelper/pubsubhelper.go
+++ b/cmd/pubsubhelper/pubsubhelper.go
@@ -11,7 +11,6 @@
 	"bufio"
 	"bytes"
 	"context"
-	"crypto/tls"
 	"encoding/json"
 	"errors"
 	"flag"
@@ -28,20 +27,23 @@
 	"sync"
 	"time"
 
+	"cloud.google.com/go/storage"
 	"github.com/bradfitz/go-smtpd/smtpd"
 	"github.com/jellevandenhooff/dkim"
 	"go4.org/types"
+	"golang.org/x/build/autocertcache"
 	"golang.org/x/build/cmd/pubsubhelper/pubsubtypes"
 	"golang.org/x/build/internal/secret"
 	"golang.org/x/crypto/acme/autocert"
 )
 
 var (
-	botEmail      = flag.String("rcpt", "\x67\x6f\x70\x68\x65\x72\x62\x6f\x74@pubsubhelper.golang.org", "email address of bot. incoming emails must be to this address.")
-	httpListen    = flag.String("http", ":80", "HTTP listen address")
-	acmeDomain    = flag.String("autocert", "pubsubhelper.golang.org", "If non-empty, listen on port 443 and serve HTTPS with a LetsEncrypt cert for this domain.")
-	smtpListen    = flag.String("smtp", ":25", "SMTP listen address")
-	webhookSecret = flag.String("webhook-secret", "", "Development mode GitHub webhook secret. This flag should not be used in production.")
+	botEmail       = flag.String("rcpt", "\x67\x6f\x70\x68\x65\x72\x62\x6f\x74@pubsubhelper.golang.org", "email address of bot. incoming emails must be to this address.")
+	httpListen     = flag.String("http", ":80", "HTTP listen address")
+	acmeDomain     = flag.String("autocert", "pubsubhelper.golang.org", "If non-empty, listen on port 443 and serve HTTPS with a LetsEncrypt cert for this domain.")
+	autocertBucket = flag.String("autocert-bucket", "", "if -autocert is enabled, use this GCS bucket as the autocert cache.")
+	smtpListen     = flag.String("smtp", ":25", "SMTP listen address")
+	webhookSecret  = flag.String("webhook-secret", "", "Development mode GitHub webhook secret. This flag should not be used in production.")
 )
 
 func main() {
@@ -96,20 +98,23 @@
 		if *acmeDomain == "" {
 			return
 		}
-		if _, err := os.Stat("/autocert-cache"); err == nil {
-			m.Cache = autocert.DirCache("/autocert-cache")
-		} else {
-			log.Printf("Warning: running acme/autocert without cache")
+		if *autocertBucket == "" {
+			log.Fatalf("autocert-bucket is required when autocert is enabled")
 		}
+		sc, err := storage.NewClient(context.Background())
+		if err != nil {
+			log.Fatalf("storage.NewClient: %v", err)
+		}
+		m.Cache = autocertcache.NewGoogleCloudStorageCache(sc, *autocertBucket)
 		log.Printf("running pubsubhelper HTTPS on :443 for %s", *acmeDomain)
 		s := &http.Server{
 			Addr:              ":https",
-			TLSConfig:         &tls.Config{GetCertificate: m.GetCertificate},
+			TLSConfig:         m.TLSConfig(),
 			ReadHeaderTimeout: 10 * time.Second,
 			WriteTimeout:      5 * time.Minute,
 			IdleTimeout:       5 * time.Minute,
 		}
-		err := s.ListenAndServeTLS("", "")
+		err = s.ListenAndServeTLS("", "")
 		errc <- fmt.Errorf("HTTPS ListenAndServeTLS: %v", err)
 	}()
 	go func() {
diff --git a/cmd/pubsubhelper/service.yaml b/cmd/pubsubhelper/service.yaml
index fd04c1e..2e6b490 100644
--- a/cmd/pubsubhelper/service.yaml
+++ b/cmd/pubsubhelper/service.yaml
@@ -1,6 +1,7 @@
 apiVersion: v1
 kind: Service
 metadata:
+  namespace: prod
   name: pubsubhelper
 spec:
   ports: