Skip to content
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

fix openstack lb pool member logic #6388

Merged
merged 1 commit into from
Jan 27, 2019
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
2 changes: 2 additions & 0 deletions upup/pkg/fi/cloudup/openstack/cloud.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
17 changes: 17 additions & 0 deletions upup/pkg/fi/cloudup/openstack/loadbalancer.go
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
64 changes: 56 additions & 8 deletions upup/pkg/fi/cloudup/openstacktasks/poolassociation.go
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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
Expand Down