Skip to content

Commit

Permalink
refactor redundant functions
Browse files Browse the repository at this point in the history
  • Loading branch information
iljarotar committed Oct 22, 2024
1 parent 5caabbd commit af28a85
Show file tree
Hide file tree
Showing 5 changed files with 82 additions and 145 deletions.
82 changes: 12 additions & 70 deletions pkg/controllers/loadbalancer/cilium/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@ package cilium

import (
"context"
"errors"
"fmt"
"strconv"
"strings"
"time"

"github.com/metal-stack/metal-lib/pkg/pointer"
Expand All @@ -27,13 +25,12 @@ import (
slimv1 "github.com/cilium/cilium/pkg/k8s/slim/k8s/apis/meta/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
"sigs.k8s.io/yaml"
)

type ciliumConfig struct {
Peers []*Peer `json:"peers,omitempty" yaml:"peers,omitempty"`
AddressPools []*loadbalancer.AddressPool `json:"address-pools,omitempty" yaml:"address-pools,omitempty"`
k8sClient clientset.Interface
loadbalancer.Config
Peers []*Peer `json:"peers,omitempty" yaml:"peers,omitempty"`
k8sClient clientset.Interface
}

func NewCiliumConfig(k8sClient clientset.Interface) *ciliumConfig {
Expand All @@ -45,7 +42,7 @@ func (cfg *ciliumConfig) Namespace() string {
}

func (cfg *ciliumConfig) PrepareConfig(ips []*models.V1IPResponse, nws sets.Set[string], nodes []v1.Node) error {
err := cfg.computeAddressPools(ips, nws)
err := cfg.ComputeAddressPools(ips, nws)
if err != nil {
return err
}
Expand All @@ -56,25 +53,6 @@ func (cfg *ciliumConfig) PrepareConfig(ips []*models.V1IPResponse, nws sets.Set[
return nil
}

func (cfg *ciliumConfig) computeAddressPools(ips []*models.V1IPResponse, nws sets.Set[string]) error {
var errs []error
for _, ip := range ips {
if !nws.Has(*ip.Networkid) {
klog.Infof("skipping ip %q: not part of cluster networks", *ip.Ipaddress)
continue
}
net := *ip.Networkid
err := cfg.addIPToPool(net, *ip)
if err != nil {
errs = append(errs, err)
}
}
if len(errs) > 0 {
return errors.Join(errs...)
}
return nil
}

func (cfg *ciliumConfig) computePeers(nodes []v1.Node) error {
cfg.Peers = []*Peer{} // we want an empty array of peers and not nil if there are no nodes
for _, n := range nodes {
Expand All @@ -94,40 +72,17 @@ func (cfg *ciliumConfig) computePeers(nodes []v1.Node) error {
return nil
}

func (cfg *ciliumConfig) getOrCreateAddressPool(poolName string) *loadbalancer.AddressPool {
for _, pool := range cfg.AddressPools {
if pool.Name == poolName {
return pool
}
}

pool := loadbalancer.NewBGPAddressPool(poolName)
cfg.AddressPools = append(cfg.AddressPools, pool)

return pool
}

func (cfg *ciliumConfig) addIPToPool(network string, ip models.V1IPResponse) error {
t := ip.Type
poolType := models.V1IPBaseTypeEphemeral
if t != nil && *t == models.V1IPBaseTypeStatic {
poolType = models.V1IPBaseTypeStatic
}
poolName := fmt.Sprintf("%s-%s", strings.ToLower(network), poolType)
pool := cfg.getOrCreateAddressPool(poolName)
err := pool.AppendIP(*ip.Ipaddress)
if err != nil {
return err
func getASNFromNodeLabels(node v1.Node) (int64, error) {
labels := node.GetLabels()
asnString, ok := labels[tag.MachineNetworkPrimaryASN]
if !ok {
return 0, fmt.Errorf("node %q misses label: %s", node.GetName(), tag.MachineNetworkPrimaryASN)
}
return nil
}

func (cfg *ciliumConfig) toYAML() (string, error) {
bb, err := yaml.Marshal(cfg)
asn, err := strconv.ParseInt(asnString, 10, 64)
if err != nil {
return "", err
return 0, fmt.Errorf("unable to parse valid integer from asn annotation: %w", err)
}
return string(bb), nil
return asn, nil
}

func (cfg *ciliumConfig) WriteCRs(ctx context.Context, c client.Client) error {
Expand Down Expand Up @@ -305,16 +260,3 @@ func (cfg *ciliumConfig) writeNodeAnnotations(ctx context.Context) error {

return nil
}

func getASNFromNodeLabels(node v1.Node) (int64, error) {
labels := node.GetLabels()
asnString, ok := labels[tag.MachineNetworkPrimaryASN]
if !ok {
return 0, fmt.Errorf("node %q misses label: %s", node.GetName(), tag.MachineNetworkPrimaryASN)
}
asn, err := strconv.ParseInt(asnString, 10, 64)
if err != nil {
return 0, fmt.Errorf("unable to parse valid integer from asn annotation: %w", err)
}
return asn, nil
}
2 changes: 1 addition & 1 deletion pkg/controllers/loadbalancer/cilium/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ func TestCiliumConfig_CalculateConfig(t *testing.T) {
return
}

yaml, err := cfg.toYAML()
yaml, err := cfg.ToYAML()
require.NoError(t, err)

if diff := cmp.Diff(yaml, mustYAML(tt.want)); diff != "" {
Expand Down
64 changes: 64 additions & 0 deletions pkg/controllers/loadbalancer/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@ package loadbalancer

import (
"context"
"errors"
"fmt"
"strings"

"github.com/metal-stack/metal-go/api/models"
"gopkg.in/yaml.v2"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/klog/v2"
"sigs.k8s.io/controller-runtime/pkg/client"
)

Expand All @@ -14,3 +19,62 @@ type LoadBalancerConfig interface {
PrepareConfig(ips []*models.V1IPResponse, nws sets.Set[string], nodes []v1.Node) error
WriteCRs(ctx context.Context, c client.Client) error
}

type Config struct {
AddressPools []*AddressPool `json:"address-pools,omitempty" yaml:"address-pools,omitempty"`
}

func (cfg *Config) ComputeAddressPools(ips []*models.V1IPResponse, nws sets.Set[string]) error {
var errs []error
for _, ip := range ips {
if !nws.Has(*ip.Networkid) {
klog.Infof("skipping ip %q: not part of cluster networks", *ip.Ipaddress)
continue
}
net := *ip.Networkid
err := cfg.addIPToPool(net, *ip)
if err != nil {
errs = append(errs, err)
}
}
if len(errs) > 0 {
return errors.Join(errs...)
}
return nil
}

func (cfg *Config) addIPToPool(network string, ip models.V1IPResponse) error {
t := ip.Type
poolType := models.V1IPBaseTypeEphemeral
if t != nil && *t == models.V1IPBaseTypeStatic {
poolType = models.V1IPBaseTypeStatic
}
poolName := fmt.Sprintf("%s-%s", strings.ToLower(network), poolType)
pool := cfg.getOrCreateAddressPool(poolName)
err := pool.AppendIP(*ip.Ipaddress)
if err != nil {
return err
}
return nil
}

func (cfg *Config) getOrCreateAddressPool(poolName string) *AddressPool {
for _, pool := range cfg.AddressPools {
if pool.Name == poolName {
return pool
}
}

pool := NewBGPAddressPool(poolName)
cfg.AddressPools = append(cfg.AddressPools, pool)

return pool
}

func (cfg *Config) ToYAML() (string, error) {
bb, err := yaml.Marshal(cfg)
if err != nil {
return "", err
}
return string(bb), nil
}
77 changes: 4 additions & 73 deletions pkg/controllers/loadbalancer/metallb/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,8 @@ package metallb

import (
"context"
"errors"
"fmt"
"strconv"
"strings"
"time"

"github.com/metal-stack/metal-ccm/pkg/controllers/loadbalancer"
Expand All @@ -20,7 +18,6 @@ import (

"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
"sigs.k8s.io/yaml"

metallbv1beta1 "go.universe.tf/metallb/api/v1beta1"
metallbv1beta2 "go.universe.tf/metallb/api/v1beta2"
Expand All @@ -30,11 +27,10 @@ const (
metallbNamespace = "metallb-system"
)

// metalLBConfig is a struct containing a config for metallb
type metalLBConfig struct {
Peers []*Peer `json:"peers,omitempty" yaml:"peers,omitempty"`
AddressPools []*loadbalancer.AddressPool `json:"address-pools,omitempty" yaml:"address-pools,omitempty"`
namespace string
loadbalancer.Config
Peers []*Peer `json:"peers,omitempty" yaml:"peers,omitempty"`
namespace string
}

func NewMetalLBConfig() *metalLBConfig {
Expand All @@ -45,9 +41,8 @@ func (cfg *metalLBConfig) Namespace() string {
return cfg.namespace
}

// CalculateConfig computes the metallb config from given parameter input.
func (cfg *metalLBConfig) PrepareConfig(ips []*models.V1IPResponse, nws sets.Set[string], nodes []v1.Node) error {
err := cfg.computeAddressPools(ips, nws)
err := cfg.ComputeAddressPools(ips, nws)
if err != nil {
return err
}
Expand All @@ -58,25 +53,6 @@ func (cfg *metalLBConfig) PrepareConfig(ips []*models.V1IPResponse, nws sets.Set
return nil
}

func (cfg *metalLBConfig) computeAddressPools(ips []*models.V1IPResponse, nws sets.Set[string]) error {
var errs []error
for _, ip := range ips {
if !nws.Has(*ip.Networkid) {
klog.Infof("skipping ip %q: not part of cluster networks", *ip.Ipaddress)
continue
}
net := *ip.Networkid
err := cfg.addIPToPool(net, *ip)
if err != nil {
errs = append(errs, err)
}
}
if len(errs) > 0 {
return errors.Join(errs...)
}
return nil
}

func (cfg *metalLBConfig) computePeers(nodes []v1.Node) error {
cfg.Peers = []*Peer{} // we want an empty array of peers and not nil if there are no nodes
for _, n := range nodes {
Expand All @@ -101,50 +77,7 @@ func (cfg *metalLBConfig) computePeers(nodes []v1.Node) error {
return nil
}

// getOrCreateAddressPool returns the address pool of the given network.
// It will be created if it does not exist yet.
func (cfg *metalLBConfig) getOrCreateAddressPool(poolName string) *loadbalancer.AddressPool {
for _, pool := range cfg.AddressPools {
if pool.Name == poolName {
return pool
}
}

pool := loadbalancer.NewBGPAddressPool(poolName)
cfg.AddressPools = append(cfg.AddressPools, pool)

return pool
}

// announceIPs appends the given IPs to the network address pools.
func (cfg *metalLBConfig) addIPToPool(network string, ip models.V1IPResponse) error {
t := ip.Type
poolType := models.V1IPBaseTypeEphemeral
if t != nil && *t == models.V1IPBaseTypeStatic {
poolType = models.V1IPBaseTypeStatic
}
poolName := fmt.Sprintf("%s-%s", strings.ToLower(network), poolType)
pool := cfg.getOrCreateAddressPool(poolName)
err := pool.AppendIP(*ip.Ipaddress)
if err != nil {
return err
}
return nil
}

// toYAML returns this config in YAML format.
func (cfg *metalLBConfig) toYAML() (string, error) {
bb, err := yaml.Marshal(cfg)
if err != nil {
return "", err
}
return string(bb), nil
}

// WriteCRs inserts or updates the Metal-LB custom resources.
func (cfg *metalLBConfig) WriteCRs(ctx context.Context, c client.Client) error {

// BGPPeers
bgpPeerList := metallbv1beta2.BGPPeerList{}
err := c.List(ctx, &bgpPeerList, client.InNamespace(cfg.namespace))
if err != nil {
Expand Down Expand Up @@ -197,7 +130,6 @@ func (cfg *metalLBConfig) WriteCRs(ctx context.Context, c client.Client) error {
}
}

// IPAddressPools
addressPoolList := metallbv1beta1.IPAddressPoolList{}
err = c.List(ctx, &addressPoolList, client.InNamespace(cfg.namespace))
if err != nil {
Expand Down Expand Up @@ -246,7 +178,6 @@ func (cfg *metalLBConfig) WriteCRs(ctx context.Context, c client.Client) error {
}
}

// BGPAdvertisements
for _, pool := range cfg.AddressPools {
bgpAdvertisementList := metallbv1beta1.BGPAdvertisementList{}
err = c.List(ctx, &bgpAdvertisementList, client.InNamespace(cfg.namespace))
Expand Down
2 changes: 1 addition & 1 deletion pkg/controllers/loadbalancer/metallb/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,7 @@ func TestMetalLBConfig_CalculateConfig(t *testing.T) {
return
}

yaml, err := cfg.toYAML()
yaml, err := cfg.ToYAML()
require.NoError(t, err)

if diff := cmp.Diff(yaml, mustYAML(tt.want)); diff != "" {
Expand Down

0 comments on commit af28a85

Please sign in to comment.