@@ -16,55 +16,124 @@ package controllers
1616
1717import (
1818 "context"
19+ "fmt"
20+ "reflect"
21+ "runtime"
1922
23+ "emperror.dev/errors"
24+ "github.com/cisco-open/operator-tools/pkg/reconciler"
2025 "github.com/go-logr/logr"
26+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2127 ctrl "sigs.k8s.io/controller-runtime"
2228 "sigs.k8s.io/controller-runtime/pkg/client"
2329
24- "github.com/kube-logging/logging-operator/pkg/sdk/logging/api/v1beta1"
30+ "github.com/kube-logging/logging-operator/pkg/resources"
31+ axosyslogresources "github.com/kube-logging/logging-operator/pkg/resources/axosyslog"
32+ v1beta1 "github.com/kube-logging/logging-operator/pkg/sdk/logging/api/v1beta1"
2533)
2634
2735// NewAxoSyslogReconciler creates a new AxoSyslogReconciler instance
28- func NewAxoSyslogReconciler (client client.Client , log logr.Logger ) * AxoSyslogReconciler {
36+ func NewAxoSyslogReconciler (client client.Client , log logr.Logger , opts reconciler. ReconcilerOpts ) * AxoSyslogReconciler {
2937 return & AxoSyslogReconciler {
30- Client : client ,
31- Log : log ,
38+ Client : client ,
39+ GenericResourceReconciler : reconciler .NewGenericReconciler (client , log , opts ),
40+ Log : log ,
3241 }
3342}
3443
3544type AxoSyslogReconciler struct {
3645 client.Client
46+ * reconciler.GenericResourceReconciler
3747 Log logr.Logger
3848}
3949
4050// +kubebuilder:rbac:groups=logging.banzaicloud.io,resources=axosyslogs,verbs=get;list;watch;create;update;patch;delete
4151// +kubebuilder:rbac:groups=logging.banzaicloud.io,resources=axosyslogs/status,verbs=get;update;patch
42- // +kubebuilder:rbac:groups="",resources=configmaps;secrets,verbs=get;list;watch;create;update;patch;delete
4352// +kubebuilder:rbac:groups=apps,resources=statefulsets,verbs=get;list;watch;create;update;patch;delete
4453// +kubebuilder:rbac:groups="",resources=services;persistentvolumeclaims;serviceaccounts;pods,verbs=get;list;watch;create;update;patch;delete
45- // +kubebuilder:rbac:groups="rbac.authorization.k8s.io",resources=clusterroles;clusterrolebindings; roles;rolebindings,verbs=get;list;watch;create;update;patch;delete
54+ // +kubebuilder:rbac:groups="rbac.authorization.k8s.io",resources=roles;rolebindings,verbs=get;list;watch;create;update;patch;delete
4655
47- // Reconciles axosyslog resource
56+ // Reconcile implements the reconciliation logic for AxoSyslog resources
4857func (r * AxoSyslogReconciler ) Reconcile (ctx context.Context , req ctrl.Request ) (ctrl.Result , error ) {
49- log := r .Log .WithValues ( "axosyslog" , req . NamespacedName )
58+ r .Log .V ( 1 ). Info ( "Reconciling AxoSyslog" )
5059
51- log .V (1 ).Info ("Reconciling AxoSyslog" )
52-
53- var axosyslog v1beta1.AxoSyslog
54- if err := r .Get (ctx , req .NamespacedName , & axosyslog ); err != nil {
60+ var axoSyslog v1beta1.AxoSyslog
61+ if err := r .Get (ctx , req .NamespacedName , & axoSyslog ); err != nil {
5562 return ctrl.Result {}, client .IgnoreNotFound (err )
5663 }
5764
58- if err := axosyslog .SetDefaults (); err != nil {
65+ log := r .Log .WithValues ("axosyslog" , fmt .Sprintf ("%s/%s" , axoSyslog .Namespace , axoSyslog .Name ))
66+
67+ if err := axoSyslog .SetDefaults (); err != nil {
68+ return ctrl.Result {}, errors .WrapIf (err , "failed to set defaults" )
69+ }
70+
71+ // TODO: config-check ?
72+
73+ if result , err := r .reconcileWorkloadResources (log , & axoSyslog ); err != nil {
5974 return ctrl.Result {}, err
75+ } else if result != nil {
76+ return * result , nil
6077 }
6178
6279 return ctrl.Result {}, nil
6380}
6481
82+ // reconcileWorkloadResources handles resources related to AxoSyslog and requires it's spec
83+ func (r * AxoSyslogReconciler ) reconcileWorkloadResources (log logr.Logger , axoSyslog * v1beta1.AxoSyslog ) (* ctrl.Result , error ) {
84+ resourceBuilders := []resources.ResourceWithSpec {
85+ axosyslogresources .StatefulSet ,
86+ axosyslogresources .Service ,
87+ axosyslogresources .HeadlessService ,
88+ // TODO: service-metrics & buffer-metrics ?
89+ // axosyslogresources.ServiceMetrics,
90+ // axosyslogresources.ServiceBufferMetrics,
91+ }
92+
93+ for _ , buildObject := range resourceBuilders {
94+ builderName := getFunctionName (buildObject )
95+ log .V (2 ).Info ("Processing resource" , "builder" , builderName )
96+
97+ o , state , err := buildObject (axoSyslog )
98+ if err != nil {
99+ return nil , errors .WrapIff (err , "failed to build object with %s" , builderName )
100+ }
101+ if o == nil {
102+ return nil , errors .Errorf ("reconcile error: %s returned nil object" , builderName )
103+ }
104+
105+ metaObj , ok := o .(metav1.Object )
106+ if ! ok {
107+ return nil , errors .Errorf ("reconcile error: %s returned non-metav1.Object" , builderName )
108+ }
109+
110+ if metaObj .GetNamespace () == "" {
111+ return nil , errors .Errorf ("reconcile error: %s returned resource without namespace set" , builderName )
112+ }
113+
114+ if err := ctrl .SetControllerReference (axoSyslog , metaObj , r .Scheme ()); err != nil {
115+ return nil , errors .WrapIff (err , "failed to set controller reference for %s" , metaObj .GetName ())
116+ }
117+
118+ result , err := r .ReconcileResource (o , state )
119+ if err != nil {
120+ return nil , errors .WrapIff (err , "failed to reconcile resource %s/%s" , metaObj .GetNamespace (), metaObj .GetName ())
121+ }
122+ if result != nil {
123+ return result , nil
124+ }
125+ }
126+
127+ return nil , nil
128+ }
129+
65130func SetupAxoSyslogWithManager (mgr ctrl.Manager , logger logr.Logger ) error {
66131 return ctrl .NewControllerManagedBy (mgr ).
67132 For (& v1beta1.AxoSyslog {}).
68- Named ("AxoSyslogController" ).
69- Complete (NewAxoSyslogReconciler (mgr .GetClient (), logger ))
133+ Named ("axosyslog" ).
134+ Complete (NewAxoSyslogReconciler (mgr .GetClient (), logger , reconciler.ReconcilerOpts {}))
135+ }
136+
137+ func getFunctionName (i any ) string {
138+ return runtime .FuncForPC (reflect .ValueOf (i ).Pointer ()).Name ()
70139}
0 commit comments