Skip to content

Commit ed89772

Browse files
sbueringerprankul88
authored andcommitted
Pr create floating ip on demand (kubernetes-sigs#435)
* create machine floating ips if they don't already exist * only associate floating ip if it already exists
1 parent 3429559 commit ed89772

File tree

3 files changed

+90
-6
lines changed

3 files changed

+90
-6
lines changed

pkg/cloud/openstack/machine/actuator.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import (
2727
constants "sigs.k8s.io/cluster-api-provider-openstack/pkg/cloud/openstack/contants"
2828
"sigs.k8s.io/cluster-api-provider-openstack/pkg/cloud/openstack/services/compute"
2929
"sigs.k8s.io/cluster-api-provider-openstack/pkg/cloud/openstack/services/loadbalancer"
30+
"sigs.k8s.io/cluster-api-provider-openstack/pkg/cloud/openstack/services/networking"
3031
"sigs.k8s.io/cluster-api-provider-openstack/pkg/cloud/openstack/services/provider"
3132
"sigs.k8s.io/cluster-api-provider-openstack/pkg/cloud/openstack/services/userdata"
3233
"sigs.k8s.io/cluster-api-provider-openstack/pkg/deployer"
@@ -96,6 +97,11 @@ func (a *Actuator) Create(ctx context.Context, cluster *clusterv1.Cluster, machi
9697
return err
9798
}
9899

100+
networkingService, err := networking.NewService(osProviderClient, clientOpts)
101+
if err != nil {
102+
return err
103+
}
104+
99105
clusterProviderSpec, clusterProviderStatus, err := providerv1.ClusterSpecAndStatusFromProviderSpec(cluster)
100106
if err != nil {
101107
return a.handleMachineError(machine, apierrors.CreateMachine(
@@ -149,7 +155,13 @@ func (a *Actuator) Create(ctx context.Context, cluster *clusterv1.Cluster, machi
149155
}
150156

151157
if machineProviderSpec.FloatingIP != "" {
152-
err := computeService.AssociateFloatingIP(instance.ID, machineProviderSpec.FloatingIP)
158+
err := networkingService.GetOrCreateFloatingIP(clusterProviderSpec, machineProviderSpec.FloatingIP)
159+
if err != nil {
160+
return a.handleMachineError(machine, apierrors.CreateMachine(
161+
"Create floatingIP err: %v", err))
162+
}
163+
164+
err = computeService.AssociateFloatingIP(instance.ID, machineProviderSpec.FloatingIP)
153165
if err != nil {
154166
return a.handleMachineError(machine, apierrors.CreateMachine(
155167
"Associate floatingIP err: %v", err))

pkg/cloud/openstack/services/loadbalancer/loadbalancer.go

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,16 +68,25 @@ func (s *Service) ReconcileLoadBalancer(clusterName string, clusterProviderSpec
6868
fpCreateOpts := &floatingips.CreateOpts{
6969
FloatingIP: clusterProviderSpec.APIServerLoadBalancerFloatingIP,
7070
FloatingNetworkID: clusterProviderSpec.ExternalNetworkID,
71-
PortID: lb.VipPortID,
7271
}
7372
fp, err = floatingips.Create(s.networkingClient, fpCreateOpts).Extract()
7473
if err != nil {
7574
return fmt.Errorf("error allocating floating IP: %s", err)
7675
}
77-
err = waitForFloatingIP(s.networkingClient, fp.ID, "ACTIVE")
78-
if err != nil {
79-
return err
80-
}
76+
}
77+
78+
// associate floating ip
79+
klog.Infof("Associating floating ip %s", clusterProviderSpec.APIServerLoadBalancerFloatingIP)
80+
fpUpdateOpts := &floatingips.UpdateOpts{
81+
PortID: &lb.VipPortID,
82+
}
83+
fp, err = floatingips.Update(s.networkingClient, fp.ID, fpUpdateOpts).Extract()
84+
if err != nil {
85+
return fmt.Errorf("error allocating floating IP: %s", err)
86+
}
87+
err = waitForFloatingIP(s.networkingClient, fp.ID, "ACTIVE")
88+
if err != nil {
89+
return err
8190
}
8291

8392
// lb listener
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package networking
2+
3+
import (
4+
"fmt"
5+
"github.com/gophercloud/gophercloud"
6+
"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips"
7+
"k8s.io/apimachinery/pkg/util/wait"
8+
"k8s.io/klog"
9+
providerv1 "sigs.k8s.io/cluster-api-provider-openstack/pkg/apis/openstackproviderconfig/v1alpha1"
10+
"time"
11+
)
12+
13+
func (s *Service) GetOrCreateFloatingIP(clusterProviderSpec *providerv1.OpenstackClusterProviderSpec, ip string) error {
14+
fp, err := checkIfFloatingIPExists(s.client, ip)
15+
if err != nil {
16+
return err
17+
}
18+
if fp == nil {
19+
klog.Infof("Creating floating ip %s", ip)
20+
fpCreateOpts := &floatingips.CreateOpts{
21+
FloatingIP: ip,
22+
FloatingNetworkID: clusterProviderSpec.ExternalNetworkID,
23+
}
24+
fp, err = floatingips.Create(s.client, fpCreateOpts).Extract()
25+
if err != nil {
26+
return fmt.Errorf("error allocating floating IP: %s", err)
27+
}
28+
}
29+
return nil
30+
}
31+
32+
func checkIfFloatingIPExists(client *gophercloud.ServiceClient, ip string) (*floatingips.FloatingIP, error) {
33+
allPages, err := floatingips.List(client, floatingips.ListOpts{FloatingIP: ip}).AllPages()
34+
if err != nil {
35+
return nil, err
36+
}
37+
fpList, err := floatingips.ExtractFloatingIPs(allPages)
38+
if err != nil {
39+
return nil, err
40+
}
41+
if len(fpList) == 0 {
42+
return nil, nil
43+
}
44+
return &fpList[0], nil
45+
}
46+
47+
var backoff = wait.Backoff{
48+
Steps: 10,
49+
Duration: 30 * time.Second,
50+
Factor: 1.0,
51+
Jitter: 0.1,
52+
}
53+
54+
func waitForFloatingIP(client *gophercloud.ServiceClient, id, target string) error {
55+
klog.Infof("Waiting for floatingip %s to become %s.", id, target)
56+
return wait.ExponentialBackoff(backoff, func() (bool, error) {
57+
fp, err := floatingips.Get(client, id).Extract()
58+
if err != nil {
59+
return false, err
60+
}
61+
return fp.Status == target, nil
62+
})
63+
}

0 commit comments

Comments
 (0)