Kubernetes RabbitMQ operator https://github.com/tekliner/rabbitmq-operator
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

98 lines
3.8 KiB

  1. package rabbitmq
  2. import (
  3. "context"
  4. "github.com/getsentry/raven-go"
  5. "github.com/go-logr/logr"
  6. v1beta1policy "k8s.io/api/policy/v1beta1"
  7. apierrors "k8s.io/apimachinery/pkg/api/errors"
  8. metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
  9. "k8s.io/apimachinery/pkg/types"
  10. "k8s.io/apimachinery/pkg/util/intstr"
  11. "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
  12. "sigs.k8s.io/controller-runtime/pkg/reconcile"
  13. rabbitmqv1 "github.com/tekliner/rabbitmq-operator/pkg/apis/rabbitmq/v1"
  14. )
  15. func (r *ReconcileRabbitmq) reconcilePdb(reqLogger logr.Logger, cr *rabbitmqv1.Rabbitmq) (reconcile.Result, error) {
  16. newPdb := getDisruptionBudget(cr)
  17. reqLogger.Info("Started reconciling PodDisruptionBudget", "Pdb.Namespace", newPdb.Namespace, "Pdb.Name", newPdb.Name)
  18. if err := controllerutil.SetControllerReference(cr, &newPdb, r.scheme); err != nil {
  19. reqLogger.Info("Error setting controller reference for PodDisruptionBudget", "Pdb.Namespace", &newPdb.Namespace, "Pdb.Name", &newPdb.Name)
  20. return reconcile.Result{}, err
  21. }
  22. // Check existing pdb
  23. foundPdb := &v1beta1policy.PodDisruptionBudget{}
  24. reqLogger.Info("Getting PodDisruptionBudget", "Pdb.Namespace", &newPdb.Namespace, "Pdb.Name", &newPdb.Name)
  25. err := r.client.Get(context.TODO(), types.NamespacedName{Name: newPdb.Name, Namespace: newPdb.Namespace}, foundPdb)
  26. if err != nil && apierrors.IsNotFound(err) {
  27. reqLogger.Info("No PodDisruptionBudget found, creating new", "Pdb.Namespace", &newPdb.Namespace, "Pdb.Name", &newPdb.Name)
  28. err = r.client.Create(context.TODO(), &newPdb)
  29. foundPdb = &newPdb
  30. if err != nil {
  31. reqLogger.Info("Error creating new PodDisruptionBudget", "Pdb.Namespace", &newPdb.Namespace, "Pdb.Name", &newPdb.Name)
  32. return reconcile.Result{}, err
  33. }
  34. } else if err != nil {
  35. reqLogger.Info("Error getting PodDisruptionBudget", "Pdb.Namespace", &newPdb.Namespace, "Pdb.Name", &newPdb.Name)
  36. return reconcile.Result{}, err
  37. } else {
  38. if reconcileRequired, reconPdb := reconcilePdb(reqLogger, *foundPdb, newPdb); reconcileRequired {
  39. reqLogger.Info("Updating PodDisruptionBudget", "Namespace", reconPdb.Namespace, "Name", reconPdb.Name)
  40. if err = r.client.Update(context.TODO(), &reconPdb); err != nil {
  41. reqLogger.Info("Reconcile PodDisruptionBudget error", "Namespace", foundPdb.Namespace, "Name", foundPdb.Name)
  42. raven.CaptureErrorAndWait(err, nil)
  43. return reconcile.Result{}, err
  44. }
  45. }
  46. }
  47. return reconcile.Result{}, nil
  48. }
  49. func getDisruptionBudget(cr *rabbitmqv1.Rabbitmq) v1beta1policy.PodDisruptionBudget {
  50. podDisruptionBudget := v1beta1policy.PodDisruptionBudget{}
  51. labelSelector := metav1.LabelSelector{MatchLabels: cr.Labels}
  52. if cr.Spec.RabbitmqReplicas >= 2 {
  53. specPDB := v1beta1policy.PodDisruptionBudgetSpec{Selector: &labelSelector}
  54. if cr.Spec.RabbitmqPdb.Spec.MinAvailable != nil && cr.Spec.RabbitmqPdb.Spec.MaxUnavailable != nil {
  55. specPDB.MinAvailable = cr.Spec.RabbitmqPdb.Spec.MinAvailable
  56. } else if cr.Spec.RabbitmqPdb.Spec.MinAvailable != nil {
  57. specPDB.MinAvailable = cr.Spec.RabbitmqPdb.Spec.MinAvailable
  58. } else if cr.Spec.RabbitmqPdb.Spec.MaxUnavailable != nil {
  59. specPDB.MaxUnavailable = cr.Spec.RabbitmqPdb.Spec.MaxUnavailable
  60. } else {
  61. specPDB.MinAvailable = func() *intstr.IntOrString { v := intstr.FromInt(1); return &v }()
  62. }
  63. podDisruptionBudget = v1beta1policy.PodDisruptionBudget{
  64. ObjectMeta: metav1.ObjectMeta{
  65. Name: cr.Name,
  66. Namespace: cr.Namespace,
  67. },
  68. Spec: specPDB,
  69. }
  70. } else {
  71. maxUnavailable := intstr.FromInt(1)
  72. specPDB := v1beta1policy.PodDisruptionBudgetSpec{
  73. Selector: &labelSelector,
  74. MaxUnavailable: &maxUnavailable,
  75. }
  76. podDisruptionBudget = v1beta1policy.PodDisruptionBudget{
  77. ObjectMeta: metav1.ObjectMeta{
  78. Name: cr.Name,
  79. Namespace: cr.Namespace,
  80. },
  81. Spec: specPDB,
  82. }
  83. }
  84. return podDisruptionBudget
  85. }