@@ -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