Skip to content

Commit

Permalink
Initial implementation of dedicated IP
Browse files Browse the repository at this point in the history
  • Loading branch information
eberlep committed Sep 8, 2023
1 parent e0fe157 commit b9c90b6
Show file tree
Hide file tree
Showing 5 changed files with 120 additions and 16 deletions.
13 changes: 9 additions & 4 deletions controllers/postgres_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,11 +130,16 @@ func (r *PostgresReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c
}
log.Info("corresponding CRD ClusterwideNetworkPolicy deleted")

if err := r.LBManager.DeleteSvcLB(ctx, instance); err != nil {
r.recorder.Eventf(instance, "Warning", "Error", "failed to delete Service: %v", err)
if err := r.LBManager.DeleteSharedSvcLB(ctx, instance); err != nil {
r.recorder.Eventf(instance, "Warning", "Error", "failed to delete Service with shared ip: %v", err)
return ctrl.Result{}, err
}
log.Info("corresponding Service of type LoadBalancer deleted")

if err := r.LBManager.DeleteDedicatedSvcLB(ctx, instance); err != nil {
r.recorder.Eventf(instance, "Warning", "Error", "failed to delete Service with dedicated ip: %v", err)
return ctrl.Result{}, err
}
log.Info("corresponding Service(s) of type LoadBalancer deleted")

// delete the postgres-exporter service
if err := r.deleteExporterSidecarService(ctx, namespace); client.IgnoreNotFound(err) != nil {
Expand Down Expand Up @@ -278,7 +283,7 @@ func (r *PostgresReconciler) Reconcile(ctx context.Context, req ctrl.Request) (c
return ctrl.Result{}, fmt.Errorf("failed to create or update zalando postgresql: %w", err)
}

if err := r.LBManager.CreateSvcLBIfNone(ctx, instance); err != nil {
if err := r.LBManager.ReconcileSvcLBs(ctx, instance); err != nil {
r.recorder.Eventf(instance, "Warning", "Error", "failed to create Service: %v", err)
return ctrl.Result{}, err
}
Expand Down
4 changes: 2 additions & 2 deletions controllers/postgres_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ var _ = Describe("postgres controller", func() {
Eventually(func() bool {
return svcClusterClient.Get(newCtx(), types.NamespacedName{
Namespace: instance.ToPeripheralResourceNamespace(),
Name: instance.ToSvcLBName(),
Name: instance.ToSharedSvcLBName(),
}, &core.Service{}) == nil
}, timeout, interval).Should(BeTrue())
})
Expand Down Expand Up @@ -96,7 +96,7 @@ var _ = Describe("postgres controller", func() {
Eventually(func() bool {
return svcClusterClient.Get(newCtx(), types.NamespacedName{
Namespace: instance.ToPeripheralResourceNamespace(),
Name: instance.ToSvcLBName(),
Name: instance.ToSharedSvcLBName(),
}, &core.Service{}) == nil
}, timeout, interval).ShouldNot(BeTrue())
})
Expand Down
2 changes: 1 addition & 1 deletion controllers/status_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ func (r *StatusReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctr
}

lb := &corev1.Service{}
if err := r.SvcClient.Get(ctx, *owner.ToSvcLBNamespacedName(), lb); err == nil {
if err := r.SvcClient.Get(ctx, *owner.ToSharedSvcLBNamespacedName(), lb); err == nil {
owner.Status.Socket.IP = lb.Spec.LoadBalancerIP
owner.Status.Socket.Port = lb.Spec.Ports[0].Port

Expand Down
7 changes: 7 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ const (
enableLBSourceRangesFlg = "enable-lb-source-ranges"
enableRandomStorageEncrytionSecretFlg = "enable-random-storage-encryption-secret"
enableWalGEncryptionFlg = "enable-walg-encryption"
enableForceSharedIPFlg = "enable-force-shared-ip"
)

var (
Expand Down Expand Up @@ -122,6 +123,7 @@ func main() {
enableLBSourceRanges bool
enableRandomStorageEncrytionSecret bool
enableWalGEncryption bool
enableForceSharedIP bool

portRangeStart int
portRangeSize int
Expand Down Expand Up @@ -255,6 +257,9 @@ func main() {
viper.SetDefault(enableWalGEncryptionFlg, false)
enableWalGEncryption = viper.GetBool(enableWalGEncryptionFlg)

viper.SetDefault(enableForceSharedIPFlg, true) // TODO switch to false?
enableForceSharedIP = viper.GetBool(enableForceSharedIPFlg)

ctrl.SetLogger(zap.New(zap.UseDevMode(true)))

ctrl.Log.Info("flag",
Expand Down Expand Up @@ -293,6 +298,7 @@ func main() {
enableRandomStorageEncrytionSecretFlg, enableRandomStorageEncrytionSecret,
postgresletFullnameFlg, postgresletFullname,
enableWalGEncryptionFlg, enableWalGEncryption,
enableForceSharedIPFlg, enableForceSharedIP,
)

svcClusterConf := ctrl.GetConfigOrDie()
Expand Down Expand Up @@ -376,6 +382,7 @@ func main() {
EnableLegacyStandbySelector: enableLegacyStandbySelector,
StandbyClustersSourceRanges: standbyClusterSourceRanges,
EnableLBSourceRanges: enableLBSourceRanges,
EnableForceSharedIP: enableForceSharedIP,
}
if err = (&controllers.PostgresReconciler{
CtrlClient: ctrlPlaneClusterMgr.GetClient(),
Expand Down
110 changes: 101 additions & 9 deletions pkg/lbmanager/lbmanager.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ type Options struct {
EnableLegacyStandbySelector bool
StandbyClustersSourceRanges []string
EnableLBSourceRanges bool
EnableForceSharedIP bool
}

// LBManager Responsible for the creation and deletion of externally accessible Services to access the Postgresql clusters managed by the Postgreslet.
Expand All @@ -35,12 +36,36 @@ func New(client client.Client, opt Options) *LBManager {
}
}

// CreateSvcLBIfNone Creates a new Service of type LoadBalancer for the given Postgres resource if neccessary
func (m *LBManager) CreateSvcLBIfNone(ctx context.Context, in *api.Postgres) error {
// ReconcileSvcLBs Creates or updates the LoadBalancer(s) for the given Postgres resource
func (m *LBManager) ReconcileSvcLBs(ctx context.Context, in *api.Postgres) error {

err1 := m.CreateOrUpdateSharedSvcLB(ctx, in)

err2 := m.CreateOrUpdateDedicatedSvcLB(ctx, in)

if err1 != nil {
return fmt.Errorf("failed to created Service of type LoadBalancer for shared IP: %w", err1)
}

if err2 != nil {
return fmt.Errorf("failed to created Service of type LoadBalancer for dedicated IP: %w", err1)
}

return nil
}

// CreateOrUpdateSharedSvcLB Creates or updates a Service of type LoadBalancer with a shared ip for the given Postgres resource if neccessary
func (m *LBManager) CreateOrUpdateSharedSvcLB(ctx context.Context, in *api.Postgres) error {
if m.options.EnableForceSharedIP != true && in.Spec.DedicatedLoadBalancerIP != nil && *in.Spec.DedicatedLoadBalancerIP != "" {
// TODO logging?
// TODO delete shared LB if neccessary (cleanup after possible config change)?
return nil
}

svc := &corev1.Service{}
if err := m.client.Get(ctx, client.ObjectKey{
Namespace: in.ToPeripheralResourceNamespace(),
Name: in.ToSvcLBName(),
Name: in.ToSharedSvcLBName(),
}, svc); err != nil {
if !apimach.IsNotFound(err) {
return fmt.Errorf("failed to fetch Service of type LoadBalancer: %w", err)
Expand All @@ -62,7 +87,63 @@ func (m *LBManager) CreateSvcLBIfNone(ctx context.Context, in *api.Postgres) err
lbIPToUse = ""
}

svc := in.ToSvcLB(lbIPToUse, nextFreePort, m.options.EnableStandbyLeaderSelector, m.options.EnableLegacyStandbySelector, m.options.StandbyClustersSourceRanges)
svc := in.ToSharedSvcLB(lbIPToUse, nextFreePort, m.options.EnableStandbyLeaderSelector, m.options.EnableLegacyStandbySelector, m.options.StandbyClustersSourceRanges)
if !m.options.EnableLBSourceRanges {
// leave empty / disable source ranges
svc.Spec.LoadBalancerSourceRanges = []string{}
}
if err := m.client.Create(ctx, svc); err != nil {
return fmt.Errorf("failed to create Service of type LoadBalancer: %w", err)
}
return nil
}

updated := in.ToSharedSvcLB("", 0, m.options.EnableStandbyLeaderSelector, m.options.EnableLegacyStandbySelector, m.options.StandbyClustersSourceRanges)
// update the selector, and only the selector (we do NOT want the change the ip or port here!!!)
svc.Spec.Selector = updated.Spec.Selector
// also update the source ranges
if m.options.EnableLBSourceRanges {
// use the given source ranges
svc.Spec.LoadBalancerSourceRanges = updated.Spec.LoadBalancerSourceRanges
} else {
// leave empty / disable source ranges
svc.Spec.LoadBalancerSourceRanges = []string{}
}

if err := m.client.Update(ctx, svc); err != nil {
return fmt.Errorf("failed to update Service of type LoadBalancer (shared): %w", err)
}

return nil
}

// CreateOrUpdateDedicatedSvcLB Creates or updates a Service of type LoadBalancer with a dedicated ip for the given Postgres resource if neccessary
func (m *LBManager) CreateOrUpdateDedicatedSvcLB(ctx context.Context, in *api.Postgres) error {
if in.Spec.DedicatedLoadBalancerIP == nil || *in.Spec.DedicatedLoadBalancerIP == "" {
// TODO logging?
err := m.DeleteDedicatedSvcLB(ctx, in)
if err != nil {

Check failure on line 125 in pkg/lbmanager/lbmanager.go

View workflow job for this annotation

GitHub Actions / build

SA9003: empty branch (staticcheck)
// TODO log, but continue
}
return nil
}

svc := &corev1.Service{}
if err := m.client.Get(ctx, client.ObjectKey{
Namespace: in.ToPeripheralResourceNamespace(),
Name: in.ToDedicatedSvcLBName(),
}, svc); err != nil {
if !apimach.IsNotFound(err) {
return fmt.Errorf("failed to fetch Service of type LoadBalancer: %w", err)
}

var nextFreePort int32 = 5432 // Default
// if in.Spec.DedicatedLoadBalancerPort != nil && *in.Spec.DedicatedLoadBalancerPort != 0 {
// nextFreePort = *in.Spec.DedicatedLoadBalancerPort
// }
var lbIPToUse string = *in.Spec.DedicatedLoadBalancerIP

svc := in.ToDedicatedSvcLB(lbIPToUse, nextFreePort, m.options.EnableStandbyLeaderSelector, m.options.EnableLegacyStandbySelector, m.options.StandbyClustersSourceRanges)
if !m.options.EnableLBSourceRanges {
// leave empty / disable source ranges
svc.Spec.LoadBalancerSourceRanges = []string{}
Expand All @@ -73,7 +154,7 @@ func (m *LBManager) CreateSvcLBIfNone(ctx context.Context, in *api.Postgres) err
return nil
}

updated := in.ToSvcLB("", 0, m.options.EnableStandbyLeaderSelector, m.options.EnableLegacyStandbySelector, m.options.StandbyClustersSourceRanges)
updated := in.ToDedicatedSvcLB("", 0, m.options.EnableStandbyLeaderSelector, m.options.EnableLegacyStandbySelector, m.options.StandbyClustersSourceRanges)
// update the selector, and only the selector (we do NOT want the change the ip or port here!!!)
svc.Spec.Selector = updated.Spec.Selector
// also update the source ranges
Expand All @@ -86,17 +167,28 @@ func (m *LBManager) CreateSvcLBIfNone(ctx context.Context, in *api.Postgres) err
}

if err := m.client.Update(ctx, svc); err != nil {
return fmt.Errorf("failed to update Service of type LoadBalancer: %w", err)
return fmt.Errorf("failed to update Service of type LoadBalancer (dedicated): %w", err)
}

return nil
}

// DeleteSvcLB Deletes the corresponding Service of type LoadBalancer of the given Postgres resource.
func (m *LBManager) DeleteSvcLB(ctx context.Context, in *api.Postgres) error {
// DeleteSharedSvcLB Deletes the corresponding Service of type LoadBalancer of the given Postgres resource.
func (m *LBManager) DeleteSharedSvcLB(ctx context.Context, in *api.Postgres) error {
lb := &corev1.Service{}
lb.Namespace = in.ToPeripheralResourceNamespace()
lb.Name = in.ToSharedSvcLBName()
if err := m.client.Delete(ctx, lb); client.IgnoreNotFound(err) != nil { // todo: remove ignorenotfound
return err
}
return nil
}

// DeleteDedicatedSvcLB Deletes the corresponding Service of type LoadBalancer of the given Postgres resource.
func (m *LBManager) DeleteDedicatedSvcLB(ctx context.Context, in *api.Postgres) error {
lb := &corev1.Service{}
lb.Namespace = in.ToPeripheralResourceNamespace()
lb.Name = in.ToSvcLBName()
lb.Name = in.ToDedicatedSvcLBName()
if err := m.client.Delete(ctx, lb); client.IgnoreNotFound(err) != nil { // todo: remove ignorenotfound
return err
}
Expand Down

0 comments on commit b9c90b6

Please sign in to comment.