From c93bedf4d614cd224cfe5e895947dca07bd695dc Mon Sep 17 00:00:00 2001 From: Jesse Haka Date: Thu, 24 Jan 2019 09:59:51 +0200 Subject: [PATCH] fix lb pool member logic add getpool function fix govet --- upup/pkg/fi/cloudup/openstack/cloud.go | 2 + upup/pkg/fi/cloudup/openstack/loadbalancer.go | 17 +++++ .../cloudup/openstacktasks/poolassociation.go | 64 ++++++++++++++++--- 3 files changed, 75 insertions(+), 8 deletions(-) diff --git a/upup/pkg/fi/cloudup/openstack/cloud.go b/upup/pkg/fi/cloudup/openstack/cloud.go index 1856357424453..fe52c9441e6ad 100644 --- a/upup/pkg/fi/cloudup/openstack/cloud.go +++ b/upup/pkg/fi/cloudup/openstack/cloud.go @@ -194,6 +194,8 @@ type OpenstackCloud interface { CreatePool(opts v2pools.CreateOpts) (*v2pools.Pool, error) + GetPool(poolID string, memberID string) (*v2pools.Member, error) + ListPools(v2pools.ListOpts) ([]v2pools.Pool, error) ListListeners(opts listeners.ListOpts) ([]listeners.Listener, error) diff --git a/upup/pkg/fi/cloudup/openstack/loadbalancer.go b/upup/pkg/fi/cloudup/openstack/loadbalancer.go index febfed5c88c69..feb589c5e2c92 100644 --- a/upup/pkg/fi/cloudup/openstack/loadbalancer.go +++ b/upup/pkg/fi/cloudup/openstack/loadbalancer.go @@ -88,6 +88,23 @@ func (c *openstackCloud) ListLBs(opt loadbalancers.ListOptsBuilder) (lbs []loadb return lbs, nil } +func (c *openstackCloud) GetPool(poolID string, memberID string) (member *v2pools.Member, err error) { + done, err := vfs.RetryWithBackoff(readBackoff, func() (bool, error) { + member, err = v2pools.GetMember(c.neutronClient, poolID, memberID).Extract() + if err != nil { + return false, err + } + return true, nil + }) + if !done { + if err == nil { + err = wait.ErrWaitTimeout + } + return member, err + } + return member, nil +} + func (c *openstackCloud) AssociateToPool(server *servers.Server, poolID string, opts v2pools.CreateMemberOpts) (association *v2pools.Member, err error) { done, err := vfs.RetryWithBackoff(writeBackoff, func() (bool, error) { diff --git a/upup/pkg/fi/cloudup/openstacktasks/poolassociation.go b/upup/pkg/fi/cloudup/openstacktasks/poolassociation.go index e6acc655ca8ee..8c04d10bf609d 100644 --- a/upup/pkg/fi/cloudup/openstacktasks/poolassociation.go +++ b/upup/pkg/fi/cloudup/openstacktasks/poolassociation.go @@ -62,8 +62,57 @@ func (s *PoolAssociation) CompareWithID() *string { } func (p *PoolAssociation) Find(context *fi.Context) (*PoolAssociation, error) { - // Task throws no errors for members which already exist in the provided pool - return nil, nil + cloud := context.Cloud.(openstack.OpenstackCloud) + + opt := v2pools.ListOpts{ + Name: fi.StringValue(p.Pool.Name), + ID: fi.StringValue(p.Pool.ID), + } + + rs, err := cloud.ListPools(opt) + if err != nil { + return nil, err + } + if rs == nil { + return nil, nil + } else if len(rs) != 1 { + return nil, fmt.Errorf("found multiple pools with name: %s", fi.StringValue(p.Pool.Name)) + } + + a := rs[0] + // check is member already created + found := false + for _, member := range a.Members { + poolMember, err := cloud.GetPool(a.ID, member.ID) + if err != nil { + return nil, err + } + if fi.StringValue(p.Name) == poolMember.Name { + found = true + break + } + } + // if not found it is created by returning nil, nil + // this is needed for instance in initial installation + if !found { + return nil, nil + } + pool, err := NewLBPoolTaskFromCloud(cloud, p.Lifecycle, &a, nil) + if err != nil { + return nil, fmt.Errorf("NewLBListenerTaskFromCloud: failed to fetch pool %s: %v", fi.StringValue(pool.Name), err) + } + + actual := &PoolAssociation{ + ID: p.ID, + Name: p.Name, + Pool: pool, + ServerGroup: p.ServerGroup, + InterfaceName: p.InterfaceName, + ProtocolPort: p.ProtocolPort, + Lifecycle: p.Lifecycle, + } + p.ID = actual.ID + return actual, nil } func (s *PoolAssociation) Run(context *fi.Context) error { @@ -95,24 +144,23 @@ func (_ *PoolAssociation) RenderOpenstack(t *openstack.OpenstackAPITarget, a, e, return fmt.Errorf("Failed to find server with id `%s`: %v", serverID, err) } - poolAddress, err := openstack.GetServerFixedIP(server, fi.StringValue(e.InterfaceName)) + memberAddress, err := openstack.GetServerFixedIP(server, fi.StringValue(e.InterfaceName)) if err != nil { return fmt.Errorf("Failed to get fixed ip for associated pool: %v", err) } - pool, err := t.Cloud.AssociateToPool(server, fi.StringValue(e.Pool.ID), v2pools.CreateMemberOpts{ + member, err := t.Cloud.AssociateToPool(server, fi.StringValue(e.Pool.ID), v2pools.CreateMemberOpts{ Name: fi.StringValue(e.Name), ProtocolPort: fi.IntValue(e.ProtocolPort), SubnetID: fi.StringValue(e.Pool.Loadbalancer.VipSubnet), - Address: poolAddress, + Address: memberAddress, }) if err != nil { - return fmt.Errorf("Failed to create pool: %v", err) + return fmt.Errorf("Failed to create member: %v", err) } - e.ID = fi.String(pool.ID) + e.ID = fi.String(member.ID) } - return nil } else { //TODO: Update Member, this is covered as `a` will always be nil