Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(kuma-cp) expose config #454

Merged
merged 4 commits into from
Nov 26, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions app/kuma-cp/cmd/run.go
Original file line number Diff line number Diff line change
@@ -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"
Expand Down Expand Up @@ -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))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think, logging API is designed in away to avoid explicit fmt.Sprintf()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The problem is that if I the bytes the whole json is escaped which is not readable at all.

if err := sds_server.SetupServer(rt); err != nil {
runLog.Error(err, "unable to set up SDS server")
return err
Expand Down
25 changes: 25 additions & 0 deletions pkg/api-server/config_ws.go
Original file line number Diff line number Diff line change
@@ -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
}
137 changes: 137 additions & 0 deletions pkg/api-server/config_ws_test.go
Original file line number Diff line number Diff line change
@@ -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))
})
})
7 changes: 6 additions & 1 deletion pkg/api-server/resource_api_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
}
25 changes: 18 additions & 7 deletions pkg/api-server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
)
Expand All @@ -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),
Expand All @@ -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,
}
Expand Down Expand Up @@ -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)
}
5 changes: 4 additions & 1 deletion pkg/config/api-server/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
20 changes: 20 additions & 0 deletions pkg/config/app/kuma-cp/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -153,6 +170,9 @@ type GeneralConfig struct {

var _ config.Config = &GeneralConfig{}

func (g *GeneralConfig) Sanitize() {
}

func (g *GeneralConfig) Validate() error {
return nil
}
Expand Down
21 changes: 21 additions & 0 deletions pkg/config/app/kuma-dp/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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"))
Expand All @@ -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"))
Expand All @@ -116,13 +129,21 @@ 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"))
}
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"))
Expand Down
Loading