Skip to content

Sort actions to ensure proper call order #95

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Nov 2, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
236 changes: 125 additions & 111 deletions pkg/oci/load_balancer.go
Original file line number Diff line number Diff line change
Expand Up @@ -204,14 +204,9 @@ func (cp *CloudProvider) EnsureLoadBalancer(clusterName string, service *api.Ser
return nil, err
}

err = cp.updateBackendSets(lb, spec)
err = cp.updateLoadBalancer(lb, spec, sslConfigMap, sourceCIDRs)
if err != nil {
return nil, fmt.Errorf("update backendsets: %v", err)
}

err = cp.updateListeners(lb, spec, sslConfigMap, sourceCIDRs)
if err != nil {
return nil, fmt.Errorf("udpate listeners: %v", err)
return nil, err
}

status, err := loadBalancerToStatus(lb)
Expand All @@ -223,15 +218,24 @@ func (cp *CloudProvider) EnsureLoadBalancer(clusterName string, service *api.Ser
return status, nil
}

func (cp *CloudProvider) updateBackendSets(lb *baremetal.LoadBalancer, spec LBSpec) error {
func (cp *CloudProvider) updateLoadBalancer(
lb *baremetal.LoadBalancer,
spec LBSpec,
sslConfigMap map[int]*baremetal.SSLConfiguration,
sourceCIDRs []string) error {
lbOCID := lb.ID

actual := lb.BackendSets
desired := spec.GetBackendSets()
actualBackendSets := lb.BackendSets
desiredBackendSets := spec.GetBackendSets()

actions := getBackendSetChanges(actual, desired)
if len(actions) == 0 {
return nil
backendSetActions := getBackendSetChanges(actualBackendSets, desiredBackendSets)

actualListeners := lb.Listeners
desiredListeners := spec.GetListeners(sslConfigMap)
listenerActions := getListenerChanges(actualListeners, desiredListeners)

if len(backendSetActions) == 0 && len(listenerActions) == 0 {
return nil // Nothing to do.
}

lbSubnets, err := cp.client.GetSubnets(spec.Subnets)
Expand All @@ -244,143 +248,153 @@ func (cp *CloudProvider) updateBackendSets(lb *baremetal.LoadBalancer, spec LBSp
return fmt.Errorf("get subnets for nodes: %v", err)
}

sourceCIDRs := []string{}
listenerPort := uint64(0)

actions := sortAndCombineActions(backendSetActions, listenerActions)
for _, action := range actions {
var workRequestID string
var err error

be := action.BackendSet
glog.V(2).Infof("Applying `%s` action on backend set `%s` for lb `%s`", action.Type, be.Name, lbOCID)

backendPort := uint64(getBackendPort(be.Backends))

switch action.Type {
case Create:
err = cp.securityListManager.Update(lbSubnets, nodeSubnets, sourceCIDRs, listenerPort, backendPort)
switch a := action.(type) {
case *BackendSetAction:
err := cp.updateBackendSet(lbOCID, a, lbSubnets, nodeSubnets)
if err != nil {
return err
return fmt.Errorf("error updating BackendSet: %v", err)
}

workRequestID, err = cp.client.CreateBackendSet(
lbOCID,
be.Name,
be.Policy,
be.Backends,
be.HealthChecker,
nil, // ssl config
nil, // session persistence
nil, // create opts
)
case Update:
err = cp.securityListManager.Update(lbSubnets, nodeSubnets, sourceCIDRs, listenerPort, backendPort)
if err != nil {
return err
case *ListenerAction:
backendSet := spec.GetBackendSets()[a.Listener.DefaultBackendSetName]
if a.Type() == Delete {
// If we need to delete the backendset then it'll no longer be
// present in the spec since that's what is desired, so we need
// to fetch it from the load balancer object.
backendSet = lb.BackendSets[a.Listener.DefaultBackendSetName]
}

workRequestID, err = cp.client.UpdateBackendSet(lbOCID, be.Name, &baremetal.UpdateLoadBalancerBackendSetOptions{
Policy: be.Policy,
HealthChecker: be.HealthChecker,
Backends: be.Backends,
})
case Delete:
err = cp.securityListManager.Delete(lbSubnets, nodeSubnets, listenerPort, backendPort)
backendPort := uint64(getBackendPort(backendSet.Backends))
err := cp.updateListener(lbOCID, a, backendPort, lbSubnets, nodeSubnets, sslConfigMap, sourceCIDRs)
if err != nil {
return err
return fmt.Errorf("error updating Listener: %v", err)
}

workRequestID, err = cp.client.DeleteBackendSet(lbOCID, be.Name, nil)
}
}
return nil
}

func (cp *CloudProvider) updateBackendSet(lbOCID string, action *BackendSetAction, lbSubnets, nodeSubnets []*baremetal.Subnet) error {
sourceCIDRs := []string{}
listenerPort := uint64(0)

var workRequestID string
var err error

be := action.BackendSet
glog.V(2).Infof("Applying %q action on backend set `%s` for lb `%s`", action.Type(), be.Name, lbOCID)

backendPort := uint64(getBackendPort(be.Backends))

switch action.Type() {
case Create:
err = cp.securityListManager.Update(lbSubnets, nodeSubnets, sourceCIDRs, listenerPort, backendPort)
if err != nil {
return err
}

_, err = cp.client.AwaitWorkRequest(workRequestID)
workRequestID, err = cp.client.CreateBackendSet(
lbOCID,
be.Name,
be.Policy,
be.Backends,
be.HealthChecker,
nil, // ssl config
nil, // session persistence
nil, // create opts
)
case Update:
err = cp.securityListManager.Update(lbSubnets, nodeSubnets, sourceCIDRs, listenerPort, backendPort)
if err != nil {
return err
}
}

return nil
}

func (cp *CloudProvider) updateListeners(lb *baremetal.LoadBalancer, spec LBSpec, sslConfigMap map[int]*baremetal.SSLConfiguration, sourceCIDRs []string) error {
lbOCID := lb.ID
workRequestID, err = cp.client.UpdateBackendSet(lbOCID, be.Name, &baremetal.UpdateLoadBalancerBackendSetOptions{
Policy: be.Policy,
HealthChecker: be.HealthChecker,
Backends: be.Backends,
})
case Delete:
err = cp.securityListManager.Delete(lbSubnets, nodeSubnets, listenerPort, backendPort)
if err != nil {
return err
}

desired := spec.GetListeners(sslConfigMap)
actions := getListenerChanges(lb.Listeners, desired)
if len(actions) == 0 {
return nil
workRequestID, err = cp.client.DeleteBackendSet(lbOCID, be.Name, nil)
}

lbSubnets, err := cp.client.GetSubnets(spec.Subnets)
if err != nil {
return fmt.Errorf("get subnets for lbs: %v", err)
return err
}

nodeSubnets, err := cp.client.GetSubnetsForNodes(spec.Nodes)
_, err = cp.client.AwaitWorkRequest(workRequestID)
if err != nil {
return fmt.Errorf("get subnets for nodes: %v", err)
return err
}

for _, action := range actions {
var workRequestID string
var err error
l := action.Listener
listenerPort := uint64(l.Port)
return nil
}

backends := spec.GetBackendSets()[l.DefaultBackendSetName].Backends
backendPort := uint64(getBackendPort(backends))
func (cp *CloudProvider) updateListener(lbOCID string,
action *ListenerAction,
backendPort uint64,
lbSubnets []*baremetal.Subnet,
nodeSubnets []*baremetal.Subnet,
sslConfigMap map[int]*baremetal.SSLConfiguration,
sourceCIDRs []string) error {

glog.V(2).Infof("Applying `%s` action on listener `%s` for lb `%s`", action.Type, l.Name, lbOCID)
var workRequestID string
var err error
l := action.Listener
listenerPort := uint64(l.Port)

switch action.Type {
case Create:
err = cp.securityListManager.Update(lbSubnets, nodeSubnets, sourceCIDRs, listenerPort, backendPort)
if err != nil {
return err
}
glog.V(2).Infof("Applying %q action on listener `%s` for lb `%s`", action.Type(), l.Name, lbOCID)

workRequestID, err = cp.client.CreateListener(
lbOCID,
l.Name,
l.DefaultBackendSetName,
l.Protocol,
l.Port,
l.SSLConfig,
nil, // create opts
)
case Update:
err = cp.securityListManager.Update(lbSubnets, nodeSubnets, sourceCIDRs, listenerPort, backendPort)
if err != nil {
return err
}

workRequestID, err = cp.client.UpdateListener(lbOCID, l.Name, &baremetal.UpdateLoadBalancerListenerOptions{
DefaultBackendSetName: l.DefaultBackendSetName,
Port: l.Port,
Protocol: l.Protocol,
SSLConfig: l.SSLConfig,
})
case Delete:
err = cp.securityListManager.Delete(lbSubnets, nodeSubnets, listenerPort, backendPort)
if err != nil {
return err
}

workRequestID, err = cp.client.DeleteListener(lbOCID, l.Name, nil)
switch action.Type() {
case Create:
err = cp.securityListManager.Update(lbSubnets, nodeSubnets, sourceCIDRs, listenerPort, backendPort)
if err != nil {
return err
}

workRequestID, err = cp.client.CreateListener(
lbOCID,
l.Name,
l.DefaultBackendSetName,
l.Protocol,
l.Port,
l.SSLConfig,
nil, // create opts
)
case Update:
err = cp.securityListManager.Update(lbSubnets, nodeSubnets, sourceCIDRs, listenerPort, backendPort)
if err != nil {
return err
}

_, err = cp.client.AwaitWorkRequest(workRequestID)
workRequestID, err = cp.client.UpdateListener(lbOCID, l.Name, &baremetal.UpdateLoadBalancerListenerOptions{
DefaultBackendSetName: l.DefaultBackendSetName,
Port: l.Port,
Protocol: l.Protocol,
SSLConfig: l.SSLConfig,
})
case Delete:
err = cp.securityListManager.Delete(lbSubnets, nodeSubnets, listenerPort, backendPort)
if err != nil {
return err
}

workRequestID, err = cp.client.DeleteListener(lbOCID, l.Name, nil)
}

if err != nil {
return err
}

_, err = cp.client.AwaitWorkRequest(workRequestID)
if err != nil {
return err
}

return nil
Expand Down
5 changes: 0 additions & 5 deletions pkg/oci/load_balancer_security_lists.go
Original file line number Diff line number Diff line change
Expand Up @@ -200,11 +200,6 @@ func (s *securityListManagerImpl) updateSecurityListRules(securityListID string,
return err
}

func getBackendPort(backends []baremetal.Backend) uint64 {
// TODO: what happens if this is 0? e.g. we scale the pods to 0 for a deployment
return uint64(backends[0].Port)
}

func getNodeIngressRules(securityList *baremetal.SecurityList, lbSubnets []*baremetal.Subnet, port uint64) []baremetal.IngressSecurityRule {
desired := sets.NewString()
for _, lbSubnet := range lbSubnets {
Expand Down
Loading