cmd/gerritbot: use secret manager only when run in GCE

Restore the ability to test gerritbot locally in dry-run mode.

Update some references to compute metadata with secret manager,
since that is what's used now.

Also add a safety check at the top of postGitHubMessageNoDup.
This increases confidence that it is safe to use dry-run mode,
and may help in case it's ever called in non-dry-run mode.

For golang/go#37171.
For golang/go#23850.

Change-Id: I6d7ea228294fc07b6167317ddcf066507e0c0d08
Reviewed-on: https://go-review.googlesource.com/c/build/+/234889
Reviewed-by: Carlos Amedee <carlos@golang.org>
Run-TryBot: Carlos Amedee <carlos@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
diff --git a/cmd/gerritbot/gerritbot.go b/cmd/gerritbot/gerritbot.go
index 366d0ad..caaa110 100644
--- a/cmd/gerritbot/gerritbot.go
+++ b/cmd/gerritbot/gerritbot.go
@@ -10,6 +10,7 @@
 	"bytes"
 	"context"
 	"crypto/sha1"
+	"errors"
 	"flag"
 	"fmt"
 	"io/ioutil"
@@ -43,7 +44,7 @@
 	workdir         = flag.String("workdir", defaultWorkdir(), "where git repos and temporary worktrees are created")
 	githubTokenFile = flag.String("github-token-file", filepath.Join(defaultWorkdir(), "github-token"), "file to load GitHub token from; should only contain the token text")
 	gerritTokenFile = flag.String("gerrit-token-file", filepath.Join(defaultWorkdir(), "gerrit-token"), "file to load Gerrit token from; should be of form <git-email>:<token>")
-	gitcookiesFile  = flag.String("gitcookies-file", "", "if non-empty, write a git http cookiefile to this location using compute metadata")
+	gitcookiesFile  = flag.String("gitcookies-file", "", "if non-empty, write a git http cookiefile to this location using secret manager")
 	dryRun          = flag.Bool("dry-run", false, "print out mutating actions but don’t perform any")
 )
 
@@ -53,7 +54,14 @@
 func main() {
 	flag.Parse()
 
-	secretClient := mustCreateSecretClient()
+	var secretClient *secret.Client
+	if metadata.OnGCE() {
+		var err error
+		secretClient, err = secret.NewClient()
+		if err != nil {
+			log.Fatalf("unable to create a secret manager client: %v", err)
+		}
+	}
 
 	if err := writeCookiesFile(secretClient); err != nil {
 		log.Fatalf("writeCookiesFile(): %v", err)
@@ -102,7 +110,7 @@
 	}
 	log.Printf("Writing git http cookies file %q ...", *gitcookiesFile)
 	if !metadata.OnGCE() {
-		return fmt.Errorf("cannot write git http cookies file %q from metadata: not on GCE", *gitcookiesFile)
+		return fmt.Errorf("cannot write git http cookies file %q from secret manager: not on GCE", *gitcookiesFile)
 	}
 
 	ctx, cancel := context.WithTimeout(context.Background(), secretClientTimeout)
@@ -830,6 +838,9 @@
 // at the beginning of a message.
 // TODO(andybons): This logic is shared by gopherbot. Consolidate it somewhere.
 func (b *bot) postGitHubMessageNoDup(ctx context.Context, org, repo string, issueNum int, msg string) error {
+	if *dryRun {
+		return errors.New("attempted write operation in dry-run mode")
+	}
 	gr := b.corpus.GitHub().Repo(org, repo)
 	if gr == nil {
 		return fmt.Errorf("unknown github repo %s/%s", org, repo)
@@ -912,11 +923,3 @@
 	logGitHubRateLimits(resp)
 	return nil
 }
-
-func mustCreateSecretClient() *secret.Client {
-	client, err := secret.NewClient()
-	if err != nil {
-		log.Fatalf("unable to create secret client %v", err)
-	}
-	return client
-}