Config change first step ()

This commit is contained in:
yfei1
2019-10-25 15:09:04 -07:00
committed by GitHub
parent 74992cdf79
commit 7a48467cb5
7 changed files with 139 additions and 64 deletions
install/helm/open-match
internal/config

@ -23,7 +23,7 @@ metadata:
component: config
release: {{ .Release.Name }}
data:
matchmaker_config.yaml: |-
matchmaker_config_override.yaml: |-
api:
mmlogic:
hostname: "{{ .Values.mmlogic.hostName }}"

@ -32,6 +32,10 @@ image:
pullPolicy: Always
configs:
# TODO: Remove this bit after deprecating the harness dependency on configmap
om-configmap-default:
volumeName: om-config-volume-default
mountPath: /app/config/default
customize-configmap:
mountPath: /app/config/om
volumeName: customize-config-volume
mountPath: /app/config/override

@ -16,7 +16,7 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: om-configmap
name: om-configmap-default
namespace: {{ .Release.Namespace }}
annotations: {{- include "openmatch.chartmeta" . | nindent 4 }}
labels:
@ -24,7 +24,7 @@ metadata:
component: config
release: {{ .Release.Name }}
data:
matchmaker_config.yaml: |-
matchmaker_config_default.yaml: |-
logging:
level: debug
{{- if .Values.global.telemetry.stackdriver.enabled }}
@ -97,4 +97,33 @@ data:
ignoreLists:
ttl: {{ .Values.redis.ignoreLists.ttl }}
expiration: 43200
telemetry:
zpages:
enable: "{{ .Values.global.telemetry.zpages.enabled }}"
jaeger:
enable: "{{ .Values.global.telemetry.jaeger.enabled }}"
agentEndpoint: "{{ .Values.global.telemetry.jaeger.agentEndpoint }}"
collectorEndpoint: "{{ .Values.global.telemetry.jaeger.collectorEndpoint }}"
prometheus:
enable: "{{ .Values.global.telemetry.prometheus.enabled }}"
endpoint: "{{ .Values.global.telemetry.prometheus.endpoint }}"
serviceDiscovery: "{{ .Values.global.telemetry.prometheus.serviceDiscovery }}"
stackdriver:
enable: "{{ .Values.global.telemetry.stackdriver.enabled }}"
gcpProjectId: "{{ .Values.global.gcpProjectId }}"
metricPrefix: "{{ .Values.global.telemetry.stackdriver.metricPrefix }}"
zipkin:
enable: "{{ .Values.global.telemetry.zipkin.enabled }}"
endpoint: "{{ .Values.global.telemetry.zipkin.endpoint }}"
reporterEndpoint: "{{ .Values.global.telemetry.zipkin.reporterEndpoint }}"
reportingPeriod: "{{ .Values.global.telemetry.reportingPeriod }}"
{{- if .Values.global.tls.enabled }}
api:
tls:
trustedCertificatePath: "{{.Values.global.tls.rootca.mountPath}}/public.cert"
certificatefile: "{{.Values.global.tls.server.mountPath}}/public.cert"
privatekey: "{{.Values.global.tls.server.mountPath}}/private.key"
rootcertificatefile: "{{.Values.global.tls.rootca.mountPath}}/public.cert"
{{- end -}}
{{- end }}

@ -0,0 +1,33 @@
# Copyright 2019 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
{{- if index .Values "open-match-core" "enabled" }}
apiVersion: v1
kind: ConfigMap
metadata:
name: om-configmap-override
namespace: {{ .Release.Namespace }}
annotations: {{- include "openmatch.chartmeta" . | nindent 4 }}
labels:
app: {{ template "openmatch.name" . }}
component: config
release: {{ .Release.Name }}
data:
# TODO: Make this override configmap optional.
# Kubernetes doesn't allow having a configmap with empty key.
# Using logging setting at here as a placeholder.
matchmaker_config_override.yaml: |-
logging:
level: debug
{{- end }}}

@ -97,9 +97,12 @@ image:
# Specifies the location and name of the Open Match application-level config volumes.
# Used in template: `openmatch.volumemounts.configs` and `openmatch.volumes.configs` under `templates/_helpers.tpl` file.
configs:
om-configmap:
volumeName: om-config-volume
mountPath: /app/config/om
om-configmap-default:
volumeName: om-config-volume-default
mountPath: /app/config/default
om-configmap-override:
volumeName: om-config-volume-override
mountPath: /app/config/override
# Override Redis settings
# https://hub.helm.sh/charts/stable/redis

@ -16,67 +16,54 @@
package config
import (
"fmt"
"github.com/fsnotify/fsnotify"
"github.com/sirupsen/logrus"
"github.com/spf13/viper"
"go.opencensus.io/stats"
"go.opencensus.io/stats/view"
"log"
)
var (
logger = logrus.WithFields(logrus.Fields{
"app": "openmatch",
"component": "config",
})
// OpenCensus
cfgVarCount = stats.Int64("config/vars_total", "Number of config vars read during initialization", "1")
// CfgVarCountView is the Open Census view for the cfgVarCount measure.
CfgVarCountView = &view.View{
Name: "config/vars_total",
Measure: cfgVarCount,
Description: "The number of config vars read during initialization",
Aggregation: view.Count(),
}
)
// Read reads a config file into a viper.Viper instance and associates environment vars defined in
// config.envMappings
// Read sets default to a viper instance and read user config to override these defaults.
func Read() (View, error) {
var err error
// read configs from config/default/matchmaker_config_default.yaml
// matchmaker_config_default provides default values for all of the possible tunnable parameters in Open Match
dcfg := viper.New()
dcfg.SetConfigType("yaml")
dcfg.AddConfigPath(".")
dcfg.AddConfigPath("config/default")
dcfg.SetConfigName("matchmaker_config_default")
err = dcfg.ReadInConfig()
if err != nil {
return nil, fmt.Errorf("fatal error reading default config file, desc: %s", err.Error())
}
// read configs from config/override/matchmaker_config_default.yaml
// matchmaker_config_override overrides default values specified in matchmaker_config_default
cfg := viper.New()
// Viper config management initialization
// Support either json or yaml file types (json for backwards compatibility
// with previous versions)
cfg.SetConfigType("json")
// set defaults for cfg using settings in dcfg
for k, v := range dcfg.AllSettings() {
cfg.SetDefault(k, v)
}
cfg.SetConfigType("yaml")
cfg.AddConfigPath(".")
cfg.AddConfigPath("config/global")
cfg.SetConfigName("global_config")
err := cfg.ReadInConfig()
cfg.AddConfigPath("config/override")
cfg.SetConfigName("matchmaker_config_override")
err = cfg.ReadInConfig()
if err != nil {
logger.WithError(err).Fatal("Fatal error reading config file")
}
cfg.AddConfigPath("config/om")
cfg.SetConfigName("matchmaker_config")
// Read in config file using Viper
err = cfg.MergeInConfig()
if err != nil {
logger.WithError(err).Fatal("Fatal error reading config file")
return nil, fmt.Errorf("fatal error reading override config file, desc: %s", err.Error())
}
// Look for updates to the config; in Kubernetes, this is implemented using
// a ConfigMap that is written to the matchmaker_config.yaml file, which is
// a ConfigMap that is written to the matchmaker_config_override.yaml file, which is
// what the Open Match components using Viper monitor for changes.
// More details about Open Match's use of Kubernetes ConfigMaps at:
// https://open-match.dev/open-match/issues/42
cfg.WatchConfig() // Watch and re-read config file.
// Write a log when the configuration changes.
cfg.OnConfigChange(func(event fsnotify.Event) {
logger.WithFields(logrus.Fields{
"filename": event.Name,
"operation": event.Op,
}).Info("Server configuration changed.")
log.Printf("Server configuration changed, operation: %v, filename: %s", event.Op, event.Name)
})
return cfg, err
return cfg, nil
}

@ -24,34 +24,53 @@ import (
)
func TestReadConfigIgnoreRace(t *testing.T) {
yaml := []byte(`metrics.endpoint: /metrics`)
if err := ioutil.WriteFile("matchmaker_config.yaml", yaml, 0666); err != nil {
const defaultCfgName = "matchmaker_config_default.yaml"
const overrideCfgName = "matchmaker_config_override.yaml"
yaml := []byte(`
metrics.overrideKey: defaultValue1
metrics.defaultKey: defaultValue2
`)
if err := ioutil.WriteFile(defaultCfgName, yaml, 0666); err != nil {
t.Fatalf("could not create config file: %s", err)
}
defer os.Remove("matchmaker_config.yaml")
yaml = []byte(`metrics.url: om`)
if err := ioutil.WriteFile("global_config.yaml", yaml, 0666); err != nil {
defer os.Remove(defaultCfgName)
yaml = []byte(`metrics.overrideKey: overrideValue1`)
if err := ioutil.WriteFile(overrideCfgName, yaml, 0666); err != nil {
t.Fatalf("could not create config file: %s", err)
}
defer os.Remove("global_config.yaml")
defer os.Remove(overrideCfgName)
cfg, err := Read()
if err != nil {
t.Fatalf("cannot load config, %s", err)
}
if cfg.GetString("metrics.endpoint") != "/metrics" {
t.Errorf("av.GetString('metrics.endpoint') = %s, expected '/metrics'", cfg.GetString("metrics.endpoint"))
if cfg.GetString("metrics.overrideKey") != "overrideValue1" {
t.Errorf("cfg.GetString('metrics.overrideKey') = %s, expected 'overrideValue1'", cfg.GetString("metrics.overrideKey"))
}
if cfg.GetString("metrics.defaultKey") != "defaultValue2" {
t.Errorf("cfg.GetString('metrics.defaultKey') = %s, expected 'defaultValue2'", cfg.GetString("metrics.defaultKey"))
}
yaml = []byte(`metrics.endpoint: ''`)
if err := ioutil.WriteFile("matchmaker_config.yaml", yaml, 0666); err != nil {
yaml = []byte(`
metrics.newKey: newValue
metrics.overrideKey: overrideValue2
`)
if err := ioutil.WriteFile(overrideCfgName, yaml, 0666); err != nil {
t.Fatalf("could not update config file: %s", err)
}
time.Sleep(2 * time.Second)
time.Sleep(time.Second)
if cfg.GetString("metrics.endpoint") != "" {
t.Errorf("av.GetString('metrics.endpoint') = %s, expected ''", cfg.GetString("metrics.endpoint"))
if cfg.GetString("metrics.overrideKey") != "overrideValue2" {
t.Errorf("cfg.GetString('metrics.overrideKey') = %s, expected 'overrideValue2'", cfg.GetString("metrics.overrideKey"))
}
if cfg.GetString("metrics.defaultKey") != "defaultValue2" {
t.Errorf("cfg.GetString('metrics.defaultKey') = %s, expected 'defaultValue2'", cfg.GetString("metrics.defaultKey"))
}
if cfg.GetString("metrics.newKey") != "newValue" {
t.Errorf("cfg.GetString('metrics.newKey') = %s, expected 'newValue'", cfg.GetString("metrics.newKey"))
}
}