Skip to content

Commit 52ed219

Browse files
MaysaMacedopierreprinettimandre
committed
openstack: Run preprovision steps for CAPI
Co-Authored-By: Pierre Prinetti <[email protected]> Co-Authored-By: Martin André <[email protected]>
1 parent 5d01497 commit 52ed219

File tree

13 files changed

+889
-904
lines changed

13 files changed

+889
-904
lines changed

pkg/asset/cluster/cluster.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,11 @@ func (c *Cluster) Dependencies() []asset.Asset {
6161
&installconfig.PlatformCredsCheck{},
6262
&installconfig.PlatformPermsCheck{},
6363
&installconfig.PlatformProvisionCheck{},
64+
new(rhcos.Image),
6465
&quota.PlatformQuotaCheck{},
6566
&tfvars.TerraformVariables{},
6667
&password.KubeadminPassword{},
68+
&manifests.Manifests{},
6769
&capimanifests.Cluster{},
6870
&kubeconfig.AdminClient{},
6971
&bootstrap.Bootstrap{},
@@ -82,8 +84,9 @@ func (c *Cluster) Generate(parents asset.Parents) (err error) {
8284

8385
clusterID := &installconfig.ClusterID{}
8486
installConfig := &installconfig.InstallConfig{}
87+
rhcosImage := new(rhcos.Image)
8588
terraformVariables := &tfvars.TerraformVariables{}
86-
parents.Get(clusterID, installConfig, terraformVariables)
89+
parents.Get(clusterID, installConfig, terraformVariables, rhcosImage)
8790

8891
if fs := installConfig.Config.FeatureSet; strings.HasSuffix(string(fs), "NoUpgrade") {
8992
logrus.Warnf("FeatureSet %q is enabled. This FeatureSet does not allow upgrades and may affect the supportability of the cluster.", fs)
@@ -116,7 +119,14 @@ func (c *Cluster) Generate(parents asset.Parents) (err error) {
116119
return err
117120
}
118121
case typesopenstack.Name:
119-
if err := openstack.PreTerraform(); err != nil {
122+
var tfvarsFile *asset.File
123+
for _, f := range terraformVariables.Files() {
124+
if f.Filename == tfvars.TfPlatformVarsFileName {
125+
tfvarsFile = f
126+
break
127+
}
128+
}
129+
if err := openstack.PreTerraform(context.TODO(), tfvarsFile, installConfig, clusterID, rhcosImage); err != nil {
120130
return err
121131
}
122132
}

pkg/asset/cluster/openstack/openstack.go

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -3,42 +3,18 @@
33
package openstack
44

55
import (
6-
"errors"
7-
"fmt"
8-
"os"
9-
"path/filepath"
6+
"context"
107

8+
"github.com/openshift/installer/pkg/asset"
9+
"github.com/openshift/installer/pkg/asset/installconfig"
10+
"github.com/openshift/installer/pkg/asset/manifests/capiutils"
11+
rhcos_asset "github.com/openshift/installer/pkg/asset/rhcos"
12+
"github.com/openshift/installer/pkg/infrastructure/openstack/preprovision"
13+
"github.com/openshift/installer/pkg/rhcos"
1114
"github.com/openshift/installer/pkg/types"
1215
"github.com/openshift/installer/pkg/types/openstack"
1316
)
1417

15-
// PreTerraform performs any infrastructure initialization which must
16-
// happen before Terraform creates the remaining infrastructure.
17-
func PreTerraform() error {
18-
// Terraform runs in a different directory but we want to allow people to
19-
// use clouds.yaml files in their local directory. Emulate this by setting
20-
// the necessary environment variable to point to this file if (a) the user
21-
// hasn't already set this environment variable and (b) there is actually
22-
// a local file
23-
if path := os.Getenv("OS_CLIENT_CONFIG_FILE"); path != "" {
24-
return nil
25-
}
26-
27-
cwd, err := os.Getwd()
28-
if err != nil {
29-
return fmt.Errorf("unable to determine working directory: %w", err)
30-
}
31-
32-
cloudsYAML := filepath.Join(cwd, "clouds.yaml")
33-
if _, err = os.Stat(cloudsYAML); err == nil {
34-
os.Setenv("OS_CLIENT_CONFIG_FILE", cloudsYAML)
35-
} else if !errors.Is(err, os.ErrNotExist) {
36-
return fmt.Errorf("unable to determine if clouds.yaml exists: %w", err)
37-
}
38-
39-
return nil
40-
}
41-
4218
// Metadata converts an install configuration to OpenStack metadata.
4319
func Metadata(infraID string, config *types.InstallConfig) *openstack.Metadata {
4420
return &openstack.Metadata{
@@ -48,3 +24,28 @@ func Metadata(infraID string, config *types.InstallConfig) *openstack.Metadata {
4824
},
4925
}
5026
}
27+
28+
// PreTerraform performs any infrastructure initialization which must
29+
// happen before Terraform creates the remaining infrastructure.
30+
func PreTerraform(ctx context.Context, tfvarsFile *asset.File, installConfig *installconfig.InstallConfig, clusterID *installconfig.ClusterID, rhcosImage *rhcos_asset.Image) error {
31+
if !capiutils.IsEnabled(installConfig) {
32+
if err := preprovision.ReplaceBootstrapIgnitionInTFVars(ctx, tfvarsFile, installConfig, clusterID); err != nil {
33+
return err
34+
}
35+
36+
if err := preprovision.TagVIPPorts(ctx, installConfig, clusterID.InfraID); err != nil {
37+
return err
38+
}
39+
40+
// upload the corresponding image to Glance if rhcosImage contains a
41+
// URL. If rhcosImage contains a name, then that points to an existing
42+
// Glance image.
43+
if imageName, isURL := rhcos.GenerateOpenStackImageName(string(*rhcosImage), clusterID.InfraID); isURL {
44+
if err := preprovision.UploadBaseImage(ctx, installConfig.Config.Platform.OpenStack.Cloud, string(*rhcosImage), imageName, clusterID.InfraID, installConfig.Config.Platform.OpenStack.ClusterOSImageProperties); err != nil {
45+
return err
46+
}
47+
}
48+
}
49+
50+
return preprovision.SetTerraformEnvironment()
51+
}

pkg/destroy/bootstrap/bootstrap.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ import (
1212

1313
configv1 "github.com/openshift/api/config/v1"
1414
"github.com/openshift/installer/pkg/asset/cluster/metadata"
15-
openstackasset "github.com/openshift/installer/pkg/asset/cluster/openstack"
1615
osp "github.com/openshift/installer/pkg/destroy/openstack"
16+
"github.com/openshift/installer/pkg/infrastructure/openstack/preprovision"
1717
infra "github.com/openshift/installer/pkg/infrastructure/platform"
1818
ibmcloudtfvars "github.com/openshift/installer/pkg/tfvars/ibmcloud"
1919
typesazure "github.com/openshift/installer/pkg/types/azure"
@@ -35,7 +35,7 @@ func Destroy(ctx context.Context, dir string) (err error) {
3535
}
3636

3737
if platform == openstack.Name {
38-
if err := openstackasset.PreTerraform(); err != nil {
38+
if err := preprovision.SetTerraformEnvironment(); err != nil {
3939
return errors.Wrapf(err, "Failed to initialize infrastructure")
4040
}
4141

pkg/infrastructure/openstack/clusterapi/clusterapi.go

Lines changed: 92 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,22 @@ import (
44
"context"
55
"fmt"
66

7-
capo "sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7"
8-
"sigs.k8s.io/controller-runtime/pkg/client"
9-
107
"github.com/gophercloud/gophercloud"
118
"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/attributestags"
129
"github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips"
1310
"github.com/gophercloud/gophercloud/openstack/networking/v2/ports"
11+
"github.com/sirupsen/logrus"
12+
"gopkg.in/yaml.v2"
13+
capo "sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha7"
14+
"sigs.k8s.io/controller-runtime/pkg/client"
15+
16+
configv1 "github.com/openshift/api/config/v1"
17+
"github.com/openshift/installer/pkg/asset/manifests"
1418
"github.com/openshift/installer/pkg/asset/manifests/capiutils"
1519
"github.com/openshift/installer/pkg/infrastructure/clusterapi"
20+
"github.com/openshift/installer/pkg/infrastructure/openstack/preprovision"
21+
"github.com/openshift/installer/pkg/rhcos"
22+
"github.com/openshift/installer/pkg/types/openstack"
1623
openstackdefaults "github.com/openshift/installer/pkg/types/openstack/defaults"
1724
)
1825

@@ -21,42 +28,89 @@ type Provider struct {
2128
clusterapi.InfraProvider
2229
}
2330

24-
// func (p Provider) PreProvision(in clusterapi.PreProvisionInput) error {
25-
// return nil
26-
// }
31+
// Name contains the name of the openstack provider.
32+
func (p Provider) Name() string {
33+
return openstack.Name
34+
}
35+
36+
var _ clusterapi.PreProvider = Provider{}
37+
38+
// PreProvision tags the VIP ports and creates the security groups that are needed during CAPI provisioning.
39+
func (p Provider) PreProvision(ctx context.Context, in clusterapi.PreProvisionInput) error {
40+
var (
41+
infraID = in.InfraID
42+
installConfig = in.InstallConfig
43+
rhcosImage = string(*in.RhcosImage)
44+
mastersSchedulable bool
45+
)
46+
47+
for _, f := range in.ManifestsAsset.Files() {
48+
if f.Filename == manifests.SchedulerCfgFilename {
49+
schedulerConfig := configv1.Scheduler{}
50+
if err := yaml.Unmarshal(f.Data, &schedulerConfig); err != nil {
51+
return fmt.Errorf("unable to decode the scheduler manifest: %w", err)
52+
}
53+
mastersSchedulable = schedulerConfig.Spec.MastersSchedulable
54+
break
55+
}
56+
}
57+
58+
if err := preprovision.TagVIPPorts(ctx, installConfig, infraID); err != nil {
59+
return err
60+
}
61+
62+
// upload the corresponding image to Glance if rhcosImage contains a
63+
// URL. If rhcosImage contains a name, then that points to an existing
64+
// Glance image.
65+
if imageName, isURL := rhcos.GenerateOpenStackImageName(rhcosImage, infraID); isURL {
66+
if err := preprovision.UploadBaseImage(ctx, installConfig.Config.Platform.OpenStack.Cloud, rhcosImage, imageName, infraID, installConfig.Config.Platform.OpenStack.ClusterOSImageProperties); err != nil {
67+
return err
68+
}
69+
}
70+
71+
return preprovision.SecurityGroups(ctx, installConfig, infraID, mastersSchedulable)
72+
}
73+
74+
var _ clusterapi.InfraReadyProvider = Provider{}
2775

28-
func (p Provider) ControlPlaneAvailable(in clusterapi.ControlPlaneAvailableInput) error {
76+
// InfraReady creates the API and Ingress ports and attaches the Floating IPs to them.
77+
func (p Provider) InfraReady(ctx context.Context, in clusterapi.InfraReadyInput) error {
78+
var (
79+
k8sClient = in.Client
80+
infraID = in.InfraID
81+
installConfig = in.InstallConfig
82+
)
2983
ospCluster := &capo.OpenStackCluster{}
3084
key := client.ObjectKey{
31-
Name: in.InfraID,
85+
Name: infraID,
3286
Namespace: capiutils.Namespace,
3387
}
34-
if err := in.Client.Get(context.Background(), key, ospCluster); err != nil {
88+
if err := k8sClient.Get(ctx, key, ospCluster); err != nil {
3589
return fmt.Errorf("failed to get OSPCluster: %w", err)
3690
}
3791

38-
networkClient, err := openstackdefaults.NewServiceClient("network", openstackdefaults.DefaultClientOpts(in.InstallConfig.Config.Platform.OpenStack.Cloud))
92+
networkClient, err := openstackdefaults.NewServiceClient("network", openstackdefaults.DefaultClientOpts(installConfig.Config.Platform.OpenStack.Cloud))
3993
if err != nil {
4094
return err
4195
}
4296

43-
apiPort, err := createPort(networkClient, "api", in.InfraID, ospCluster.Status.Network.ID)
97+
apiPort, err := createPort(networkClient, "api", infraID, ospCluster.Status.Network.ID, ospCluster.Status.Network.Subnets[0].ID, installConfig.Config.Platform.OpenStack.APIVIPs[0])
4498
if err != nil {
4599
return err
46100
}
47-
if in.InstallConfig.Config.OpenStack.APIFloatingIP != "" {
48-
err = assignFIP(networkClient, in.InstallConfig.Config.OpenStack.APIFloatingIP, apiPort)
101+
if installConfig.Config.OpenStack.APIFloatingIP != "" {
102+
err = assignFIP(networkClient, installConfig.Config.OpenStack.APIFloatingIP, apiPort)
49103
if err != nil {
50104
return err
51105
}
52106
}
53107

54-
ingressPort, err := createPort(networkClient, "ingress", in.InfraID, ospCluster.Status.Network.ID)
108+
ingressPort, err := createPort(networkClient, "ingress", infraID, ospCluster.Status.Network.ID, ospCluster.Status.Network.Subnets[0].ID, installConfig.Config.Platform.OpenStack.IngressVIPs[0])
55109
if err != nil {
56110
return err
57111
}
58-
if in.InstallConfig.Config.OpenStack.IngressFloatingIP != "" {
59-
err = assignFIP(networkClient, in.InstallConfig.Config.OpenStack.IngressFloatingIP, ingressPort)
112+
if installConfig.Config.OpenStack.IngressFloatingIP != "" {
113+
err = assignFIP(networkClient, installConfig.Config.OpenStack.IngressFloatingIP, ingressPort)
60114
if err != nil {
61115
return err
62116
}
@@ -65,14 +119,33 @@ func (p Provider) ControlPlaneAvailable(in clusterapi.ControlPlaneAvailableInput
65119
return nil
66120
}
67121

68-
func createPort(client *gophercloud.ServiceClient, role, infraID, networkID string) (*ports.Port, error) {
69-
createOtps := ports.CreateOpts{
122+
var _ clusterapi.IgnitionProvider = Provider{}
123+
124+
// Ignition uploads the bootstrap machine's Ignition file to OpenStack.
125+
func (p Provider) Ignition(ctx context.Context, in clusterapi.IgnitionInput) ([]byte, error) {
126+
logrus.Debugf("Uploading the bootstrap machine's Ignition file to OpenStack")
127+
var (
128+
bootstrapIgnData = in.BootstrapIgnData
129+
infraID = in.InfraID
130+
installConfig = in.InstallConfig
131+
)
132+
133+
return preprovision.UploadIgnitionAndBuildShim(ctx, installConfig.Config.Platform.OpenStack.Cloud, infraID, installConfig.Config.Proxy, bootstrapIgnData)
134+
}
135+
136+
func createPort(client *gophercloud.ServiceClient, role, infraID, networkID, subnetID, fixedIP string) (*ports.Port, error) {
137+
createOpts := ports.CreateOpts{
70138
Name: fmt.Sprintf("%s-%s-port", infraID, role),
71139
NetworkID: networkID,
72140
Description: "Created By OpenShift Installer",
141+
FixedIPs: []ports.IP{
142+
{
143+
IPAddress: fixedIP,
144+
SubnetID: subnetID,
145+
}},
73146
}
74147

75-
port, err := ports.Create(client, createOtps).Extract()
148+
port, err := ports.Create(client, createOpts).Extract()
76149
if err != nil {
77150
return nil, err
78151
}

0 commit comments

Comments
 (0)