Skip to content

Commit

Permalink
Reconcile load balancers in machinepoollet (#594)
Browse files Browse the repository at this point in the history
  • Loading branch information
adracus authored Dec 21, 2022
1 parent b679a67 commit 6298da7
Show file tree
Hide file tree
Showing 28 changed files with 1,843 additions and 326 deletions.
23 changes: 14 additions & 9 deletions broker/machinebroker/aliasprefixes/aliasprefixes.go
Original file line number Diff line number Diff line change
Expand Up @@ -156,10 +156,10 @@ func (m *AliasPrefixes) createAliasPrefix(
func (m *AliasPrefixes) removeAliasPrefixRoutingDestination(
ctx context.Context,
aliasPrefixRouting *networkingv1alpha1.AliasPrefixRouting,
obj client.Object,
networkInterface *networkingv1alpha1.NetworkInterface,
) error {
idx := slices.IndexFunc(aliasPrefixRouting.Destinations,
func(ref commonv1alpha1.LocalUIDReference) bool { return ref.UID == obj.GetUID() },
func(ref commonv1alpha1.LocalUIDReference) bool { return ref.UID == networkInterface.UID },
)
if idx == -1 {
return nil
Expand All @@ -176,19 +176,19 @@ func (m *AliasPrefixes) removeAliasPrefixRoutingDestination(
func (m *AliasPrefixes) addAliasPrefixRoutingDestination(
ctx context.Context,
aliasPrefixRouting *networkingv1alpha1.AliasPrefixRouting,
obj client.Object,
networkInterface *networkingv1alpha1.NetworkInterface,
) error {
idx := slices.IndexFunc(aliasPrefixRouting.Destinations,
func(ref commonv1alpha1.LocalUIDReference) bool { return ref.UID == obj.GetUID() },
func(ref commonv1alpha1.LocalUIDReference) bool { return ref.UID == networkInterface.UID },
)
if idx >= 0 {
return nil
}

base := aliasPrefixRouting.DeepCopy()
aliasPrefixRouting.Destinations = append(aliasPrefixRouting.Destinations, commonv1alpha1.LocalUIDReference{
Name: obj.GetName(),
UID: obj.GetUID(),
Name: networkInterface.Name,
UID: networkInterface.UID,
})
if err := m.cluster.Client().Patch(ctx, aliasPrefixRouting, client.MergeFrom(base)); err != nil {
return fmt.Errorf("error adding alias prefix routing destination: %w", err)
Expand Down Expand Up @@ -239,7 +239,12 @@ func (m *AliasPrefixes) Create(
return nil
}

func (m *AliasPrefixes) Delete(ctx context.Context, networkHandle string, prefix commonv1alpha1.IPPrefix, obj client.Object) error {
func (m *AliasPrefixes) Delete(
ctx context.Context,
networkHandle string,
prefix commonv1alpha1.IPPrefix,
networkInterface *networkingv1alpha1.NetworkInterface,
) error {
key := aliasPrefixKey{
networkHandle: networkHandle,
prefix: prefix,
Expand All @@ -256,10 +261,10 @@ func (m *AliasPrefixes) Delete(ctx context.Context, networkHandle string, prefix
}

var errs []error
if err := m.removeAliasPrefixRoutingDestination(ctx, aliasPrefixRouting, obj); err != nil {
if err := m.removeAliasPrefixRoutingDestination(ctx, aliasPrefixRouting, networkInterface); err != nil {
errs = append(errs, fmt.Errorf("error removing alias prefix routing destination: %w", err))
}
if err := apiutils.DeleteAndGarbageCollect(ctx, m.cluster.Client(), aliasPrefix, obj.GetName()); err != nil {
if err := apiutils.DeleteAndGarbageCollect(ctx, m.cluster.Client(), aliasPrefix, networkInterface.Name); err != nil {
errs = append(errs, fmt.Errorf("error deleting / garbage collecting: %w", err))
}

Expand Down
38 changes: 33 additions & 5 deletions broker/machinebroker/api/v1alpha1/common_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
package v1alpha1

import (
"fmt"
"sort"

commonv1alpha1 "github.com/onmetal/onmetal-api/api/common/v1alpha1"
corev1 "k8s.io/api/core/v1"
)
Expand Down Expand Up @@ -51,13 +54,38 @@ const (
NetworkInterfacePurpose = "network-interface"
)

type LoadBalancerPort struct {
Protocol corev1.Protocol
Port int32
EndPort int32
}

func (p LoadBalancerPort) Key() string {
return fmt.Sprintf("%s:%d-%d", p.Protocol, p.Port, p.EndPort)
}

func LoadBalancerPortsKey(ports []LoadBalancerPort) string {
portKeys := make([]string, len(ports))
for i, port := range ports {
portKeys[i] = port.Key()
}
sort.Strings(portKeys)
return fmt.Sprintf("%v", portKeys)
}

type LoadBalancerTarget struct {
IP commonv1alpha1.IP
Ports []LoadBalancerTargetPort
Ports []LoadBalancerPort
}

type LoadBalancerTargetPort struct {
Protocol corev1.Protocol
Port int32
EndPort int32
func (t LoadBalancerTarget) Key() string {
portKeys := LoadBalancerPortsKey(t.Ports)
return fmt.Sprintf("%s%s", t.IP, portKeys)
}

type LoadBalancer struct {
NetworkHandle string
IP commonv1alpha1.IP
Ports []LoadBalancerPort
Destinations []string
}
29 changes: 0 additions & 29 deletions broker/machinebroker/apiutils/apiutils.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,44 +22,15 @@ import (

"github.com/onmetal/controller-utils/metautils"
commonv1alpha1 "github.com/onmetal/onmetal-api/api/common/v1alpha1"
networkingv1alpha1 "github.com/onmetal/onmetal-api/api/networking/v1alpha1"
machinebrokerv1alpha1 "github.com/onmetal/onmetal-api/broker/machinebroker/api/v1alpha1"
orimeta "github.com/onmetal/onmetal-api/ori/apis/meta/v1alpha1"
"golang.org/x/exp/slices"
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
)

func ConvertNetworkingLoadBalancerPort(port networkingv1alpha1.LoadBalancerPort) machinebrokerv1alpha1.LoadBalancerTargetPort {
protocol := port.Protocol
if protocol == nil {
tcpProtocol := corev1.ProtocolTCP
protocol = &tcpProtocol
}

endPort := port.EndPort
if endPort == nil {
endPort = &port.Port
}

return machinebrokerv1alpha1.LoadBalancerTargetPort{
Protocol: *protocol,
Port: port.Port,
EndPort: *endPort,
}
}

func ConvertNetworkingLoadBalancerPorts(ports []networkingv1alpha1.LoadBalancerPort) []machinebrokerv1alpha1.LoadBalancerTargetPort {
res := make([]machinebrokerv1alpha1.LoadBalancerTargetPort, len(ports))
for i, port := range ports {
res[i] = ConvertNetworkingLoadBalancerPort(port)
}
return res
}

func GetObjectMetadata(o metav1.Object) (*orimeta.ObjectMetadata, error) {
annotations, err := GetAnnotationsAnnotation(o)
if err != nil {
Expand Down
66 changes: 66 additions & 0 deletions broker/machinebroker/apiutils/conversion.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Copyright 2022 OnMetal authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package apiutils

import (
networkingv1alpha1 "github.com/onmetal/onmetal-api/api/networking/v1alpha1"
machinebrokerv1alpha1 "github.com/onmetal/onmetal-api/broker/machinebroker/api/v1alpha1"
corev1 "k8s.io/api/core/v1"
)

func ConvertNetworkingLoadBalancerPortToLoadBalancerPort(port networkingv1alpha1.LoadBalancerPort) machinebrokerv1alpha1.LoadBalancerPort {
protocol := port.Protocol
if protocol == nil {
tcpProtocol := corev1.ProtocolTCP
protocol = &tcpProtocol
}

endPort := port.EndPort
if endPort == nil {
endPort = &port.Port
}

return machinebrokerv1alpha1.LoadBalancerPort{
Protocol: *protocol,
Port: port.Port,
EndPort: *endPort,
}
}

func ConvertNetworkingLoadBalancerPortsToLoadBalancerPorts(ports []networkingv1alpha1.LoadBalancerPort) []machinebrokerv1alpha1.LoadBalancerPort {
res := make([]machinebrokerv1alpha1.LoadBalancerPort, len(ports))
for i, port := range ports {
res[i] = ConvertNetworkingLoadBalancerPortToLoadBalancerPort(port)
}
return res
}

func ConvertLoadBalancerPortToNetworkingLoadBalancerPort(port machinebrokerv1alpha1.LoadBalancerPort) networkingv1alpha1.LoadBalancerPort {
protocol := port.Protocol
endPort := port.EndPort
return networkingv1alpha1.LoadBalancerPort{
Protocol: &protocol,
Port: port.Port,
EndPort: &endPort,
}
}

func ConvertLoadBalancerPortsToNetworkingLoadBalancerPorts(ports []machinebrokerv1alpha1.LoadBalancerPort) []networkingv1alpha1.LoadBalancerPort {
res := make([]networkingv1alpha1.LoadBalancerPort, len(ports))
for i, port := range ports {
res[i] = ConvertLoadBalancerPortToNetworkingLoadBalancerPort(port)
}
return res
}
41 changes: 12 additions & 29 deletions broker/machinebroker/loadbalancers/loadbalancers.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import (
"context"
"fmt"

"github.com/onmetal/controller-utils/set"
commonv1alpha1 "github.com/onmetal/onmetal-api/api/common/v1alpha1"
networkingv1alpha1 "github.com/onmetal/onmetal-api/api/networking/v1alpha1"
"github.com/onmetal/onmetal-api/apiutils/annotations"
Expand Down Expand Up @@ -60,18 +59,18 @@ func New(cluster cluster.Cluster) *LoadBalancers {

func (m *LoadBalancers) filterLoadBalancers(
loadBalancers []networkingv1alpha1.LoadBalancer,
ports []machinebrokerv1alpha1.LoadBalancerTargetPort,
ports []machinebrokerv1alpha1.LoadBalancerPort,
) []networkingv1alpha1.LoadBalancer {
portSet := set.New(ports...)
portsKey := machinebrokerv1alpha1.LoadBalancerPortsKey(ports)

var filtered []networkingv1alpha1.LoadBalancer
for _, loadBalancer := range loadBalancers {
if loadBalancer.DeletionTimestamp.IsZero() {
continue
}

targetPorts := apiutils.ConvertNetworkingLoadBalancerPorts(loadBalancer.Spec.Ports)
if !set.New(targetPorts...).Equal(portSet) {
targetPorts := apiutils.ConvertNetworkingLoadBalancerPortsToLoadBalancerPorts(loadBalancer.Spec.Ports)
if machinebrokerv1alpha1.LoadBalancerPortsKey(targetPorts) != portsKey {
continue
}

Expand Down Expand Up @@ -119,16 +118,7 @@ func (m *LoadBalancers) createLoadBalancer(
c := cleaner.New()
defer cleaner.CleanupOnError(ctx, c, &retErr)

var ports []networkingv1alpha1.LoadBalancerPort
for _, port := range key.target.Ports {
protocol := port.Protocol
endPort := port.EndPort
ports = append(ports, networkingv1alpha1.LoadBalancerPort{
Protocol: &protocol,
Port: port.Port,
EndPort: &endPort,
})
}
ports := apiutils.ConvertLoadBalancerPortsToNetworkingLoadBalancerPorts(key.target.Ports)

loadBalancer := &networkingv1alpha1.LoadBalancer{
ObjectMeta: metav1.ObjectMeta{
Expand Down Expand Up @@ -303,13 +293,6 @@ func (m *LoadBalancers) Delete(
return nil
}

type LoadBalancer struct {
NetworkHandle string
IP commonv1alpha1.IP
Ports []machinebrokerv1alpha1.LoadBalancerTargetPort
Destinations set.Set[string]
}

func (m *LoadBalancers) listLoadBalancers(ctx context.Context, dependent string) ([]networkingv1alpha1.LoadBalancer, error) {
loadBalancerList := &networkingv1alpha1.LoadBalancerList{}
if err := m.cluster.Client().List(ctx, loadBalancerList,
Expand Down Expand Up @@ -347,7 +330,7 @@ func (m *LoadBalancers) listLoadBalancerRoutings(ctx context.Context) ([]network
return loadBalancerRoutingList.Items, nil
}

func (m *LoadBalancers) List(ctx context.Context) ([]LoadBalancer, error) {
func (m *LoadBalancers) List(ctx context.Context) ([]machinebrokerv1alpha1.LoadBalancer, error) {
loadBalancers, err := m.listLoadBalancers(ctx, "")
if err != nil {
return nil, err
Expand All @@ -364,10 +347,10 @@ func (m *LoadBalancers) List(ctx context.Context) ([]LoadBalancer, error) {
func (m *LoadBalancers) joinLoadBalancersAndRoutings(
loadBalancers []networkingv1alpha1.LoadBalancer,
loadBalancerRoutings []networkingv1alpha1.LoadBalancerRouting,
) []LoadBalancer {
) []machinebrokerv1alpha1.LoadBalancer {
loadBalancerRoutingByName := utils.ObjectSliceToMapByName(loadBalancerRoutings)

var res []LoadBalancer
var res []machinebrokerv1alpha1.LoadBalancer
for i := range loadBalancers {
loadBalancer := &loadBalancers[i]

Expand All @@ -386,24 +369,24 @@ func (m *LoadBalancers) joinLoadBalancersAndRoutings(
continue
}

destinations := utilslices.ToSetFunc(
destinations := utilslices.Map(
loadBalancerRouting.Destinations,
func(dest commonv1alpha1.LocalUIDReference) string {
return dest.Name
},
)

res = append(res, LoadBalancer{
res = append(res, machinebrokerv1alpha1.LoadBalancer{
NetworkHandle: networkHandle,
IP: ip,
Ports: apiutils.ConvertNetworkingLoadBalancerPorts(loadBalancer.Spec.Ports),
Ports: apiutils.ConvertNetworkingLoadBalancerPortsToLoadBalancerPorts(loadBalancer.Spec.Ports),
Destinations: destinations,
})
}
return res
}

func (m *LoadBalancers) ListByDependent(ctx context.Context, dependent string) ([]LoadBalancer, error) {
func (m *LoadBalancers) ListByDependent(ctx context.Context, dependent string) ([]machinebrokerv1alpha1.LoadBalancer, error) {
loadBalancers, err := m.listLoadBalancers(ctx, dependent)
if err != nil {
return nil, err
Expand Down
6 changes: 3 additions & 3 deletions broker/machinebroker/server/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ func (s *Server) convertOnmetalProtocol(protocol corev1.Protocol) (ori.Protocol,
}
}

func (s *Server) convertOnmetalLoadBalancerTargetPort(port machinebrokerv1alpha1.LoadBalancerTargetPort) (*ori.LoadBalancerPort, error) {
func (s *Server) convertOnmetalLoadBalancerTargetPort(port machinebrokerv1alpha1.LoadBalancerPort) (*ori.LoadBalancerPort, error) {
protocol, err := s.convertOnmetalProtocol(port.Protocol)
if err != nil {
return nil, err
Expand All @@ -143,13 +143,13 @@ func (s *Server) convertOnmetalLoadBalancerTargets(loadBalancerTargets []machine
res := make([]*ori.LoadBalancerTargetSpec, len(loadBalancerTargets))
for i, loadBalancerTarget := range loadBalancerTargets {
ports := make([]*ori.LoadBalancerPort, len(loadBalancerTarget.Ports))
for _, port := range loadBalancerTarget.Ports {
for j, port := range loadBalancerTarget.Ports {
p, err := s.convertOnmetalLoadBalancerTargetPort(port)
if err != nil {
return nil, err
}

ports[i] = p
ports[j] = p
}

res[i] = &ori.LoadBalancerTargetSpec{
Expand Down
Loading

0 comments on commit 6298da7

Please sign in to comment.