Skip to content

Commit

Permalink
Merge pull request #551 from mengqiy/release-0.2
Browse files Browse the repository at this point in the history
🏃 fast forward release-0.2 branch
  • Loading branch information
k8s-ci-robot authored Aug 7, 2019
2 parents aaddbd9 + 084b73e commit eb94491
Show file tree
Hide file tree
Showing 49 changed files with 1,053 additions and 474 deletions.
2 changes: 1 addition & 1 deletion FAQ.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
**A**: Each controller should only reconcile one object type. Other
affected objects should be mapped to a single type of root object, using
the `EnqueueRequestForOwner` or `EnqueueRequestsFromMapFunc` event
handlers, and potentially indicies. Then, your Reconcile method should
handlers, and potentially indices. Then, your Reconcile method should
attempt to reconcile *all* state for that given root objects.

### Q: How do I have different logic in my reconciler for different types of events (e.g. create, update, delete)?
Expand Down
12 changes: 6 additions & 6 deletions TMP-LOGGING.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ or even write
func (r *Reconciler) Reconcile(req reconcile.Request) (reconcile.Response, error) {
logger := logger.WithValues("pod", req.NamespacedName)
// do some stuff
logger.Info("starting reconcilation")
logger.Info("starting reconciliation")
}
```

Expand All @@ -49,7 +49,7 @@ provides some helpers to make it easy to use

You can configure the logging implementation using
`"sigs.k8s.io/controller-runtime/pkg/log".SetLogger`. That
package also contains the convinience functions for setting up Zap.
package also contains the convenience functions for setting up Zap.

You can get a handle to the the "root" logger using
`"sigs.k8s.io/controller-runtime/pkg/log".Log`, and can then call
Expand All @@ -58,7 +58,7 @@ repeatedly to chain names together:

```go
logger := log.Log.WithName("controller").WithName("replicaset")
// in reconile...
// in reconcile...
logger = logger.WithValues("replicaset", req.NamespacedName)
// later on in reconcile...
logger.Info("doing things with pods", "pod", newPod)
Expand Down Expand Up @@ -86,7 +86,7 @@ Errors should *always* be logged with `log.Error`, which allows logr
implementations to provide special handling of errors (for instance,
providing stack traces in debug mode).

It's acceptible to log call `log.Error` with a nil error object. This
It's acceptable to log call `log.Error` with a nil error object. This
conveys that an error occurred in some capacity, but that no actual
`error` object was involved.

Expand Down Expand Up @@ -125,12 +125,12 @@ logic.

### Groups, Versions, and Kinds

- Kinds should not be logged alone (they're meanless alone). Use
- Kinds should not be logged alone (they're meaningless alone). Use
a `GroupKind` object to log them instead, or a `GroupVersionKind` when
version is relevant.

- If you need to log an API version string, use `api version` as the key
(formatted as with a `GroupVersion`, or as recieved directly from API
(formatted as with a `GroupVersion`, or as received directly from API
discovery).

### Objects and Types
Expand Down
10 changes: 5 additions & 5 deletions VERSIONING.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ greatest code, including breaking changes, happens on master.
The *release-X* branches contain stable, backwards compatible code. Every
major (X) release, a new such branch is created. It is from these
branches that minor and patch releases are tagged. If some cases, it may
be neccessary open PRs for bugfixes directly against stable branches, but
be necessary open PRs for bugfixes directly against stable branches, but
this should generally not be the case.

The maintainers are responsible for updating the contents of this branch;
Expand Down Expand Up @@ -131,7 +131,7 @@ branch, except in exceptional circumstances. Patches will be backported
to maintained stable versions, as needed.

Major releases are done shortly after a breaking change is merged -- once
a breaking change is merged, the next release *must* be a major revison.
a breaking change is merged, the next release *must* be a major revision.
We don't intend to have a lot of these, so we may put off merging breaking
PRs until a later date.

Expand Down Expand Up @@ -172,9 +172,9 @@ have to rewrite their code when they eventually upgrade, and for
maintainers/contributors, who have to deal with differences between master
and stable branches.

That being said, we'll occaisonally want to make breaking changes. They'll
That being said, we'll occasionally want to make breaking changes. They'll
be merged onto master, and will then trigger a major release (see [Release
Proccess](#release-process)). Because breaking changes induce a major
Process](#release-process)). Because breaking changes induce a major
revision, the maintainers may delay a particular breaking change until
a later date when they are ready to make a major revision with a few
breaking changes.
Expand All @@ -187,7 +187,7 @@ Maintainers should treat breaking changes with caution, and evaluate
potential non-breaking solutions (see below).

Note that API breakage in public APIs due to dependencies will trigger
a major revision, so you may occaisonally need to have a major release
a major revision, so you may occasionally need to have a major release
anyway, due to changes in libraries like `k8s.io/client-go` or
`k8s.io/apimachinery`.

Expand Down
2 changes: 1 addition & 1 deletion doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ limitations under the License.
// sources (pkg/source), like Kubernetes API object changes, to event handlers
// (pkg/handler), like "enqueue a reconcile request for the object owner".
// Predicates (pkg/predicate) can be used to filter which events actually
// trigger reconciles. There are pre-written utilies for the common cases, and
// trigger reconciles. There are pre-written utilities for the common cases, and
// interfaces and helpers for advanced cases.
//
// Reconcilers
Expand Down
36 changes: 36 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Examples

These two examples represent the usage of `controller-runtime` libraries for built-in Kubernetes resources as well as custom resources.

### builtins/

This example implements a custom controller and webhooks for the *existing* ReplicaSet resource.

* `controller.go`: implements a reconciler for ReplicaSets
* `mutatingwebhook.go`: implements a mutating webhook that adds an annotation to every incoming Pod ("example-mutating-admission-webhook" = "foo")
* `validatingwebhook.go`: implements a validating webhook that checks to see if a Pod has the aforementioned annotation
* `main.go`
1. Creates a new manager
2. Creates a new controller that watches both ReplicaSets and Pods and reconciles the objects with the implemented reconciler
3. Registers the mutating and validating webhooks with the manager
4. Starts the manager

### crd/

This example implements a *new* Kubernetes resource, ChaosPod, and creates a custom controller that watches it and webhooks that mutate and validate.

* `pkg/`
* `resource.go`: defines the schema for the ChaosPod API and implements validate and mutate webhooks
* `groupversion_info.go`: specifies the Group and Version for the ChaosPod API
* `zz_generated.deepcopy.go`: deep copy functions generated by kubebuilder
* `main.go`
1. Creates a new manager
2. Adds ChaosPod resource to the manager's schema
3. Implements a reconciler to execute the desired behavior of the ChaosPod API
4. Creates a new controller that watches ChaosPods and reconciles the objects with the implemented reconciler
5. Adds ChaosPod webhooks to manager
6. Starts the manager

## Deploying and Running

To install and run the provided examples, see the Kubebuilder [Quick Start](https://book.kubebuilder.io/quick-start.html).
2 changes: 1 addition & 1 deletion examples/builtins/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ type reconcileReplicaSet struct {
var _ reconcile.Reconciler = &reconcileReplicaSet{}

func (r *reconcileReplicaSet) Reconcile(request reconcile.Request) (reconcile.Result, error) {
// set up a convinient log object so we don't have to type request over and over again
// set up a convenient log object so we don't have to type request over and over again
log := r.log.WithValues("request", request)

// Fetch the ReplicaSet from the cache
Expand Down
6 changes: 0 additions & 6 deletions examples/builtins/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ limitations under the License.
package main

import (
"flag"
"os"

appsv1 "k8s.io/api/apps/v1"
Expand All @@ -37,11 +36,6 @@ import (
var log = logf.Log.WithName("example-controller")

func main() {
var disableWebhookConfigInstaller bool
flag.BoolVar(&disableWebhookConfigInstaller, "disable-webhook-config-installer", false,
"disable the installer in the webhook server, so it won't install webhook configuration resources during bootstrapping")

flag.Parse()
logf.SetLogger(zap.Logger(false))
entryLog := log.WithName("entrypoint")

Expand Down
10 changes: 10 additions & 0 deletions examples/crd/pkg/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,16 @@ func (c *ChaosPod) ValidateUpdate(old runtime.Object) error {
return nil
}

// ValidateDelete implements webhookutil.validator so a webhook will be registered for the type
func (c *ChaosPod) ValidateDelete() error {
log.Info("validate delete", "name", c.Name)

if c.Spec.NextStop.Before(&metav1.Time{Time: time.Now()}) {
return fmt.Errorf(".spec.nextStop must be later than current time")
}
return nil
}

// +kubebuilder:webhook:path=/mutate-chaosapps-metamagical-io-v1-chaospod,mutating=true,failurePolicy=fail,groups=chaosapps.metamagical.io,resources=chaospods,verbs=create;update,versions=v1,name=mchaospod.kb.io

var _ webhook.Defaulter = &ChaosPod{}
Expand Down
2 changes: 1 addition & 1 deletion hack/check-everything.sh
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ function fetch_kb_tools {
}

function is_installed {
if [ command -v $1 &>/dev/null ]; then
if command -v "$1" &>/dev/null; then
return 0
fi
return 1
Expand Down
4 changes: 2 additions & 2 deletions pkg/builder/builder_suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ var _ = AfterSuite(func() {

func addCRDToEnvironment(env *envtest.Environment, gvks ...schema.GroupVersionKind) {
for _, gvk := range gvks {
plural, singlar := meta.UnsafeGuessKindToResource(gvk)
plural, singular := meta.UnsafeGuessKindToResource(gvk)
crd := &apiextensionsv1beta1.CustomResourceDefinition{
TypeMeta: metav1.TypeMeta{
APIVersion: "apiextensions.k8s.io",
Expand All @@ -91,7 +91,7 @@ func addCRDToEnvironment(env *envtest.Environment, gvks ...schema.GroupVersionKi
Version: gvk.Version,
Names: apiextensionsv1beta1.CustomResourceDefinitionNames{
Plural: plural.Resource,
Singular: singlar.Resource,
Singular: singular.Resource,
Kind: gvk.Kind,
},
Versions: []apiextensionsv1beta1.CustomResourceDefinitionVersion{
Expand Down
71 changes: 20 additions & 51 deletions pkg/builder/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/rest"
"sigs.k8s.io/controller-runtime/pkg/client/apiutil"
"sigs.k8s.io/controller-runtime/pkg/client/config"
"sigs.k8s.io/controller-runtime/pkg/controller"
"sigs.k8s.io/controller-runtime/pkg/handler"
"sigs.k8s.io/controller-runtime/pkg/manager"
Expand All @@ -33,9 +32,7 @@ import (
)

// Supporting mocking out functions for testing
var getConfig = config.GetConfig
var newController = controller.New
var newManager = manager.New
var getGvk = apiutil.GVKForObject

// Builder builds a Controller.
Expand All @@ -47,19 +44,13 @@ type Builder struct {
watchRequest []watchRequest
config *rest.Config
ctrl controller.Controller
ctrlOptions controller.Options
name string
}

// SimpleController returns a new Builder.
//
// Deprecated: Use ControllerManagedBy(Manager) instead.
func SimpleController() *Builder {
return &Builder{}
}

// ControllerManagedBy returns a new controller builder that will be started by the provided Manager
func ControllerManagedBy(m manager.Manager) *Builder {
return SimpleController().WithManager(m)
return &Builder{mgr: m}
}

// ForType defines the type of Object being *reconciled*, and configures the ControllerManagedBy to respond to create / delete /
Expand Down Expand Up @@ -109,14 +100,6 @@ func (blder *Builder) WithConfig(config *rest.Config) *Builder {
return blder
}

// WithManager sets the Manager to use for registering the ControllerManagedBy. Defaults to a new manager.Manager.
//
// Deprecated: Use ControllerManagedBy(Manager) and this isn't needed.
func (blder *Builder) WithManager(m manager.Manager) *Builder {
blder.mgr = m
return blder
}

// WithEventFilter sets the event filters, to filter which create/update/delete/generic events eventually
// trigger reconciliations. For example, filtering on whether the resource version has changed.
// Defaults to the empty list.
Expand All @@ -125,6 +108,12 @@ func (blder *Builder) WithEventFilter(p predicate.Predicate) *Builder {
return blder
}

// WithOptions overrides the controller options use in doController. Defaults to empty.
func (blder *Builder) WithOptions(options controller.Options) *Builder {
blder.ctrlOptions = options
return blder
}

// Named sets the name of the controller to the given name. The name shows up
// in metrics, among other things, and thus should be a prometheus compatible name
// (underscores and alphanumeric characters only).
Expand All @@ -141,23 +130,17 @@ func (blder *Builder) Complete(r reconcile.Reconciler) error {
return err
}

// Build builds the Application ControllerManagedBy and returns the Manager used to start it.
//
// Deprecated: Use Complete
func (blder *Builder) Build(r reconcile.Reconciler) (manager.Manager, error) {
// Build builds the Application ControllerManagedBy and returns the Controller it created.
func (blder *Builder) Build(r reconcile.Reconciler) (controller.Controller, error) {
if r == nil {
return nil, fmt.Errorf("must provide a non-nil Reconciler")
}

// Set the Config
if err := blder.loadRestConfig(); err != nil {
return nil, err
if blder.mgr == nil {
return nil, fmt.Errorf("must provide a non-nil Manager")
}

// Set the Manager
if err := blder.doManager(); err != nil {
return nil, err
}
// Set the Config
blder.loadRestConfig()

// Set the ControllerManagedBy
if err := blder.doController(r); err != nil {
Expand All @@ -169,7 +152,7 @@ func (blder *Builder) Build(r reconcile.Reconciler) (manager.Manager, error) {
return nil, err
}

return blder.mgr, nil
return blder.ctrl, nil
}

func (blder *Builder) doWatch() error {
Expand Down Expand Up @@ -203,26 +186,10 @@ func (blder *Builder) doWatch() error {
return nil
}

func (blder *Builder) loadRestConfig() error {
if blder.config != nil {
return nil
}
if blder.mgr != nil {
func (blder *Builder) loadRestConfig() {
if blder.config == nil {
blder.config = blder.mgr.GetConfig()
return nil
}
var err error
blder.config, err = getConfig()
return err
}

func (blder *Builder) doManager() error {
if blder.mgr != nil {
return nil
}
var err error
blder.mgr, err = newManager(blder.config, manager.Options{})
return err
}

func (blder *Builder) getControllerName() (string, error) {
Expand All @@ -241,6 +208,8 @@ func (blder *Builder) doController(r reconcile.Reconciler) error {
if err != nil {
return err
}
blder.ctrl, err = newController(name, blder.mgr, controller.Options{Reconciler: r})
ctrlOptions := blder.ctrlOptions
ctrlOptions.Reconciler = r
blder.ctrl, err = newController(name, blder.mgr, ctrlOptions)
return err
}
Loading

0 comments on commit eb94491

Please sign in to comment.