Add events
This commit is contained in:
		
							parent
							
								
									9d4c56545e
								
							
						
					
					
						commit
						ec248f2d42
					
				|  | @ -9,6 +9,7 @@ import ( | ||||||
| 
 | 
 | ||||||
| 	"github.com/VirtusLab/jenkins-operator/pkg/apis" | 	"github.com/VirtusLab/jenkins-operator/pkg/apis" | ||||||
| 	"github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins" | 	"github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins" | ||||||
|  | 	"github.com/VirtusLab/jenkins-operator/pkg/event" | ||||||
| 	"github.com/VirtusLab/jenkins-operator/pkg/log" | 	"github.com/VirtusLab/jenkins-operator/pkg/log" | ||||||
| 	"github.com/VirtusLab/jenkins-operator/version" | 	"github.com/VirtusLab/jenkins-operator/version" | ||||||
| 
 | 
 | ||||||
|  | @ -79,8 +80,14 @@ func main() { | ||||||
| 		fatal(err, "failed to setup scheme") | 		fatal(err, "failed to setup scheme") | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	// setup events
 | ||||||
|  | 	events, err := event.New(cfg) | ||||||
|  | 	if err != nil { | ||||||
|  | 		fatal(err, "failed to create manager") | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	// setup Jenkins controller
 | 	// setup Jenkins controller
 | ||||||
| 	if err := jenkins.Add(mgr, *local, *minikube); err != nil { | 	if err := jenkins.Add(mgr, *local, *minikube, events); err != nil { | ||||||
| 		fatal(err, "failed to setup controllers") | 		fatal(err, "failed to setup controllers") | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -9,11 +9,13 @@ import ( | ||||||
| 	"github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/configuration/user" | 	"github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/configuration/user" | ||||||
| 	"github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/constants" | 	"github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/constants" | ||||||
| 	"github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/plugins" | 	"github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/plugins" | ||||||
|  | 	"github.com/VirtusLab/jenkins-operator/pkg/event" | ||||||
| 	"github.com/VirtusLab/jenkins-operator/pkg/log" | 	"github.com/VirtusLab/jenkins-operator/pkg/log" | ||||||
| 
 | 
 | ||||||
| 	"github.com/go-logr/logr" | 	"github.com/go-logr/logr" | ||||||
|  | 	"github.com/pkg/errors" | ||||||
| 	corev1 "k8s.io/api/core/v1" | 	corev1 "k8s.io/api/core/v1" | ||||||
| 	"k8s.io/apimachinery/pkg/api/errors" | 	apierrors "k8s.io/apimachinery/pkg/api/errors" | ||||||
| 	"k8s.io/apimachinery/pkg/api/resource" | 	"k8s.io/apimachinery/pkg/api/resource" | ||||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||||
| 	"k8s.io/apimachinery/pkg/runtime" | 	"k8s.io/apimachinery/pkg/runtime" | ||||||
|  | @ -25,19 +27,26 @@ import ( | ||||||
| 	"sigs.k8s.io/controller-runtime/pkg/source" | 	"sigs.k8s.io/controller-runtime/pkg/source" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
|  | const ( | ||||||
|  | 	ReasonBaseConfigurationSuccess event.Reason = "BaseConfigurationSuccess" | ||||||
|  | 	ReasonBaseConfigurationFailure event.Reason = "BaseConfigurationFailure" | ||||||
|  | 	ReasonCRValidationFailure      event.Reason = "CRValidationFailure" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
| // Add creates a new Jenkins Controller and adds it to the Manager. The Manager will set fields on the Controller
 | // Add creates a new Jenkins Controller and adds it to the Manager. The Manager will set fields on the Controller
 | ||||||
| // and Start it when the Manager is Started.
 | // and Start it when the Manager is Started.
 | ||||||
| func Add(mgr manager.Manager, local, minikube bool) error { | func Add(mgr manager.Manager, local, minikube bool, events event.Recorder) error { | ||||||
| 	return add(mgr, newReconciler(mgr, local, minikube)) | 	return add(mgr, newReconciler(mgr, local, minikube, events)) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // newReconciler returns a new reconcile.Reconciler
 | // newReconciler returns a new reconcile.Reconciler
 | ||||||
| func newReconciler(mgr manager.Manager, local, minikube bool) reconcile.Reconciler { | func newReconciler(mgr manager.Manager, local, minikube bool, events event.Recorder) reconcile.Reconciler { | ||||||
| 	return &ReconcileJenkins{ | 	return &ReconcileJenkins{ | ||||||
| 		client:   mgr.GetClient(), | 		client:   mgr.GetClient(), | ||||||
| 		scheme:   mgr.GetScheme(), | 		scheme:   mgr.GetScheme(), | ||||||
| 		local:    local, | 		local:    local, | ||||||
| 		minikube: minikube, | 		minikube: minikube, | ||||||
|  | 		events:   events, | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -85,6 +94,7 @@ type ReconcileJenkins struct { | ||||||
| 	client          client.Client | 	client          client.Client | ||||||
| 	scheme          *runtime.Scheme | 	scheme          *runtime.Scheme | ||||||
| 	local, minikube bool | 	local, minikube bool | ||||||
|  | 	events          event.Recorder | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Reconcile it's a main reconciliation loop which maintain desired state based on Jenkins.Spec
 | // Reconcile it's a main reconciliation loop which maintain desired state based on Jenkins.Spec
 | ||||||
|  | @ -93,7 +103,7 @@ func (r *ReconcileJenkins) Reconcile(request reconcile.Request) (reconcile.Resul | ||||||
| 	logger.V(log.VDebug).Info("Reconciling Jenkins") | 	logger.V(log.VDebug).Info("Reconciling Jenkins") | ||||||
| 
 | 
 | ||||||
| 	result, err := r.reconcile(request, logger) | 	result, err := r.reconcile(request, logger) | ||||||
| 	if err != nil && errors.IsConflict(err) { | 	if err != nil && apierrors.IsConflict(err) { | ||||||
| 		logger.V(log.VWarn).Info(err.Error()) | 		logger.V(log.VWarn).Info(err.Error()) | ||||||
| 		return reconcile.Result{Requeue: true}, nil | 		return reconcile.Result{Requeue: true}, nil | ||||||
| 	} else if err != nil { | 	} else if err != nil { | ||||||
|  | @ -108,7 +118,7 @@ func (r *ReconcileJenkins) reconcile(request reconcile.Request, logger logr.Logg | ||||||
| 	jenkins := &virtuslabv1alpha1.Jenkins{} | 	jenkins := &virtuslabv1alpha1.Jenkins{} | ||||||
| 	err := r.client.Get(context.TODO(), request.NamespacedName, jenkins) | 	err := r.client.Get(context.TODO(), request.NamespacedName, jenkins) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		if errors.IsNotFound(err) { | 		if apierrors.IsNotFound(err) { | ||||||
| 			// Request object not found, could have been deleted after reconcile request.
 | 			// Request object not found, could have been deleted after reconcile request.
 | ||||||
| 			// Owned objects are automatically garbage collected. For additional cleanup logic use finalizers.
 | 			// Owned objects are automatically garbage collected. For additional cleanup logic use finalizers.
 | ||||||
| 			// Return and don't requeue
 | 			// Return and don't requeue
 | ||||||
|  | @ -128,16 +138,19 @@ func (r *ReconcileJenkins) reconcile(request reconcile.Request, logger logr.Logg | ||||||
| 
 | 
 | ||||||
| 	valid, err := baseConfiguration.Validate(jenkins) | 	valid, err := baseConfiguration.Validate(jenkins) | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return reconcile.Result{}, err | 		r.events.Emitf(jenkins, event.TypeWarning, ReasonBaseConfigurationFailure, "Base configuration failed: %s", err) | ||||||
|  | 		return reconcile.Result{}, errors.Wrap(err, "Base configuration failed") | ||||||
| 	} | 	} | ||||||
| 	if !valid { | 	if !valid { | ||||||
| 		logger.V(log.VWarn).Info("Validation of user configuration failed, please correct Jenkins CR") | 		r.events.Emit(jenkins, event.TypeWarning, ReasonCRValidationFailure, "Base CR validation failed") | ||||||
|  | 		logger.V(log.VWarn).Info("Validation of base configuration failed, please correct Jenkins CR") | ||||||
| 		return reconcile.Result{}, nil // don't requeue
 | 		return reconcile.Result{}, nil // don't requeue
 | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	result, jenkinsClient, err := baseConfiguration.Reconcile() | 	result, jenkinsClient, err := baseConfiguration.Reconcile() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return reconcile.Result{}, err | 		r.events.Emitf(jenkins, event.TypeWarning, ReasonBaseConfigurationFailure, "Base configuration failed: %s", err) | ||||||
|  | 		return reconcile.Result{}, errors.Wrap(err, "Base configuration failed") | ||||||
| 	} | 	} | ||||||
| 	if result.Requeue { | 	if result.Requeue { | ||||||
| 		return result, nil | 		return result, nil | ||||||
|  | @ -151,9 +164,9 @@ func (r *ReconcileJenkins) reconcile(request reconcile.Request, logger logr.Logg | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
| 			return reconcile.Result{}, err | 			return reconcile.Result{}, err | ||||||
| 		} | 		} | ||||||
|  | 		r.events.Emit(jenkins, event.TypeNormal, ReasonBaseConfigurationSuccess, "Base configuration completed") | ||||||
| 		logger.Info("Base configuration completed time has been updated") | 		logger.Info("Base configuration completed time has been updated") | ||||||
| 	} | 	} | ||||||
| 
 |  | ||||||
| 	// Reconcile user configuration
 | 	// Reconcile user configuration
 | ||||||
| 	userConfiguration := user.New(r.client, jenkinsClient, logger, jenkins) | 	userConfiguration := user.New(r.client, jenkinsClient, logger, jenkins) | ||||||
| 
 | 
 | ||||||
|  | @ -163,12 +176,13 @@ func (r *ReconcileJenkins) reconcile(request reconcile.Request, logger logr.Logg | ||||||
| 	} | 	} | ||||||
| 	if !valid { | 	if !valid { | ||||||
| 		logger.V(log.VWarn).Info("Validation of user configuration failed, please correct Jenkins CR") | 		logger.V(log.VWarn).Info("Validation of user configuration failed, please correct Jenkins CR") | ||||||
|  | 		r.events.Emit(jenkins, event.TypeWarning, ReasonCRValidationFailure, "User CR validation failed") | ||||||
| 		return reconcile.Result{}, nil // don't requeue
 | 		return reconcile.Result{}, nil // don't requeue
 | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	result, err = userConfiguration.Reconcile() | 	result, err = userConfiguration.Reconcile() | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		return reconcile.Result{}, err | 		return reconcile.Result{}, errors.Wrap(err, "Base configuration failed") | ||||||
| 	} | 	} | ||||||
| 	if result.Requeue { | 	if result.Requeue { | ||||||
| 		return result, nil | 		return result, nil | ||||||
|  | @ -188,7 +202,7 @@ func (r *ReconcileJenkins) reconcile(request reconcile.Request, logger logr.Logg | ||||||
| 	return reconcile.Result{}, nil | 	return reconcile.Result{}, nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (r *ReconcileJenkins) buildLogger(jenkinsName string) logr.Logger { | func (*ReconcileJenkins) buildLogger(jenkinsName string) logr.Logger { | ||||||
| 	return log.Log.WithValues("cr", jenkinsName) | 	return log.Log.WithValues("cr", jenkinsName) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -0,0 +1,71 @@ | ||||||
|  | package event | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 
 | ||||||
|  | 	"github.com/VirtusLab/jenkins-operator/pkg/controller/jenkins/constants" | ||||||
|  | 
 | ||||||
|  | 	"github.com/golang/glog" | ||||||
|  | 	"k8s.io/api/core/v1" | ||||||
|  | 	"k8s.io/apimachinery/pkg/runtime" | ||||||
|  | 	"k8s.io/client-go/kubernetes" | ||||||
|  | 	"k8s.io/client-go/kubernetes/scheme" | ||||||
|  | 	typedcorev1 "k8s.io/client-go/kubernetes/typed/core/v1" | ||||||
|  | 	"k8s.io/client-go/rest" | ||||||
|  | 	"k8s.io/client-go/tools/record" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | const ( | ||||||
|  | 	// Information only and will not cause any problems
 | ||||||
|  | 	TypeNormal = Type("Normal") | ||||||
|  | 	// These events are to warn that something might go wrong
 | ||||||
|  | 	TypeWarning = Type("Warning") | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | type Type string | ||||||
|  | type Reason string | ||||||
|  | 
 | ||||||
|  | type Recorder interface { | ||||||
|  | 	Emit(object runtime.Object, eventType Type, reason Reason, message string) | ||||||
|  | 	Emitf(object runtime.Object, eventType Type, reason Reason, format string, args ...interface{}) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | type recorder struct { | ||||||
|  | 	recorder record.EventRecorder | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func New(config *rest.Config) (Recorder, error) { | ||||||
|  | 	eventRecorder, err := initializeEventRecorder(config) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	return &recorder{ | ||||||
|  | 		recorder: eventRecorder, | ||||||
|  | 	}, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func initializeEventRecorder(config *rest.Config) (record.EventRecorder, error) { | ||||||
|  | 	client, err := kubernetes.NewForConfig(config) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return nil, err | ||||||
|  | 	} | ||||||
|  | 	eventBroadcaster := record.NewBroadcaster() | ||||||
|  | 	eventBroadcaster.StartLogging(glog.Infof) | ||||||
|  | 	eventBroadcaster.StartRecordingToSink( | ||||||
|  | 		&typedcorev1.EventSinkImpl{ | ||||||
|  | 			Interface: client.CoreV1().Events("")}) | ||||||
|  | 	eventRecorder := eventBroadcaster.NewRecorder( | ||||||
|  | 		scheme.Scheme, | ||||||
|  | 		v1.EventSource{ | ||||||
|  | 			Component: constants.OperatorName}) | ||||||
|  | 	return eventRecorder, nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (r recorder) Emit(object runtime.Object, eventType Type, reason Reason, message string) { | ||||||
|  | 	r.recorder.Event(object, string(eventType), string(reason), message) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (r recorder) Emitf(object runtime.Object, eventType Type, reason Reason, format string, args ...interface{}) { | ||||||
|  | 	r.recorder.Event(object, string(eventType), string(reason), fmt.Sprintf(format, args...)) | ||||||
|  | } | ||||||
		Loading…
	
		Reference in New Issue