Skip to content

Commit

Permalink
Document runtime controller package
Browse files Browse the repository at this point in the history
Signed-off-by: Hidde Beydals <[email protected]>
  • Loading branch information
hiddeco committed Jul 7, 2021
1 parent 702679a commit 7c2b0b8
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 34 deletions.
4 changes: 2 additions & 2 deletions runtime/controller/doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

// Package controller offers embeddable structs for putting in your
// controller, to help with conforming to GitOps Toolkit conventions.
// Package controller offers embeddable structs for usage in your controller and underlying reconcilers, to help with
// conforming to GitOps Toolkit conventions.
package controller
34 changes: 17 additions & 17 deletions runtime/controller/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,26 +30,28 @@ import (
"github.com/fluxcd/pkg/runtime/events"
)

// Events is a helper struct that adds the capability of sending
// events to the Kubernetes API and to the GitOps Toolkit notification
// controller. You use it by embedding it in your reconciler struct:
// Events is a helper struct that adds the capability of sending events to the Kubernetes API and an external event
// recorder, like the GitOps Toolkit notification-controller.
//
// type MyTypeReconciler {
// client.Client
// // ... etc.
// controller.Events
// }
// Use it by embedding it in your reconciler struct:
//
// You initialise a suitable value with MakeEvents; in most cases the
// value needs to be initialized once per controller, as the specialised
// logger and object reference data are gathered from the arguments
// provided to the Eventf method.
// type MyTypeReconciler {
// client.Client
// // ... etc.
// controller.Events
// }
//
// Use MakeEvents to create a working Events value; in most cases the value needs to be initialised just once per
// controller, as the specialised logger and object reference data are gathered from the arguments provided to the
// Eventf method.
type Events struct {
Scheme *runtime.Scheme
EventRecorder kuberecorder.EventRecorder
ExternalEventRecorder *events.Recorder
}

// MakeEvents creates a new Events, with the Events.Scheme set to that of the given mgr and a newly initialised
// Events.EventRecorder for the given controllerName.
func MakeEvents(mgr ctrl.Manager, controllerName string, ext *events.Recorder) Events {
return Events{
Scheme: mgr.GetScheme(),
Expand All @@ -58,14 +60,12 @@ func MakeEvents(mgr ctrl.Manager, controllerName string, ext *events.Recorder) E
}
}

// Event emits a Kubernetes event, and forwards the event to the
// notification controller if configured.
// Event emits a Kubernetes event, and forwards the event to the ExternalEventRecorder if configured.
func (e Events) Event(ctx context.Context, obj client.Object, metadata map[string]string, severity, reason, msg string) {
e.Eventf(ctx, obj, metadata, severity, reason, msg)
}

// Eventf emits a Kubernetes event, and forwards the event to the
// notification controller if configured.
// Eventf emits a Kubernetes event, and forwards the event to the ExternalEventRecorder if configured.
func (e Events) Eventf(ctx context.Context, obj client.Object, metadata map[string]string, severity, reason, msgFmt string, args ...interface{}) {
if e.EventRecorder != nil {
e.EventRecorder.Eventf(obj, severityToEventType(severity), reason, msgFmt, args...)
Expand All @@ -83,7 +83,7 @@ func (e Events) Eventf(ctx context.Context, obj client.Object, metadata map[stri
}
}

// severityToEventType maps the given severity string to a corev1 event type.
// severityToEventType maps the given severity string to a corev1 EventType.
// In case of an unrecognised severity, EventTypeNormal is returned.
func severityToEventType(severity string) string {
switch severity {
Expand Down
38 changes: 23 additions & 15 deletions runtime/controller/metrics.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,30 +31,32 @@ import (
"github.com/fluxcd/pkg/runtime/metrics"
)

// Metrics adds the capability for recording GOTK-standard metrics to
// a reconciler. Use by embedding into the reconciler struct:
// Metrics is a helper struct that adds the capability for recording GitOps Toolkit standard metrics to a reconciler.
//
// type MyTypeReconciler struct {
// client.Client
// // ...
// controller.Metrics
// }
// Use it by embedding it in your reconciler struct:
//
// Following the GOTK-standard, API types used in GOTK should implement
// conditions.Getter to work with status condition types, and required
// to be able to record metrics.
// type MyTypeReconciler {
// client.Client
// // ... etc.
// controller.Metrics
// }
//
// When initialising the controllers in main.go, use MustMakeMetrics to
// create a working Metrics value; you can supply the same value to
// all reconcilers.
// Following the GitOps Toolkit conventions, API types used in GOTK SHOULD implement conditions.Getter to work with
// status condition types, and this convention MUST be followed to be able to record metrics using this helper.
//
// Once initialised, metrics can be recorded by calling one of the
// available `Record*` methods.
// Use MustMakeMetrics to create a working Metrics value; you can supply the same value to all reconcilers.
//
// Once initialised, metrics can be recorded by calling one of the available `Record*` methods.
type Metrics struct {
Scheme *runtime.Scheme
MetricsRecorder *metrics.Recorder
}

// MustMakeMetrics creates a new Metrics with a new metrics.Recorder, and the Metrics.Scheme set to that of the given
// mgr.
// It attempts to register the metrics collectors in the controller-runtime metrics registry, which panics upon the
// first registration that causes an error. Which usually happens if you try to initialize a Metrics value twice for
// your controller.
func MustMakeMetrics(mgr ctrl.Manager) Metrics {
metricsRecorder := metrics.NewRecorder()
crtlmetrics.Registry.MustRegister(metricsRecorder.Collectors()...)
Expand All @@ -65,6 +67,7 @@ func MustMakeMetrics(mgr ctrl.Manager) Metrics {
}
}

// RecordDuration records the duration of a reconcile attempt for the given obj based on the given startTime.
func (m Metrics) RecordDuration(ctx context.Context, obj conditions.Getter, startTime time.Time) {
if m.MetricsRecorder != nil {
ref, err := reference.GetReference(m.Scheme, obj)
Expand All @@ -76,6 +79,7 @@ func (m Metrics) RecordDuration(ctx context.Context, obj conditions.Getter, star
}
}

// RecordSuspend records the suspension of the given obj based on the given suspend value.
func (m Metrics) RecordSuspend(ctx context.Context, obj conditions.Getter, suspend bool) {
if m.MetricsRecorder != nil {
ref, err := reference.GetReference(m.Scheme, obj)
Expand All @@ -87,18 +91,22 @@ func (m Metrics) RecordSuspend(ctx context.Context, obj conditions.Getter, suspe
}
}

// RecordReadiness records the meta.ReadyCondition status for the given obj.
func (m Metrics) RecordReadiness(ctx context.Context, obj conditions.Getter) {
m.RecordCondition(ctx, obj, meta.ReadyCondition)
}

// RecordReconciling records the meta.ReconcilingCondition status for the given obj.
func (m Metrics) RecordReconciling(ctx context.Context, obj conditions.Getter) {
m.RecordCondition(ctx, obj, meta.ReconcilingCondition)
}

// RecordStalled records the meta.StalledCondition status for the given obj.
func (m Metrics) RecordStalled(ctx context.Context, obj conditions.Getter) {
m.RecordCondition(ctx, obj, meta.StalledCondition)
}

// RecordCondition records the status of the given conditionType for the given obj.
func (m Metrics) RecordCondition(ctx context.Context, obj conditions.Getter, conditionType string) {
if m.MetricsRecorder == nil {
return
Expand Down

0 comments on commit 7c2b0b8

Please sign in to comment.