controllers/gerritgroupmember/controller.go (133 lines of code) (raw):

package gerritgroupmember import ( "context" "fmt" "os" "reflect" "time" "github.com/go-logr/logr" "github.com/pkg/errors" k8sErrors "k8s.io/apimachinery/pkg/api/errors" "k8s.io/apimachinery/pkg/runtime" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/builder" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/event" "sigs.k8s.io/controller-runtime/pkg/predicate" "sigs.k8s.io/controller-runtime/pkg/reconcile" gerritApi "github.com/epam/edp-gerrit-operator/v2/api/v1" "github.com/epam/edp-gerrit-operator/v2/controllers/helper" gerritClient "github.com/epam/edp-gerrit-operator/v2/pkg/client/gerrit" "github.com/epam/edp-gerrit-operator/v2/pkg/service/gerrit" "github.com/epam/edp-gerrit-operator/v2/pkg/service/platform" ) const ( finalizerName = "gerritgroupmember.gerrit.finalizer.name" syncIntervalEnv = "GERRIT_GROUP_MEMBER_SYNC_INTERVAL" ) type Reconcile struct { client client.Client service gerrit.Interface log logr.Logger } func NewReconcile(k8sClient client.Client, scheme *runtime.Scheme, log logr.Logger) (helper.Controller, error) { ps, err := platform.NewService(helper.GetPlatformTypeEnv(), scheme) if err != nil { return nil, errors.Wrap(err, "unable to create platform service") } return &Reconcile{ client: k8sClient, service: gerrit.NewComponentService(ps, k8sClient, scheme), log: log.WithName("gerrit"), }, nil } func (r *Reconcile) SetupWithManager(mgr ctrl.Manager) error { pred := predicate.Funcs{ UpdateFunc: isSpecUpdated, } err := ctrl.NewControllerManagedBy(mgr). For(&gerritApi.GerritGroupMember{}, builder.WithPredicates(pred)). Complete(r) if err != nil { return fmt.Errorf("failed to setup GerritGroupMember controller: %w", err) } return nil } func isSpecUpdated(e event.UpdateEvent) bool { oo, ok := e.ObjectOld.(*gerritApi.GerritGroupMember) if !ok { return false } no, ok := e.ObjectNew.(*gerritApi.GerritGroupMember) if !ok { return false } return !reflect.DeepEqual(oo.Spec, no.Spec) || (oo.GetDeletionTimestamp().IsZero() && !no.GetDeletionTimestamp().IsZero()) } //+kubebuilder:rbac:groups=v2.edp.epam.com,namespace=placeholder,resources=gerritgroupmembers,verbs=get;list;watch;create;update;patch;delete //+kubebuilder:rbac:groups=v2.edp.epam.com,namespace=placeholder,resources=gerritgroupmembers/status,verbs=get;update;patch //+kubebuilder:rbac:groups=v2.edp.epam.com,namespace=placeholder,resources=gerritgroupmembers/finalizers,verbs=update func (r *Reconcile) Reconcile(ctx context.Context, request reconcile.Request) (result reconcile.Result, resError error) { reqLogger := r.log.WithValues("Request.Namespace", request.Namespace, "Request.Name", request.Name) reqLogger.V(2).Info("Reconciling GerritGroupMember has been started") var instance gerritApi.GerritGroupMember if err := r.client.Get(context.TODO(), request.NamespacedName, &instance); err != nil { if k8sErrors.IsNotFound(err) { return } return reconcile.Result{}, errors.Wrap(err, "unable to get GerritGroupMember instance") } defer func() { if err := r.client.Status().Update(context.Background(), &instance); err != nil { reqLogger.Error(err, "unable to update instance status") } }() if err := r.tryToReconcile(ctx, &instance); err != nil { reqLogger.Error(err, "unable to reconcile GerritGroupMember") instance.Status.Value = err.Error() expRequeueTime := helper.SetFailureCount(&instance) constTimeout, isSet := getSyncInterval(syncIntervalEnv) if !isSet { reqLogger.Info("Unable to get sync interval from env. Requeue time will be set using the exponential formula") reqLogger.Info("Requeue time", "time", expRequeueTime.String()) return reconcile.Result{RequeueAfter: expRequeueTime}, nil } reqLogger.Info("Requeue time", "time", constTimeout.String()) return reconcile.Result{RequeueAfter: constTimeout}, nil } helper.SetSuccessStatus(&instance) return } func (r *Reconcile) tryToReconcile(ctx context.Context, instance *gerritApi.GerritGroupMember) error { cl, err := helper.GetGerritClient(ctx, r.client, instance, instance.Spec.OwnerName, r.service) if err != nil { return errors.Wrap(err, "unable to init gerrit client") } if err := cl.AddUserToGroup(instance.Spec.GroupID, instance.Spec.AccountID); err != nil { return errors.Wrap(err, "unable to add user to group") } if err := helper.TryToDelete(ctx, r.client, instance, finalizerName, r.makeDeletionFunc(cl, instance)); err != nil { return errors.Wrap(err, "unable to delete CR") } return nil } func (*Reconcile) makeDeletionFunc(cl gerritClient.ClientInterface, instance *gerritApi.GerritGroupMember) func() error { return func() error { if err := cl.DeleteUserFromGroup(instance.Spec.GroupID, instance.Spec.AccountID); err != nil { return errors.Wrap(err, "unable to delete user from group") } return nil } } func getSyncInterval(envVarName string) (time.Duration, bool) { value, ok := os.LookupEnv(envVarName) if !ok { return 0, false } interval, err := time.ParseDuration(value) if err != nil { return 0, false } if interval <= 0 { return 0, false } return interval, true }