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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

馃摉Adding ComponentConfig proposal #818

Conversation

christopherhein
Copy link
Member

@christopherhein christopherhein commented Feb 25, 2020

This is a proposal for how we can integrate ComponentConfig into controller-runtime without breaking existing implementations and allows controller authors an easier way to configure their controllers.

This was originally documented in #518

This uses the new design proposals from designs/template.md for a working example see christopherhein/github-controller#5

Signed-off-by: Chris Hein me@chrishein.com

@k8s-ci-robot k8s-ci-robot added the cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. label Feb 25, 2020
@k8s-ci-robot k8s-ci-robot added the size/L Denotes a PR that changes 100-499 lines, ignoring generated files. label Feb 25, 2020
@christopherhein
Copy link
Member Author

/assign @vincepri

Copy link

@stealthybox stealthybox left a comment

Choose a reason for hiding this comment

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

Small grammar edits + a question

designs/component-config.md Outdated Show resolved Hide resolved
designs/component-config.md Outdated Show resolved Hide resolved
designs/component-config.md Outdated Show resolved Hide resolved
designs/component-config.md Outdated Show resolved Hide resolved
Copy link

@shawn-hurley shawn-hurley left a comment

Choose a reason for hiding this comment

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

I really like that we standardizing on a controller configuration format thanks for putting this together, sorry the review took so long.

Can we make it easier to use a default component config by providing the struct/methods and unmarshaling?

designs/component-config.md Show resolved Hide resolved
designs/component-config.md Outdated Show resolved Hide resolved
@christopherhein christopherhein force-pushed the proposal/component-config branch 2 times, most recently from 1740c99 to d74b31d Compare March 3, 2020 08:06
@christopherhein
Copy link
Member Author

@stealthybox @shawn-hurley updated with new DefaultControllerConfig struct, and using unmarshalling built into the NewForComponentConfig() func.

@christopherhein christopherhein force-pushed the proposal/component-config branch 2 times, most recently from 7aae5bd to 33ccd9a Compare March 5, 2020 01:39
@christopherhein
Copy link
Member Author

@stealthybox @shawn-hurley updated again to include the embeddable type of metav1alpha1.RuntimeConfig and adding how that supports DefaultControllerConfiguration.

Thanks again for taking a look at this.

designs/component-config.md Show resolved Hide resolved
designs/component-config.md Show resolved Hide resolved
Copy link

@shawn-hurley shawn-hurley left a comment

Choose a reason for hiding this comment

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

Just to make sure that I am following,

  1. the first pass is to create the meta/config types and the default type and new NewManager method such that a user could use all the default stuff.

  2. A new design on how a user could extend the default stuff including adding scaffolding for that?

designs/component-config.md Outdated Show resolved Hide resolved
designs/component-config.md Show resolved Hide resolved
@christopherhein
Copy link
Member Author

2. A new design on how a user could extend the default stuff including adding scaffolding for that?

Correct and #2 will be another PR into Kubebuilder as I'd assume the scaffolding will live there. I'm holding off submitting that until we have this one ironed out.

@christopherhein christopherhein force-pushed the proposal/component-config branch 2 times, most recently from 5655dcd to fce7c66 Compare March 11, 2020 00:29
@christopherhein
Copy link
Member Author

christopherhein commented Mar 11, 2020

@mtaufen @lavalamp @shawn-hurley @stealthybox thanks for all the feedback, this has been updated with the most recent changes:

  • Renamed embedded RuntimeConfig to ControllerConfiguration
  • Moved the embedded types into pkg/api/config/v1alpha1/types.go so they'll now will live with the DefaultControllerConfiguration
  • Cleaned up some wording.

Appreciate the time reviewing this 馃槂

Copy link
Contributor

@djzager djzager left a comment

Choose a reason for hiding this comment

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

Nice work.

designs/component-config.md Outdated Show resolved Hide resolved
designs/component-config.md Outdated Show resolved Hide resolved
designs/component-config.md Show resolved Hide resolved
designs/component-config.md Show resolved Hide resolved
@christopherhein
Copy link
Member Author

@shawn-hurley @mtaufen @stealthybox @vincepri any more feedback, I'd love to start moving this forward and get a implementation in place.

@mtaufen
Copy link

mtaufen commented Mar 25, 2020

Forge ahead! :)

Do take a spin through the Versioned Component Configuration Files doc (2018) while you're implementing and see how this compares (kubernetes-dev membership grants access).

/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Mar 25, 2020

#### Using Flags w/ ComponentConfig

Since this design still requires setting up the initial `ComponentConfig` type and passing in a pointer to `ctrl.NewFromComponentConfig()` if you want to allow for the use of flags, your controller can use any of the different flagging interfaces. eg [`flag`](https://golang.org/pkg/flag/), [`pflag`](https://godoc.org/github.com/spf13/pflag), [`flagnum`](https://godoc.org/github.com/luci/luci-go/common/flag/flagenum) and set values on the `ComponentConfig` type prior to passing the pointer into the `ctrl.NewFromComponentConfig()`, example below.
Copy link

Choose a reason for hiding this comment

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

Just FYI for backwards compatibility flags usually need to take precedence over config (unless you can force users to use exclusively flags or config).

Copy link
Member Author

Choose a reason for hiding this comment

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

Good callout, since we're decoding in the same object that the flags could have already been set on there isn't a way I'm aware of to not override existing values while decoding. Have any suggestions?

Choose a reason for hiding this comment

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

save off the flags and apply them after the decode? (merge the options structs together more or less)?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yea, that probably makes the most sense. I personally don't think this needs to be documented in the design doc, do you?

Feeling okay with the rest of this @shawn-hurley ?

Copy link
Member

Choose a reason for hiding this comment

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

Instead of ctrl.NewFromComponentConfig() that returns Manager, would it be reasonable to have ctrl.NewOptionsFromComponentConfig() that returns manager.Options. And then let callers call manager.New() themselves so that they have more flexibility in updating manager.Options after it has been populated?

Copy link
Member Author

Choose a reason for hiding this comment

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

Totally a possibility. I'd originally started with that path and ended up combining the funcs to make the new API quicker to implement.

@shawn-hurley @mtaufen @DirectXMan12 @stealthybox Do you have a preference? The options would be:

  1. Use a single function ctrl.NewFromComponentConfig() which takes the ComponentConfig type and returns a ctrl.Manager.

or

  1. Separate the funcs and make it ctrl.NewOptionsFromComponentConfig() which returns manager.Options that implementation wise would be passed into manager.New().

Copy link
Member

Choose a reason for hiding this comment

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

Another thought would be for the ComponentConfig-populating function to accept a pointer to a manager.Options struct so that something like this would be possible:

func main() {
   opts := manager.Options{}
   _ = flag.StringVar(&opts.Namespace, "namespace", "", "Namespace to watch.")

   ctrl.UpdateOptionsFromComponentConfig(&opts)

   // Parse flags after populating from ComponentConfig so that flags
   // take precedence
   _ = flag.Parse()
   _ = manager.New(ctrl.GetConfigOrDie(), opts)
}

Copy link
Member Author

@christopherhein christopherhein Apr 1, 2020

Choose a reason for hiding this comment

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

We'd need to pass similar params into each func, EG parsing out the ComponentConfig type into the options we need to have the scheme, config filename, the component config type and the Options struct.

func main() {
   opts := manager.Options{}
   _ = flag.StringVar(&opts.Namespace, "namespace", "", "Namespace to watch.")
   _ = flag.StringVar(&filename, "config", "f", "ConmponentConfig type configuration.")

   _ = ctrl.UpdateOptionsFromComponentConfig(scheme, filename, &componentconfig, &opts)

   // Parse flags after populating from ComponentConfig so that flags
   // take precedence
   _ = flag.Parse()
   _ = manager.New(ctrl.GetConfigOrDie(), opts)
}

I think both are fair flows and we could achieve the same goals with a composite function that returns the manager or returns the options.

Does anyone have strong opinions against this? @stealthybox @johnsonj @joelanford @djzager @shawn-hurley @mtaufen

Signed-off-by: Chris Hein <me@chrishein.com>
@k8s-ci-robot k8s-ci-robot removed the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Apr 1, 2020
@joelanford
Copy link
Member

/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Apr 1, 2020
@shawn-hurley
Copy link

/approve

If any other followups we can still discuss here, but let's get an implementation started and if more things come up we can discuss.

@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: christopherhein, shawn-hurley

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@k8s-ci-robot k8s-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Apr 2, 2020
@k8s-ci-robot k8s-ci-robot merged commit be3a066 into kubernetes-sigs:master Apr 2, 2020
@christopherhein christopherhein deleted the proposal/component-config branch April 11, 2020 04:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. lgtm "Looks good to me", indicates that a PR is ready to be merged. size/L Denotes a PR that changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

10 participants