Skip to content

Commit 58f46e5

Browse files
committed
cluster-api: Create bootstrap FIP
This is created in the postprovision step, since we'll attach it once the bootstrap machine has been created. Signed-off-by: Stephen Finucane <[email protected]>
1 parent 75ba853 commit 58f46e5

File tree

2 files changed

+143
-0
lines changed

2 files changed

+143
-0
lines changed

pkg/infrastructure/openstack/clusterapi/clusterapi.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"github.com/openshift/installer/pkg/asset/manifests/capiutils"
1515
"github.com/openshift/installer/pkg/infrastructure/clusterapi"
1616
"github.com/openshift/installer/pkg/infrastructure/openstack/infraready"
17+
"github.com/openshift/installer/pkg/infrastructure/openstack/postprovision"
1718
"github.com/openshift/installer/pkg/infrastructure/openstack/preprovision"
1819
"github.com/openshift/installer/pkg/rhcos"
1920
"github.com/openshift/installer/pkg/types/openstack"
@@ -102,3 +103,25 @@ func (p Provider) Ignition(ctx context.Context, in clusterapi.IgnitionInput) ([]
102103

103104
return preprovision.UploadIgnitionAndBuildShim(ctx, installConfig.Config.Platform.OpenStack.Cloud, infraID, installConfig.Config.Proxy, bootstrapIgnData)
104105
}
106+
107+
var _ clusterapi.PostProvider = Provider{}
108+
109+
// PostProvision creates and attaches a Floating IP to the Bootstrap Machine.
110+
func (p Provider) PostProvision(ctx context.Context, in clusterapi.PostProvisionInput) error {
111+
var (
112+
k8sClient = in.Client
113+
infraID = in.InfraID
114+
installConfig = in.InstallConfig
115+
)
116+
117+
ospCluster := &capo.OpenStackCluster{}
118+
key := client.ObjectKey{
119+
Name: infraID,
120+
Namespace: capiutils.Namespace,
121+
}
122+
if err := k8sClient.Get(ctx, key, ospCluster); err != nil {
123+
return fmt.Errorf("failed to get OSPCluster: %w", err)
124+
}
125+
126+
return postprovision.FloatingIPs(ctx, k8sClient, ospCluster, installConfig, infraID)
127+
}
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
package postprovision
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/gophercloud/gophercloud"
8+
"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/attributestags"
9+
"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips"
10+
"github.com/gophercloud/gophercloud/openstack/networking/v2/networks"
11+
"github.com/gophercloud/gophercloud/openstack/networking/v2/ports"
12+
capo "sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7"
13+
"sigs.k8s.io/controller-runtime/pkg/client"
14+
15+
"github.com/openshift/installer/pkg/asset/installconfig"
16+
"github.com/openshift/installer/pkg/asset/manifests/capiutils"
17+
openstackdefaults "github.com/openshift/installer/pkg/types/openstack/defaults"
18+
)
19+
20+
// FloatingIPs creates and attaches a Floating IP to the Bootstrap Machine.
21+
func FloatingIPs(ctx context.Context, c client.Client, cluster *capo.OpenStackCluster, installConfig *installconfig.InstallConfig, infraID string) error {
22+
bootstrapMachine := &capo.OpenStackMachine{}
23+
key := client.ObjectKey{
24+
Name: capiutils.GenerateBoostrapMachineName(infraID),
25+
Namespace: capiutils.Namespace,
26+
}
27+
if err := c.Get(ctx, key, bootstrapMachine); err != nil {
28+
return fmt.Errorf("failed to get bootstrap Machine: %w", err)
29+
}
30+
31+
networkClient, err := openstackdefaults.NewServiceClient("network", openstackdefaults.DefaultClientOpts(installConfig.Config.Platform.OpenStack.Cloud))
32+
if err != nil {
33+
return err
34+
}
35+
36+
bootstrapPort, err := getPortForInstance(networkClient, *bootstrapMachine.Spec.InstanceID)
37+
if err != nil {
38+
return err
39+
}
40+
41+
network, err := getNetworkByName(networkClient, cluster.Spec.ExternalNetworkID)
42+
if err != nil {
43+
return err
44+
}
45+
46+
_, err = createAndAttachFIP(networkClient, "bootstrap", infraID, network.ID, bootstrapPort.ID)
47+
if err != nil {
48+
return err
49+
}
50+
51+
return nil
52+
}
53+
54+
// Get the first port associated with an instance.
55+
//
56+
// This is used to attach a FIP to the instance.
57+
func getPortForInstance(client *gophercloud.ServiceClient, instanceID string) (*ports.Port, error) {
58+
listOpts := ports.ListOpts{
59+
DeviceID: instanceID,
60+
}
61+
allPages, err := ports.List(client, listOpts).AllPages()
62+
if err != nil {
63+
return nil, fmt.Errorf("failed to list ports: %w", err)
64+
}
65+
allPorts, err := ports.ExtractPorts(allPages)
66+
if err != nil {
67+
return nil, fmt.Errorf("failed to extract ports: %w", err)
68+
}
69+
70+
if len(allPorts) < 1 {
71+
return nil, fmt.Errorf("bootstrap machine has no associated ports")
72+
}
73+
74+
return &allPorts[0], nil
75+
}
76+
77+
// Get a network by name.
78+
func getNetworkByName(client *gophercloud.ServiceClient, name string) (*networks.Network, error) {
79+
listOpts := networks.ListOpts{
80+
Name: name,
81+
}
82+
allPages, err := networks.List(client, listOpts).AllPages()
83+
if err != nil {
84+
return nil, fmt.Errorf("failed to list networks: %w", err)
85+
}
86+
allNetworks, err := networks.ExtractNetworks(allPages)
87+
if err != nil {
88+
return nil, fmt.Errorf("failed to extract networks: %w", err)
89+
}
90+
91+
if len(allNetworks) < 1 {
92+
return nil, fmt.Errorf("found no matches for network %s", name)
93+
} else if len(allNetworks) > 1 {
94+
return nil, fmt.Errorf("found more than one match for network %s", name)
95+
}
96+
97+
return &allNetworks[0], nil
98+
}
99+
100+
// Create a floating IP.
101+
func createAndAttachFIP(client *gophercloud.ServiceClient, role, infraID, networkID, portID string) (*floatingips.FloatingIP, error) {
102+
createOpts := floatingips.CreateOpts{
103+
Description: fmt.Sprintf("%s-%s-fip", infraID, role),
104+
FloatingNetworkID: networkID,
105+
PortID: portID,
106+
}
107+
108+
floatingIP, err := floatingips.Create(client, createOpts).Extract()
109+
if err != nil {
110+
return nil, err
111+
}
112+
113+
tag := fmt.Sprintf("openshiftClusterID=%s", infraID)
114+
err = attributestags.Add(client, "floatingips", floatingIP.ID, tag).ExtractErr()
115+
if err != nil {
116+
return nil, err
117+
}
118+
119+
return floatingIP, err
120+
}

0 commit comments

Comments
 (0)