diff --git a/app/kuma-cp/cmd/run.go b/app/kuma-cp/cmd/run.go index 7c3a1b8fe91f..99144fa6d598 100644 --- a/app/kuma-cp/cmd/run.go +++ b/app/kuma-cp/cmd/run.go @@ -1,6 +1,7 @@ package cmd import ( + "fmt" ui_server "github.com/Kong/kuma/app/kuma-ui/pkg/server" api_server "github.com/Kong/kuma/pkg/api-server" "github.com/Kong/kuma/pkg/config" @@ -47,6 +48,17 @@ func newRunCmdWithOpts(opts runCmdOpts) *cobra.Command { runLog.Error(err, "unable to set up Control Plane runtime") return err } + cfgForDisplay, err := config.ConfigForDisplay(&cfg) + if err != nil { + runLog.Error(err, "unable to prepare config for display") + return err + } + cfgBytes, err := config.ToJson(cfgForDisplay) + if err != nil { + runLog.Error(err, "unable to convert config to json") + return err + } + runLog.Info(fmt.Sprintf("Current config %s", cfgBytes)) if err := sds_server.SetupServer(rt); err != nil { runLog.Error(err, "unable to set up SDS server") return err diff --git a/pkg/api-server/config_ws.go b/pkg/api-server/config_ws.go new file mode 100644 index 000000000000..dc22863e16b2 --- /dev/null +++ b/pkg/api-server/config_ws.go @@ -0,0 +1,25 @@ +package api_server + +import ( + "github.com/Kong/kuma/pkg/config" + "github.com/emicklei/go-restful" +) + +func configWs(cfg config.Config) (*restful.WebService, error) { + cfgForDisplay, err := config.ConfigForDisplay(cfg) + if err != nil { + return nil, err + } + json, err := config.ToJson(cfgForDisplay) + if err != nil { + return nil, err + } + ws := new(restful.WebService).Path("/config") + ws.Route(ws.GET("").To(func(req *restful.Request, resp *restful.Response) { + resp.AddHeader("content-type", "application/json") + if _, err := resp.Write(json); err != nil { + log.Error(err, "Could not write the index response") + } + })) + return ws, nil +} diff --git a/pkg/api-server/config_ws_test.go b/pkg/api-server/config_ws_test.go new file mode 100644 index 000000000000..4b84bffc9b04 --- /dev/null +++ b/pkg/api-server/config_ws_test.go @@ -0,0 +1,137 @@ +package api_server_test + +import ( + "fmt" + api_server_config "github.com/Kong/kuma/pkg/config/api-server" + "github.com/Kong/kuma/pkg/plugins/resources/memory" + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + "io/ioutil" + "net/http" + "strings" +) + +var _ = Describe("Config WS", func() { + + It("should return the config", func() { + // given + cfg := api_server_config.DefaultApiServerConfig() + + // setup + resourceStore := memory.NewStore() + apiServer := createTestApiServer(resourceStore, cfg) + + stop := make(chan struct{}) + go func() { + defer GinkgoRecover() + err := apiServer.Start(stop) + Expect(err).ToNot(HaveOccurred()) + }() + port := strings.Split(apiServer.Address(), ":")[1] + + // wait for the server + Eventually(func() error { + _, err := http.Get(fmt.Sprintf("http://localhost:%s/config", port)) + return err + }, "3s").ShouldNot(HaveOccurred()) + + // when + resp, err := http.Get(fmt.Sprintf("http://localhost:%s/config", port)) + Expect(err).ToNot(HaveOccurred()) + + // then + body, err := ioutil.ReadAll(resp.Body) + Expect(err).ToNot(HaveOccurred()) + + // when + json := fmt.Sprintf(` + { + "apiServer": { + "corsAllowedDomains": [ + ".*" + ], + "port": %s, + "readOnly": false + }, + "bootstrapServer": { + "params": { + "adminAccessLogPath": "/dev/null", + "adminAddress": "127.0.0.1", + "adminPort": 0, + "xdsConnectTimeout": "1s", + "xdsHost": "", + "xdsPort": 0 + }, + "port": 5682 + }, + "dataplaneTokenServer": { + "enabled": true, + "local": { + "port": 5679 + }, + "public": { + "clientCertsDir": "", + "enabled": false, + "interface": "", + "port": 0, + "tlsCertFile": "", + "tlsKeyFile": "" + } + }, + "defaults": { + "mesh": "type: Mesh\nname: default\nmtls:\n ca: {}\n enabled: false\n" + }, + "discovery": { + "universal": { + "pollingInterval": "1s" + } + }, + "environment": "universal", + "general": { + "advertisedHostname": "localhost" + }, + "guiServer": { + "port": 5683 + }, + "reports": { + "enabled": true + }, + "runtime": { + "kubernetes": { + "admissionServer": { + "address": "", + "certDir": "", + "port": 5443 + } + } + }, + "sdsServer": { + "grpcPort": 5677, + "tlsCertFile": "", + "tlsKeyFile": "" + }, + "store": { + "kubernetes": { + "systemNamespace": "kuma-system" + }, + "postgres": { + "connectionTimeout": 5, + "dbName": "kuma", + "host": "127.0.0.1", + "password": "*****", + "port": 15432, + "user": "kuma" + }, + "type": "memory" + }, + "xdsServer": { + "dataplaneConfigurationRefreshInterval": "1s", + "dataplaneStatusFlushInterval": "1s", + "diagnosticsPort": 5680, + "grpcPort": 5678 + } + } + `, port) + Expect(body).To(MatchJSON(json)) + }) +}) diff --git a/pkg/api-server/resource_api_client_test.go b/pkg/api-server/resource_api_client_test.go index dbd8546d0885..0cfe607b4429 100644 --- a/pkg/api-server/resource_api_client_test.go +++ b/pkg/api-server/resource_api_client_test.go @@ -7,6 +7,7 @@ import ( api_server "github.com/Kong/kuma/pkg/api-server" "github.com/Kong/kuma/pkg/api-server/definitions" config_api_server "github.com/Kong/kuma/pkg/config/api-server" + kuma_cp "github.com/Kong/kuma/pkg/config/app/kuma-cp" "github.com/Kong/kuma/pkg/core/resources/manager" "github.com/Kong/kuma/pkg/core/resources/store" "github.com/Kong/kuma/pkg/test" @@ -105,5 +106,9 @@ func createTestApiServer(store store.ResourceStore, config *config_api_server.Ap config.Port = port defs := append(definitions.All, SampleTrafficRouteWsDefinition) resources := manager.NewResourceManager(store) - return api_server.NewApiServer(resources, defs, config) + cfg := kuma_cp.DefaultConfig() + cfg.ApiServer = config + apiServer, err := api_server.NewApiServer(resources, defs, cfg.ApiServer, &cfg) + Expect(err).ToNot(HaveOccurred()) + return apiServer } diff --git a/pkg/api-server/server.go b/pkg/api-server/server.go index a1afff462827..f6c099bbf17a 100644 --- a/pkg/api-server/server.go +++ b/pkg/api-server/server.go @@ -3,12 +3,14 @@ package api_server import ( "context" "fmt" - "github.com/Kong/kuma/pkg/core/resources/manager" + "github.com/pkg/errors" "net/http" "github.com/Kong/kuma/pkg/api-server/definitions" - config "github.com/Kong/kuma/pkg/config/api-server" + "github.com/Kong/kuma/pkg/config" + api_server_config "github.com/Kong/kuma/pkg/config/api-server" "github.com/Kong/kuma/pkg/core" + "github.com/Kong/kuma/pkg/core/resources/manager" "github.com/Kong/kuma/pkg/core/runtime" "github.com/emicklei/go-restful" ) @@ -25,7 +27,7 @@ func (a *ApiServer) Address() string { return a.server.Addr } -func NewApiServer(resManager manager.ResourceManager, defs []definitions.ResourceWsDefinition, serverConfig *config.ApiServerConfig) *ApiServer { +func NewApiServer(resManager manager.ResourceManager, defs []definitions.ResourceWsDefinition, serverConfig *api_server_config.ApiServerConfig, cfg config.Config) (*ApiServer, error) { container := restful.NewContainer() srv := &http.Server{ Addr: fmt.Sprintf(":%d", serverConfig.Port), @@ -48,14 +50,19 @@ func NewApiServer(resManager manager.ResourceManager, defs []definitions.Resourc container.Add(ws) container.Add(indexWs()) container.Add(catalogWs(*serverConfig.Catalog)) + configWs, err := configWs(cfg) + if err != nil { + return nil, errors.Wrap(err, "could not create configuration webservice") + } + container.Add(configWs) - ws.Filter(cors.Filter) + container.Filter(cors.Filter) return &ApiServer{ server: srv, - } + }, nil } -func addToWs(ws *restful.WebService, defs []definitions.ResourceWsDefinition, resManager manager.ResourceManager, config *config.ApiServerConfig) { +func addToWs(ws *restful.WebService, defs []definitions.ResourceWsDefinition, resManager manager.ResourceManager, config *api_server_config.ApiServerConfig) { overviewWs := overviewWs{ resManager: resManager, } @@ -96,6 +103,10 @@ func (a *ApiServer) Start(stop <-chan struct{}) error { } func SetupServer(rt runtime.Runtime) error { - apiServer := NewApiServer(rt.ResourceManager(), definitions.All, rt.Config().ApiServer) + cfg := rt.Config() + apiServer, err := NewApiServer(rt.ResourceManager(), definitions.All, rt.Config().ApiServer, &cfg) + if err != nil { + return err + } return rt.Add(apiServer) } diff --git a/pkg/config/api-server/config.go b/pkg/config/api-server/config.go index 6c6a11c2d9c8..92b07e9476e0 100644 --- a/pkg/config/api-server/config.go +++ b/pkg/config/api-server/config.go @@ -16,11 +16,14 @@ type ApiServerConfig struct { // If true, then API Server will operate in read only mode (serving GET requests) ReadOnly bool `yaml:"readOnly" envconfig:"kuma_api_server_read_only"` // API Catalog - Catalog *catalog.CatalogConfig + Catalog *catalog.CatalogConfig `yaml:"-"` // Allowed domains for Cross-Origin Resource Sharing. The value can be either domain or regexp CorsAllowedDomains []string `yaml:"corsAllowedDomains" envconfig:"kuma_api_server_cors_allowed_domains"` } +func (a *ApiServerConfig) Sanitize() { +} + func (a *ApiServerConfig) Validate() error { if a.Port < 0 { return errors.New("Port cannot be negative") diff --git a/pkg/config/app/kuma-cp/config.go b/pkg/config/app/kuma-cp/config.go index 8bd127de2cf2..996e536a85d0 100644 --- a/pkg/config/app/kuma-cp/config.go +++ b/pkg/config/app/kuma-cp/config.go @@ -28,6 +28,9 @@ type Defaults struct { Mesh string `yaml:"mesh"` } +func (d *Defaults) Sanitize() { +} + func (d *Defaults) MeshProto() v1alpha1.Mesh { mesh, err := d.parseMesh() util_error.MustNot(err) @@ -81,6 +84,20 @@ type Config struct { GuiServer *gui_server.GuiServerConfig `yaml:"guiServer"` } +func (c *Config) Sanitize() { + c.General.Sanitize() + c.Store.Sanitize() + c.Discovery.Sanitize() + c.BootstrapServer.Sanitize() + c.XdsServer.Sanitize() + c.SdsServer.Sanitize() + c.DataplaneTokenServer.Sanitize() + c.ApiServer.Sanitize() + c.Runtime.Sanitize() + c.Defaults.Sanitize() + c.GuiServer.Sanitize() +} + func DefaultConfig() Config { return Config{ Environment: core.UniversalEnvironment, @@ -153,6 +170,9 @@ type GeneralConfig struct { var _ config.Config = &GeneralConfig{} +func (g *GeneralConfig) Sanitize() { +} + func (g *GeneralConfig) Validate() error { return nil } diff --git a/pkg/config/app/kuma-dp/config.go b/pkg/config/app/kuma-dp/config.go index 34e44c905d83..9509bb2f7c71 100644 --- a/pkg/config/app/kuma-dp/config.go +++ b/pkg/config/app/kuma-dp/config.go @@ -39,6 +39,12 @@ type Config struct { DataplaneRuntime DataplaneRuntime `yaml:"dataplaneRuntime,omitempty"` } +func (c *Config) Sanitize() { + c.ControlPlane.Sanitize() + c.Dataplane.Sanitize() + c.DataplaneRuntime.Sanitize() +} + // ControlPlane defines coordinates of the Control Plane. type ControlPlane struct { // ApiServer defines coordinates of the Control Plane API Server @@ -89,6 +95,10 @@ func (c *Config) Validate() (errs error) { var _ config.Config = &ControlPlane{} +func (c *ControlPlane) Sanitize() { + c.ApiServer.Sanitize() +} + func (c *ControlPlane) Validate() (errs error) { if err := c.ApiServer.Validate(); err != nil { errs = multierr.Append(errs, errors.Wrapf(err, ".ApiServer is not valid")) @@ -98,6 +108,9 @@ func (c *ControlPlane) Validate() (errs error) { var _ config.Config = &Dataplane{} +func (d *Dataplane) Sanitize() { +} + func (d *Dataplane) Validate() (errs error) { if d.Mesh == "" { errs = multierr.Append(errs, errors.Errorf(".Mesh must be non-empty")) @@ -116,6 +129,9 @@ func (d *Dataplane) Validate() (errs error) { var _ config.Config = &DataplaneRuntime{} +func (d *DataplaneRuntime) Sanitize() { +} + func (d *DataplaneRuntime) Validate() (errs error) { if d.BinaryPath == "" { errs = multierr.Append(errs, errors.Errorf(".BinaryPath must be non-empty")) @@ -123,6 +139,11 @@ func (d *DataplaneRuntime) Validate() (errs error) { return } +var _ config.Config = &ApiServer{} + +func (d *ApiServer) Sanitize() { +} + func (d *ApiServer) Validate() (errs error) { if d.URL == "" { errs = multierr.Append(errs, errors.Errorf(".URL must be non-empty")) diff --git a/pkg/config/app/kuma-injector/config.go b/pkg/config/app/kuma-injector/config.go index 26ac27b6287d..7bb8d51443d9 100644 --- a/pkg/config/app/kuma-injector/config.go +++ b/pkg/config/app/kuma-injector/config.go @@ -88,6 +88,9 @@ type WebHookServer struct { CertDir string `yaml:"certDir,omitempty" envconfig:"kuma_injector_webhook_server_cert_dir"` } +func (s *WebHookServer) Sanitize() { +} + // Injector defines configuration of a Kuma Sidecar Injector. type Injector struct { // ControlPlane defines coordinates of the Kuma Control Plane. @@ -190,6 +193,11 @@ type InitContainer struct { var _ config.Config = &Config{} +func (c *Config) Sanitize() { + c.Injector.Sanitize() + c.WebHookServer.Sanitize() +} + func (c *Config) Validate() (errs error) { if err := c.WebHookServer.Validate(); err != nil { errs = multierr.Append(errs, errors.Wrapf(err, ".WebHookServer is not valid")) @@ -217,6 +225,12 @@ func (s *WebHookServer) Validate() (errs error) { var _ config.Config = &Injector{} +func (i *Injector) Sanitize() { + i.ControlPlane.Sanitize() + i.InitContainer.Sanitize() + i.SidecarContainer.Sanitize() +} + func (i *Injector) Validate() (errs error) { if err := i.ControlPlane.Validate(); err != nil { errs = multierr.Append(errs, errors.Wrapf(err, ".ControlPlane is not valid")) @@ -232,6 +246,10 @@ func (i *Injector) Validate() (errs error) { var _ config.Config = &ControlPlane{} +func (c *ControlPlane) Sanitize() { + c.ApiServer.Sanitize() +} + func (c *ControlPlane) Validate() (errs error) { if err := c.ApiServer.Validate(); err != nil { errs = multierr.Append(errs, errors.Wrapf(err, ".ApiServer is not valid")) @@ -241,6 +259,9 @@ func (c *ControlPlane) Validate() (errs error) { var _ config.Config = &ApiServer{} +func (s *ApiServer) Sanitize() { +} + func (s *ApiServer) Validate() (errs error) { if s.URL == "" { errs = multierr.Append(errs, errors.Errorf(".URL must be non-empty")) @@ -255,6 +276,12 @@ func (s *ApiServer) Validate() (errs error) { var _ config.Config = &SidecarContainer{} +func (c *SidecarContainer) Sanitize() { + c.Resources.Sanitize() + c.LivenessProbe.Sanitize() + c.ReadinessProbe.Sanitize() +} + func (c *SidecarContainer) Validate() (errs error) { if c.Image == "" { errs = multierr.Append(errs, errors.Errorf(".Image must be non-empty")) @@ -282,6 +309,9 @@ func (c *SidecarContainer) Validate() (errs error) { var _ config.Config = &InitContainer{} +func (c *InitContainer) Sanitize() { +} + func (c *InitContainer) Validate() (errs error) { if c.Image == "" { errs = multierr.Append(errs, errors.Errorf(".Image must be non-empty")) @@ -291,6 +321,9 @@ func (c *InitContainer) Validate() (errs error) { var _ config.Config = &SidecarReadinessProbe{} +func (c *SidecarReadinessProbe) Sanitize() { +} + func (c *SidecarReadinessProbe) Validate() (errs error) { if c.InitialDelaySeconds < 1 { errs = multierr.Append(errs, errors.Errorf(".InitialDelaySeconds must be >= 1")) @@ -312,6 +345,9 @@ func (c *SidecarReadinessProbe) Validate() (errs error) { var _ config.Config = &SidecarLivenessProbe{} +func (c *SidecarLivenessProbe) Sanitize() { +} + func (c *SidecarLivenessProbe) Validate() (errs error) { if c.InitialDelaySeconds < 1 { errs = multierr.Append(errs, errors.Errorf(".InitialDelaySeconds must be >= 1")) @@ -330,6 +366,14 @@ func (c *SidecarLivenessProbe) Validate() (errs error) { var _ config.Config = &SidecarResources{} +func (c *SidecarResources) Sanitize() { + c.Limits.Sanitize() + c.Requests.Sanitize() +} + +func (c *SidecarResourceRequests) Sanitize() { +} + func (c *SidecarResources) Validate() (errs error) { if err := c.Requests.Validate(); err != nil { errs = multierr.Append(errs, errors.Wrapf(err, ".Requests is not valid")) @@ -354,6 +398,9 @@ func (c *SidecarResourceRequests) Validate() (errs error) { var _ config.Config = &SidecarResourceLimits{} +func (c *SidecarResourceLimits) Sanitize() { +} + func (c *SidecarResourceLimits) Validate() (errs error) { if _, err := kube_api.ParseQuantity(c.CPU); err != nil { errs = multierr.Append(errs, errors.Wrapf(err, ".CPU is not valid")) diff --git a/pkg/config/config.go b/pkg/config/config.go index 91e03c79a6ba..cce72f1c3981 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -1,5 +1,8 @@ package config +const SanitizedValue = "*****" + type Config interface { + Sanitize() Validate() error } diff --git a/pkg/config/core/discovery/config.go b/pkg/config/core/discovery/config.go index 4e27fa2dc8ce..40c6fceb07d5 100644 --- a/pkg/config/core/discovery/config.go +++ b/pkg/config/core/discovery/config.go @@ -12,6 +12,10 @@ type DiscoveryConfig struct { Universal *universal.UniversalDiscoveryConfig `yaml:"universal"` } +func (d *DiscoveryConfig) Sanitize() { + d.Universal.Sanitize() +} + func (d *DiscoveryConfig) Validate() error { return errors.Wrap(d.Universal.Validate(), "Discovery validation failed") } diff --git a/pkg/config/core/resources/store/config.go b/pkg/config/core/resources/store/config.go index 4035e3c3e6e0..6dc5cc6169a7 100644 --- a/pkg/config/core/resources/store/config.go +++ b/pkg/config/core/resources/store/config.go @@ -36,6 +36,11 @@ func DefaultStoreConfig() *StoreConfig { } } +func (s *StoreConfig) Sanitize() { + s.Kubernetes.Sanitize() + s.Postgres.Sanitize() +} + func (s *StoreConfig) Validate() error { switch s.Type { case PostgresStore: diff --git a/pkg/config/display.go b/pkg/config/display.go new file mode 100644 index 000000000000..f1f58d17933b --- /dev/null +++ b/pkg/config/display.go @@ -0,0 +1,29 @@ +package config + +import ( + "encoding/json" + "reflect" +) + +func ConfigForDisplay(cfg Config) (Config, error) { + // copy config so we don't override values, because nested structs in config are pointers + newCfg, err := copyConfig(cfg) + if err != nil { + return nil, err + } + newCfg.Sanitize() + return newCfg, nil +} + +func copyConfig(cfg Config) (Config, error) { + cfgBytes, err := json.Marshal(cfg) + if err != nil { + return nil, err + } + + newCfg := reflect.New(reflect.TypeOf(cfg).Elem()).Interface().(Config) + if err := json.Unmarshal(cfgBytes, newCfg); err != nil { + return nil, err + } + return newCfg, nil +} diff --git a/pkg/config/gui-server/config.go b/pkg/config/gui-server/config.go index 1e0d27f970e1..20c4cdd01c5a 100644 --- a/pkg/config/gui-server/config.go +++ b/pkg/config/gui-server/config.go @@ -10,7 +10,10 @@ type GuiServerConfig struct { // Port on which the server is exposed Port uint32 `yaml:"port" envconfig:"kuma_gui_server_port"` // Config of the GUI itself - GuiConfig *GuiConfig + GuiConfig *GuiConfig `yaml:"-"` +} + +func (g *GuiServerConfig) Sanitize() { } func (g *GuiServerConfig) Validate() error { diff --git a/pkg/config/loader.go b/pkg/config/loader.go index c0dcbf2e9ff2..9843492a523e 100644 --- a/pkg/config/loader.go +++ b/pkg/config/loader.go @@ -2,10 +2,10 @@ package config import ( "github.com/Kong/kuma/pkg/core" - //"github.com/ghodss/yaml" "github.com/kelseyhightower/envconfig" "github.com/pkg/errors" - "gopkg.in/yaml.v2" // todo(jakubdyszkiewicz) switch to "github.com/ghodss/yaml" when solved problems with loading xdsServer + // we use gopkg.in/yaml.v2 because it supports time.Duration + "gopkg.in/yaml.v2" "io/ioutil" "os" ) diff --git a/pkg/config/plugins/discovery/universal/config.go b/pkg/config/plugins/discovery/universal/config.go index 8f9bbff5a51e..8ab2e99bcb4c 100644 --- a/pkg/config/plugins/discovery/universal/config.go +++ b/pkg/config/plugins/discovery/universal/config.go @@ -13,6 +13,9 @@ type UniversalDiscoveryConfig struct { PollingInterval time.Duration `yaml:"pollingInterval" envconfig:"kuma_discovery_universal_polling_interval"` } +func (u UniversalDiscoveryConfig) Sanitize() { +} + func (u UniversalDiscoveryConfig) Validate() error { return nil } diff --git a/pkg/config/plugins/resources/k8s/config.go b/pkg/config/plugins/resources/k8s/config.go index 67b709e9a841..b2f40f0984f1 100644 --- a/pkg/config/plugins/resources/k8s/config.go +++ b/pkg/config/plugins/resources/k8s/config.go @@ -20,6 +20,9 @@ type KubernetesStoreConfig struct { var _ config.Config = &KubernetesStoreConfig{} +func (p *KubernetesStoreConfig) Sanitize() { +} + func (p *KubernetesStoreConfig) Validate() error { if len(p.SystemNamespace) < 1 { return errors.New("SystemNamespace should not be empty") diff --git a/pkg/config/plugins/resources/postgres/config.go b/pkg/config/plugins/resources/postgres/config.go index 5f73505a21f8..541c40c15d78 100644 --- a/pkg/config/plugins/resources/postgres/config.go +++ b/pkg/config/plugins/resources/postgres/config.go @@ -24,6 +24,10 @@ type PostgresStoreConfig struct { ConnectionTimeout int `yaml:"connectionTimeout" envconfig:"kuma_store_postgres_connection_timeout"` } +func (p *PostgresStoreConfig) Sanitize() { + p.Password = config.SanitizedValue +} + func (p *PostgresStoreConfig) Validate() error { if len(p.Host) < 1 { return errors.New("Host should not be empty") diff --git a/pkg/config/plugins/runtime/config.go b/pkg/config/plugins/runtime/config.go index f398cd02b2ca..5e2fff29b4ff 100644 --- a/pkg/config/plugins/runtime/config.go +++ b/pkg/config/plugins/runtime/config.go @@ -19,6 +19,10 @@ type RuntimeConfig struct { Kubernetes *k8s.KubernetesRuntimeConfig `yaml:"kubernetes"` } +func (c *RuntimeConfig) Sanitize() { + c.Kubernetes.Sanitize() +} + func (c *RuntimeConfig) Validate(env core.EnvironmentType) error { switch env { case core.KubernetesEnvironment: diff --git a/pkg/config/plugins/runtime/k8s/config.go b/pkg/config/plugins/runtime/k8s/config.go index c5ceebb8b28a..b089e981cda9 100644 --- a/pkg/config/plugins/runtime/k8s/config.go +++ b/pkg/config/plugins/runtime/k8s/config.go @@ -35,6 +35,9 @@ type AdmissionServerConfig struct { var _ config.Config = &KubernetesRuntimeConfig{} +func (c *KubernetesRuntimeConfig) Sanitize() { +} + func (c *KubernetesRuntimeConfig) Validate() error { if err := c.AdmissionServer.Validate(); err != nil { return errors.Wrap(err, "Admission Server validation failed") @@ -44,6 +47,9 @@ func (c *KubernetesRuntimeConfig) Validate() error { var _ config.Config = &AdmissionServerConfig{} +func (c *AdmissionServerConfig) Sanitize() { +} + func (c *AdmissionServerConfig) Validate() error { if 65535 < c.Port { return errors.New("Port must be in the range [0, 65535]") diff --git a/pkg/config/sds/config.go b/pkg/config/sds/config.go index fba9e951d1f9..83f955974afb 100644 --- a/pkg/config/sds/config.go +++ b/pkg/config/sds/config.go @@ -24,6 +24,9 @@ type SdsServerConfig struct { var _ config.Config = &SdsServerConfig{} +func (c *SdsServerConfig) Sanitize() { +} + func (c *SdsServerConfig) Validate() error { if c.GrpcPort < 0 { return errors.New("GrpcPort cannot be negative") diff --git a/pkg/config/token-server/config.go b/pkg/config/token-server/config.go index 254e6d2e331b..15d65ab337bd 100644 --- a/pkg/config/token-server/config.go +++ b/pkg/config/token-server/config.go @@ -25,6 +25,11 @@ type DataplaneTokenServerConfig struct { Public *PublicDataplaneTokenServerConfig `yaml:"public"` } +func (i *DataplaneTokenServerConfig) Sanitize() { + i.Public.Sanitize() + i.Local.Sanitize() +} + func (i *DataplaneTokenServerConfig) Validate() error { if err := i.Local.Validate(); err != nil { return errors.Wrap(err, "Local validation failed") @@ -46,6 +51,9 @@ type LocalDataplaneTokenServerConfig struct { var _ config.Config = &LocalDataplaneTokenServerConfig{} +func (l *LocalDataplaneTokenServerConfig) Sanitize() { +} + func (l *LocalDataplaneTokenServerConfig) Validate() error { if l.Port > 65535 { return errors.New("Port must be in the range [0, 65535]") @@ -88,6 +96,9 @@ func DefaultPublicDataplaneTokenServerConfig() *PublicDataplaneTokenServerConfig } } +func (p *PublicDataplaneTokenServerConfig) Sanitize() { +} + func (p *PublicDataplaneTokenServerConfig) Validate() error { if p.Port > 65535 { return errors.New("Port must be in the range [0, 65535]") diff --git a/pkg/config/util.go b/pkg/config/util.go index 64ada0060cd4..a73a88a8f1e3 100644 --- a/pkg/config/util.go +++ b/pkg/config/util.go @@ -1,6 +1,7 @@ package config import ( + ghodss_yaml "github.com/ghodss/yaml" "gopkg.in/yaml.v2" ) @@ -11,3 +12,12 @@ func FromYAML(content []byte, cfg Config) error { func ToYAML(cfg Config) ([]byte, error) { return yaml.Marshal(cfg) } + +func ToJson(cfg Config) ([]byte, error) { + yamlBytes, err := ToYAML(cfg) + if err != nil { + return nil, err + } + // there is no easy way to convert yaml to json using gopkg.in/yaml.v2 + return ghodss_yaml.YAMLToJSON(yamlBytes) +} diff --git a/pkg/config/xds/bootstrap/config.go b/pkg/config/xds/bootstrap/config.go index ce4b5d15f05f..7af89c857973 100644 --- a/pkg/config/xds/bootstrap/config.go +++ b/pkg/config/xds/bootstrap/config.go @@ -18,6 +18,10 @@ type BootstrapServerConfig struct { Params *BootstrapParamsConfig `yaml:"params"` } +func (b *BootstrapServerConfig) Sanitize() { + b.Params.Sanitize() +} + func (b *BootstrapServerConfig) Validate() error { if b.Port > 65535 { return errors.New("Port must be in the range [0, 65535]") @@ -52,6 +56,9 @@ type BootstrapParamsConfig struct { XdsConnectTimeout time.Duration `yaml:"xdsConnectTimeout" envconfig:"kuma_bootstrap_server_params_xds_connect_timeout"` } +func (b *BootstrapParamsConfig) Sanitize() { +} + func (b *BootstrapParamsConfig) Validate() error { if b.AdminAddress == "" { return errors.New("AdminAddress cannot be empty") diff --git a/pkg/config/xds/config.go b/pkg/config/xds/config.go index 8b5cc4349162..cf65a510ff9b 100644 --- a/pkg/config/xds/config.go +++ b/pkg/config/xds/config.go @@ -23,6 +23,9 @@ type XdsServerConfig struct { DataplaneStatusFlushInterval time.Duration `yaml:"dataplaneStatusFlushInterval" envconfig:"kuma_xds_server_dataplane_status_flush_interval"` } +func (x *XdsServerConfig) Sanitize() { +} + func (x *XdsServerConfig) Validate() error { if x.GrpcPort < 0 { return errors.New("GrpcPort cannot be negative")