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

feat(kuma-cp) expose config #454

merged 4 commits into from
Nov 26, 2019

Conversation

jakubdyszkiewicz
Copy link
Contributor

Summary

Starting as draft, because of open questions.

  1. Library
    I tried to switch from gopkg.in/yaml.v2 to github.com/ghodss/yaml. It required to change yaml to json annotations, but it turned out that ghodss does not support time.Duration, therefore you cannot put in config stuff like xdsConnectTimeout: 1s. I'd say this is a decrease in UX.

  2. Secret values
    For now, we only want to hide the Postgres password, but who knows what will come next. I see 2 ways to implement this.

    1. via annotation like secret:"true" next to envconfig and yaml. Then scan struct recursivly via reflection and replace it via placeholder. Extra tricky part, the value can be of many types.
    2. Just like validation, we can add func HideSecretValues() method on Config, call that for every subconfig and explicitly replace the values.

    I like the second option better. Although probably a bit more code, it is explicit and less magical.

  3. Pointers in config
    We have to replace secrets in config so we have to copy a config. It's a problem since subconfigs are pointers. We can "hack" it with marshal -> unmarshal, but I'd say it's better to get rid of pointers. It's kind of uncomfortable to think that any component can change the config at any given time of running app.

@@ -10,7 +10,7 @@ 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:"-"`
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't understand. Why don't we want to see this field in YAML ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Otherwise the json/yaml looks wierd. Like this:

{
  "guiServer": {
      "port": 1234,
      "GuiConfig": {
          "ApiUrl": "",
          "Environment": "",
      }
  }
}

everything in config is lowercase instead of this. If we write yaml tags, we will expose this config to the users.

Copy link
Contributor

Choose a reason for hiding this comment

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

Up to you.
Personally, I see the value in exposing the entire config even if it comes at a cost.

@@ -16,7 +16,7 @@ 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 Catalogue
Catalogue *catalogue.CatalogueConfig
Catalogue *catalogue.CatalogueConfig `yaml:"-"`
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't understand. Why don't we want to see this field in 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
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't understand this.

Here is an example of ghodds/yaml doing marshalling/unmarshalling of time.Duration - https://play.golang.org/p/NdpmTyqitmw

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sorry I wasn't clear enough. ghodss supports time.Duration, but you cannot deserialize 2s, you have to write 2000000000 which I'd say is not user friendly at all

Copy link
Contributor

Choose a reason for hiding this comment

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

pkg/config/display.go Outdated Show resolved Hide resolved
pkg/config/display.go Outdated Show resolved Hide resolved
pkg/api-server/server.go Outdated Show resolved Hide resolved
app/kuma-cp/cmd/run.go Outdated Show resolved Hide resolved
pkg/api-server/config_ws_test.go Outdated Show resolved Hide resolved
@yskopets
Copy link
Contributor

it turned out that ghodss does not support time.Duration

I'm not sure I get this. Here is a working example - https://play.golang.org/p/NdpmTyqitmw

I like the second option better. Although probably a bit more code, it is explicit and less magical.

Let's go ahead with it. A more conventional name for that func would be Sanitize()

It's a problem since subconfigs are pointers.

Sub-configs are pointers if (and only if) they're optional. It wouldn't be right to break this convention for the sake of /config feature

@jakubdyszkiewicz jakubdyszkiewicz marked this pull request as ready for review November 22, 2019 16:00
@jakubdyszkiewicz jakubdyszkiewicz requested review from a team and yskopets November 22, 2019 16:00
pkg/api-server/config_ws_test.go Outdated Show resolved Hide resolved
"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
Copy link
Contributor

Choose a reason for hiding this comment

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

runLog.Error(err, "unable to prepare config for display")
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.

pkg/api-server/config_ws.go Outdated Show resolved Hide resolved
@jakubdyszkiewicz
Copy link
Contributor Author

There are workarounds for this, e.g. https://stackoverflow.com/questions/48050945/how-to-unmarshal-json-into-durations

not sure if custom duration time is better.
I'm gonna merge this as it is, but I'm open for discussion!

@jakubdyszkiewicz jakubdyszkiewicz merged commit 87e855a into master Nov 26, 2019
@jakubdyszkiewicz jakubdyszkiewicz deleted the feature/expose-config branch November 26, 2019 11:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants