all: switch from github.com/ghodss/yaml to gopkg.in/yaml.v3

yaml.v3 is the more widely used yaml. The main difference between the
two is that ghodss converts yaml to JSON as an intermediate to
marshalling and unmarshalling. That means we need to add yaml struct
tags to use yaml.v3.

Add yaml tags to ConfigOverride and QuotaSettings because yaml.v3
lowercases the names of fields by default and the configs have used
uppercase names. Change a test experiment config to use lowercase
names since that's what's used in most other configs.

For golang/go#61399

Change-Id: Id7f09f2635ee013506b1573bfe555ec0348e60e4
Reviewed-on: https://go-review.googlesource.com/c/pkgsite/+/514522
TryBot-Result: Gopher Robot <gobot@golang.org>
Run-TryBot: Michael Matloob <matloob@golang.org>
Reviewed-by: Hyang-Ah Hana Kim <hyangah@gmail.com>
Reviewed-by: Jamal Carvalho <jamal@golang.org>
kokoro-CI: kokoro <noreply+kokoro@google.com>
diff --git a/devtools/cmd/create_experiment_config/main.go b/devtools/cmd/create_experiment_config/main.go
index 98505e8..e111cdf 100644
--- a/devtools/cmd/create_experiment_config/main.go
+++ b/devtools/cmd/create_experiment_config/main.go
@@ -13,8 +13,8 @@
 	"sort"
 	"strings"
 
-	"github.com/ghodss/yaml"
 	"golang.org/x/pkgsite/internal"
+	"gopkg.in/yaml.v3"
 )
 
 type Experiment struct {
diff --git a/go.mod b/go.mod
index cec5eb7..33dd6e1 100644
--- a/go.mod
+++ b/go.mod
@@ -16,7 +16,6 @@
 	github.com/alicebob/miniredis/v2 v2.17.0
 	github.com/andybalholm/cascadia v1.3.1
 	github.com/evanw/esbuild v0.17.8
-	github.com/ghodss/yaml v1.0.0
 	github.com/go-redis/redis/v8 v8.11.4
 	github.com/go-redis/redis_rate/v9 v9.1.2
 	github.com/golang-migrate/migrate/v4 v4.15.1
@@ -43,6 +42,7 @@
 	google.golang.org/genproto v0.0.0-20211208223120-3a66f561d7aa
 	google.golang.org/grpc v1.43.0
 	google.golang.org/protobuf v1.27.1
+	gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c
 )
 
 require (
@@ -91,5 +91,4 @@
 	golang.org/x/sys v0.10.0 // indirect
 	golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect
 	google.golang.org/appengine v1.6.7 // indirect
-	gopkg.in/yaml.v2 v2.4.0 // indirect
 )
diff --git a/go.sum b/go.sum
index 2c4b14a..a23947e 100644
--- a/go.sum
+++ b/go.sum
@@ -405,7 +405,6 @@
 github.com/gabriel-vasile/mimetype v1.4.0/go.mod h1:fA8fi6KUiG7MgQQ+mEWotXoEOvmxRtOJlERCzSmRvr8=
 github.com/garyburd/redigo v0.0.0-20150301180006-535138d7bcd7/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY=
 github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
-github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
 github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
 github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g=
 github.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3T0ecnM9pNujks=
diff --git a/internal/config/config.go b/internal/config/config.go
index 4b8e50d..900e2d2 100644
--- a/internal/config/config.go
+++ b/internal/config/config.go
@@ -24,12 +24,12 @@
 	"time"
 
 	"cloud.google.com/go/storage"
-	"github.com/ghodss/yaml"
 	"golang.org/x/net/context/ctxhttp"
 	"golang.org/x/pkgsite/internal/derrors"
 	"golang.org/x/pkgsite/internal/log"
 	"golang.org/x/pkgsite/internal/secrets"
 	mrpb "google.golang.org/genproto/googleapis/api/monitoredres"
+	"gopkg.in/yaml.v3"
 )
 
 // GetEnv looks up the given key from the environment, returning its value if
@@ -159,7 +159,7 @@
 
 	DBSecret, DBUser, DBHost, DBPort, DBName, DBSSL string
 	DBSecondaryHost                                 string // DB host to use if first one is down
-	DBPassword                                      string `json:"-"`
+	DBPassword                                      string `json:"-" yaml:"-"`
 
 	// Configuration for redis page cache.
 	RedisCacheHost, RedisBetaCacheHost, RedisCachePort string
@@ -331,25 +331,25 @@
 
 // configOverride holds selected config settings that can be dynamically overridden.
 type configOverride struct {
-	DBHost          string
-	DBSecondaryHost string
-	DBName          string
-	Quota           QuotaSettings
+	DBHost          string        `yaml:"DBHost"`
+	DBSecondaryHost string        `yaml:"DBSecondaryHost"`
+	DBName          string        `yaml:"DBName"`
+	Quota           QuotaSettings `yaml:"Quota"`
 }
 
 // QuotaSettings is config for internal/middleware/quota.go
 type QuotaSettings struct {
-	Enable     bool
-	QPS        int // allowed queries per second, per IP block
-	Burst      int // maximum requests per second, per block; the size of the token bucket
-	MaxEntries int // maximum number of entries to keep track of
+	Enable     bool `yaml:"Enable"`
+	QPS        int  `yaml:"QPS"`        // allowed queries per second, per IP block
+	Burst      int  `yaml:"Burst"`      // maximum requests per second, per block; the size of the token bucket
+	MaxEntries int  `yaml:"MaxEntries"` // maximum number of entries to keep track of
 	// Record data about blocking, but do not actually block.
 	// This is a *bool, so we can distinguish "not present" from "false" in an override
-	RecordOnly *bool
+	RecordOnly *bool `yaml:"RecordOnly"`
 	// AuthValues is the set of values that could be set on the AuthHeader, in
 	// order to bypass checks by the quota server.
-	AuthValues []string
-	HMACKey    []byte `json:"-"` // key for obfuscating IPs
+	AuthValues []string `yaml:"AuthValues"`
+	HMACKey    []byte   `json:"-" yaml:"-"` // key for obfuscating IPs
 }
 
 // Init resolves all configuration values provided by the config package. It
diff --git a/internal/config/dynconfig/dynconfig.go b/internal/config/dynconfig/dynconfig.go
index 9e3f66c..fe1b82c 100644
--- a/internal/config/dynconfig/dynconfig.go
+++ b/internal/config/dynconfig/dynconfig.go
@@ -15,10 +15,10 @@
 	"strings"
 
 	"cloud.google.com/go/storage"
-	"github.com/ghodss/yaml"
 	"golang.org/x/pkgsite/internal"
 	"golang.org/x/pkgsite/internal/derrors"
 	"golang.org/x/pkgsite/internal/log"
+	"gopkg.in/yaml.v3"
 )
 
 // DynamicConfig holds configuration that can change over the lifetime of the
diff --git a/tests/search/config.yaml b/tests/search/config.yaml
index dc9c6ba..b1c8af7 100644
--- a/tests/search/config.yaml
+++ b/tests/search/config.yaml
@@ -1,5 +1,5 @@
 experiments:
-- Name: search-grouping
-  Rollout: 100
-- Name: symbol-search
-  Rollout: 100
+- name: search-grouping
+  rollout: 100
+- name: symbol-search
+  rollout: 100