Source File
config.go
Belonging Package
golang.org/x/pkgsite/internal/config
package config
import (
mrpb
)
const AppVersionFormat = "20060102t150405"
BypassQuotaAuthHeader = "X-Go-Discovery-Auth-Bypass-Quota"
BypassCacheAuthHeader = "X-Go-Discovery-Auth-Bypass-Cache"
BypassErrorReportingHeader = "X-Go-Discovery-Bypass-Error-Reporting"
)
FallbackVersionLabel string
DBSecret, DBUser, DBHost, DBPort, DBName string
DBSecondaryHost string // DB host to use if first one is down
DBPassword string `json:"-"`
DBDriver string
func ( *Config) () string {
if .VersionID != "" {
return .VersionID
}
return .FallbackVersionLabel
}
func ( *Config) () bool {
return .OnAppEngine() || .OnGKE()
}
const StatementTimeout = 30 * time.Minute
const SourceTimeout = 1 * time.Minute
const TaskIDChangeIntervalFrontend = 30 * time.Minute
func ( *Config) () string {
return .dbConnInfo(.DBHost)
}
func ( *Config) () string {
if .DBSecondaryHost == "" {
return ""
}
return .dbConnInfo(.DBSecondaryHost)
}
:= fmt.Sprintf("-c statement_timeout=%d", StatementTimeout/time.Millisecond)
return fmt.Sprintf("user='%s' password='%s' host='%s' port=%s dbname='%s' sslmode=disable options='%s'",
.DBUser, .DBPassword, , .DBPort, .DBName, )
}
type configOverride struct {
DBHost string
DBSecondaryHost string
DBName string
Quota QuotaSettings
}
AuthValues []string
HMACKey []byte `json:"-"` // key for obfuscating IPs
}
ProjectID: os.Getenv("GOOGLE_CLOUD_PROJECT"),
ServiceID: GetEnv("GAE_SERVICE", os.Getenv("GO_DISCOVERY_SERVICE")),
VersionID: GetEnv("GAE_VERSION", os.Getenv("DOCKER_IMAGE")),
InstanceID: GetEnv("GAE_INSTANCE", os.Getenv("GO_DISCOVERY_INSTANCE")),
GoogleTagManagerID: os.Getenv("GO_DISCOVERY_GOOGLE_TAG_MANAGER_ID"),
QueueURL: os.Getenv("GO_DISCOVERY_QUEUE_URL"),
QueueAudience: os.Getenv("GO_DISCOVERY_QUEUE_AUDIENCE"),
FallbackVersionLabel: time.Now().Format(AppVersionFormat),
DBHost: chooseOne(GetEnv("GO_DISCOVERY_DATABASE_HOST", "localhost")),
DBUser: GetEnv("GO_DISCOVERY_DATABASE_USER", "postgres"),
DBPassword: os.Getenv("GO_DISCOVERY_DATABASE_PASSWORD"),
DBSecondaryHost: chooseOne(os.Getenv("GO_DISCOVERY_DATABASE_SECONDARY_HOST")),
DBPort: GetEnv("GO_DISCOVERY_DATABASE_PORT", "5432"),
DBName: GetEnv("GO_DISCOVERY_DATABASE_NAME", "discovery-db"),
DBSecret: os.Getenv("GO_DISCOVERY_DATABASE_SECRET"),
DBDriver: GetEnv("GO_DISCOVERY_DATABASE_DRIVER", "pgx"),
RedisCacheHost: os.Getenv("GO_DISCOVERY_REDIS_HOST"),
RedisCachePort: GetEnv("GO_DISCOVERY_REDIS_PORT", "6379"),
RedisHAHost: os.Getenv("GO_DISCOVERY_REDIS_HA_HOST"),
RedisHAPort: GetEnv("GO_DISCOVERY_REDIS_HA_PORT", "6379"),
Quota: QuotaSettings{
Enable: os.Getenv("GO_DISCOVERY_ENABLE_QUOTA") == "true",
QPS: GetEnvInt("GO_DISCOVERY_QUOTA_QPS", 10),
Burst: 20, // ignored in redis-based quota implementation
MaxEntries: 1000, // ignored in redis-based quota implementation
RecordOnly: func() *bool {
:= (os.Getenv("GO_DISCOVERY_QUOTA_RECORD_ONLY") != "false")
return &
}(),
AuthValues: parseCommaList(os.Getenv("GO_DISCOVERY_AUTH_VALUES")),
},
UseProfiler: os.Getenv("GO_DISCOVERY_USE_PROFILER") == "true",
LogLevel: os.Getenv("GO_DISCOVERY_LOG_LEVEL"),
ServeStats: os.Getenv("GO_DISCOVERY_SERVE_STATS") == "true",
DisableErrorReporting: os.Getenv("GO_DISCOVERY_DISABLE_ERROR_REPORTING") == "true",
}
:= os.Getenv("GO_DISCOVERY_CONFIG_BUCKET")
:= os.Getenv("GO_DISCOVERY_CONFIG_DYNAMIC")
if != "" {
if == "" {
return nil, errors.New("GO_DISCOVERY_CONFIG_DYNAMIC must be set if GO_DISCOVERY_CONFIG_BUCKET is")
}
.DynamicConfigLocation = fmt.Sprintf("gs://%s/%s", , )
} else {
.DynamicConfigLocation =
}
, := gceMetadata(, "instance/zone")
if != nil {
return nil,
}
.ZoneID =
, := gceMetadata(, "instance/service-accounts/default/email")
if != nil {
return nil,
}
.ServiceAccount =
switch {
.MonitoredResource = &mrpb.MonitoredResource{
Type: "gae_app",
Labels: map[string]string{
"project_id": .ProjectID,
"module_id": .ServiceID,
"version_id": .VersionID,
"zone": .ZoneID,
},
}
case .OnGKE():
.MonitoredResource = &mrpb.MonitoredResource{
Type: "k8s_container",
Labels: map[string]string{
"project_id": .ProjectID,
"location": path.Base(.ZoneID),
"cluster_name": .DeploymentEnvironment() + "-pkgsite",
"namespace_name": "default",
"pod_name": os.Getenv("HOSTNAME"),
"container_name": .Application(),
},
}
default:
return nil, errors.New("on GCP but using an unknown product")
}
} else { // running locally, perhaps
.MonitoredResource = &mrpb.MonitoredResource{
Type: "global",
Labels: map[string]string{"project_id": .ProjectID},
}
}
if .DBHost == "" {
panic("DBHost is empty; impossible")
}
if .DBSecret != "" {
var error
.DBPassword, = secrets.Get(, .DBSecret)
if != nil {
return nil, fmt.Errorf("could not get database password secret: %v", )
}
}
if .Quota.Enable {
, := secrets.Get(, "quota-hmac-key")
if != nil {
return nil,
}
, := hex.DecodeString()
if != nil {
return nil,
}
if len() < 16 {
return nil, errors.New("HMAC secret must be at least 16 bytes")
}
.Quota.HMACKey =
} else {
log.Print("quota enforcement disabled")
}
:= os.Getenv("GO_DISCOVERY_CONFIG_OVERRIDE")
if != "" {
, := readOverrideFile(, , )
if != nil {
log.Print()
} else {
log.Printf("processing overrides from gs://%s/%s", , )
processOverrides(, )
}
}
return , nil
}
func ( context.Context, , string) ( []byte, error) {
defer derrors.Wrap(&, "readOverrideFile(ctx, %q)", )
, := storage.NewClient()
if != nil {
return nil,
}
defer .Close()
, := .Bucket().Object().NewReader()
if != nil {
return nil,
}
defer .Close()
return ioutil.ReadAll()
}
func ( *Config, []byte) {
var configOverride
if := yaml.Unmarshal(, &); != nil {
log.Printf("processOverrides: %v", )
return
}
overrideString("DBHost", &.DBHost, .DBHost)
overrideString("DBSecondaryHost", &.DBSecondaryHost, .DBSecondaryHost)
overrideString("DBName", &.DBName, .DBName)
overrideInt("Quota.QPS", &.Quota.QPS, .Quota.QPS)
overrideInt("Quota.Burst", &.Quota.Burst, .Quota.Burst)
overrideInt("Quota.MaxEntries", &.Quota.MaxEntries, .Quota.MaxEntries)
overrideBool("Quota.RecordOnly", &.Quota.RecordOnly, .Quota.RecordOnly)
}
func ( string, *string, string) {
if != "" {
* =
log.Printf("overriding %s with %q", , )
}
}
func ( string, *int, int) {
if != 0 {
* =
log.Printf("overriding %s with %d", , )
}
}
func ( string, **bool, *bool) {
if != nil {
* =
log.Printf("overriding %s with %t", , *)
}
}
defer derrors.Wrap(&, "gceMetadata(ctx, %q)", )
const = "http://metadata.google.internal/computeMetadata/v1/"
, := http.NewRequest("GET", +, nil)
if != nil {
return "", fmt.Errorf("http.NewRequest: %v", )
}
.Header.Set("Metadata-Flavor", "Google")
, := ctxhttp.Do(, nil, )
if != nil {
return "", fmt.Errorf("ctxhttp.Do: %v", )
}
defer .Body.Close()
if .StatusCode != http.StatusOK {
return "", fmt.Errorf("bad status: %s", .Status)
}
, := ioutil.ReadAll(.Body)
if != nil {
return "", fmt.Errorf("ioutil.ReadAll: %v", )
}
return string(), nil
}
func ( string) []string {
var []string
for , := range strings.Split(, ",") {
= strings.TrimSpace()
if != "" {
= append(, )
}
}
return
![]() |
The pages are generated with Golds v0.3.2-preview. (GOOS=darwin GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds. |