@@ -5,30 +5,23 @@ import (
55 "fmt"
66 "path/filepath"
77 "strings"
8- "time"
98
109 "github.com/pkg/errors"
1110 "github.com/sirupsen/logrus"
12- "gopkg.in/yaml.v2"
13- apierrors "k8s.io/apimachinery/pkg/api/errors"
14- "k8s.io/apimachinery/pkg/util/wait"
15- clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
16- utilkubeconfig "sigs.k8s.io/cluster-api/util/kubeconfig"
17- "sigs.k8s.io/controller-runtime/pkg/client"
18- "sigs.k8s.io/controller-runtime/pkg/manager/signals"
1911
2012 "github.com/openshift/installer/pkg/asset"
2113 "github.com/openshift/installer/pkg/asset/cluster/aws"
2214 "github.com/openshift/installer/pkg/asset/cluster/azure"
2315 "github.com/openshift/installer/pkg/asset/cluster/openstack"
16+ "github.com/openshift/installer/pkg/asset/cluster/tfvars"
17+ "github.com/openshift/installer/pkg/asset/ignition/bootstrap"
18+ "github.com/openshift/installer/pkg/asset/ignition/machine"
2419 "github.com/openshift/installer/pkg/asset/installconfig"
25- awsconfig "github.com/openshift/installer/pkg/asset/installconfig/aws"
2620 "github.com/openshift/installer/pkg/asset/kubeconfig"
27- "github.com/openshift/installer/pkg/asset/manifests/capiutils "
21+ "github.com/openshift/installer/pkg/asset/machines "
2822 capimanifests "github.com/openshift/installer/pkg/asset/manifests/clusterapi"
2923 "github.com/openshift/installer/pkg/asset/password"
3024 "github.com/openshift/installer/pkg/asset/quota"
31- "github.com/openshift/installer/pkg/clusterapi"
3225 infra "github.com/openshift/installer/pkg/infrastructure/platform"
3326 typesaws "github.com/openshift/installer/pkg/types/aws"
3427 typesazure "github.com/openshift/installer/pkg/types/azure"
@@ -67,10 +60,13 @@ func (c *Cluster) Dependencies() []asset.Asset {
6760 & installconfig.PlatformPermsCheck {},
6861 & installconfig.PlatformProvisionCheck {},
6962 & quota.PlatformQuotaCheck {},
70- & TerraformVariables {},
63+ & tfvars. TerraformVariables {},
7164 & password.KubeadminPassword {},
7265 & capimanifests.Cluster {},
7366 & kubeconfig.AdminClient {},
67+ & bootstrap.Bootstrap {},
68+ & machine.Master {},
69+ & machines.ClusterAPI {},
7470 }
7571}
7672
@@ -82,7 +78,7 @@ func (c *Cluster) Generate(parents asset.Parents) (err error) {
8278
8379 clusterID := & installconfig.ClusterID {}
8480 installConfig := & installconfig.InstallConfig {}
85- terraformVariables := & TerraformVariables {}
81+ terraformVariables := & tfvars. TerraformVariables {}
8682 parents .Get (clusterID , installConfig , terraformVariables )
8783
8884 if fs := installConfig .Config .FeatureSet ; strings .HasSuffix (string (fs ), "NoUpgrade" ) {
@@ -97,31 +93,14 @@ func (c *Cluster) Generate(parents asset.Parents) (err error) {
9793 return errors .New ("cluster cannot be created with bootstrapInPlace set" )
9894 }
9995
100- // Check if we're using Cluster API.
101- if capiutils .IsEnabled (installConfig ) {
102- // TODO(vincepri): The context should be passed down from the caller,
103- // although today the Asset interface doesn't allow it, refactor once it does.
104- ctx , cancel := context .WithCancel (signals .SetupSignalHandler ())
105- go func () {
106- <- ctx .Done ()
107- cancel ()
108- clusterapi .System ().Teardown ()
109- }()
110-
111- return c .provisionWithClusterAPI (ctx , parents , installConfig , clusterID )
112- }
113-
114- // Otherwise, use the normal path.
115- return c .provision (installConfig , clusterID , terraformVariables )
116- }
117-
118- func (c * Cluster ) provision (installConfig * installconfig.InstallConfig , clusterID * installconfig.ClusterID , terraformVariables * TerraformVariables ) error {
11996 platform := installConfig .Config .Platform .Name ()
12097
12198 if azure := installConfig .Config .Platform .Azure ; azure != nil && azure .CloudName == typesazure .StackCloud {
12299 platform = typesazure .StackTerraformName
123100 }
124101
102+ // TODO(padillon): determine whether CAPI handles tagging shared subnets, in which case we should be able
103+ // to encapsulate these into the terraform package.
125104 logrus .Infof ("Creating infrastructure resources..." )
126105 switch platform {
127106 case typesaws .Name :
@@ -138,16 +117,11 @@ func (c *Cluster) provision(installConfig *installconfig.InstallConfig, clusterI
138117 }
139118 }
140119
141- tfvarsFiles := []* asset.File {}
142- for _ , file := range terraformVariables .Files () {
143- tfvarsFiles = append (tfvarsFiles , file )
144- }
145-
146120 provider , err := infra .ProviderForPlatform (platform , installConfig .Config .EnabledFeatureGates ())
147121 if err != nil {
148122 return fmt .Errorf ("error getting infrastructure provider: %w" , err )
149123 }
150- files , err := provider .Provision (InstallDir , tfvarsFiles )
124+ files , err := provider .Provision (InstallDir , parents )
151125 if files != nil {
152126 c .FileList = append (c .FileList , files ... ) // append state files even in case of failure
153127 }
@@ -158,137 +132,6 @@ func (c *Cluster) provision(installConfig *installconfig.InstallConfig, clusterI
158132 return nil
159133}
160134
161- func (c * Cluster ) provisionWithClusterAPI (ctx context.Context , parents asset.Parents , installConfig * installconfig.InstallConfig , clusterID * installconfig.ClusterID ) error {
162- capiManifests := & capimanifests.Cluster {}
163- clusterKubeconfigAsset := & kubeconfig.AdminClient {}
164- parents .Get (
165- capiManifests ,
166- clusterKubeconfigAsset ,
167- )
168-
169- // Only need the objects--not the files.
170- manifests := []client.Object {}
171- for _ , m := range capiManifests .RuntimeFiles () {
172- manifests = append (manifests , m .Object )
173- }
174-
175- // Run the CAPI system.
176- capiSystem := clusterapi .System ()
177- if err := capiSystem .Run (ctx , installConfig ); err != nil {
178- return fmt .Errorf ("failed to run cluster api system: %w" , err )
179- }
180-
181- // Grab the client.
182- cl := capiSystem .Client ()
183-
184- // Create all the manifests and store them.
185- for _ , m := range manifests {
186- m .SetNamespace (capiutils .Namespace )
187- if err := cl .Create (context .Background (), m ); err != nil {
188- return fmt .Errorf ("failed to create manifest: %w" , err )
189- }
190- logrus .Infof ("Created manifest %+T, namespace=%s name=%s" , m , m .GetNamespace (), m .GetName ())
191- }
192-
193- // Pass cluster kubeconfig and store it in; this is usually the role of a bootstrap provider.
194- {
195- key := client.ObjectKey {
196- Name : clusterID .InfraID ,
197- Namespace : capiutils .Namespace ,
198- }
199- cluster := & clusterv1.Cluster {}
200- if err := cl .Get (context .Background (), key , cluster ); err != nil {
201- return err
202- }
203- // Create the secret.
204- clusterKubeconfig := clusterKubeconfigAsset .Files ()[0 ].Data
205- secret := utilkubeconfig .GenerateSecret (cluster , clusterKubeconfig )
206- if err := cl .Create (context .Background (), secret ); err != nil {
207- return err
208- }
209- }
210-
211- // Wait for the load balancer to be ready by checking the control plane endpoint
212- // on the cluster object.
213- var cluster * clusterv1.Cluster
214- {
215- if err := wait .ExponentialBackoff (wait.Backoff {
216- Duration : time .Second * 10 ,
217- Factor : float64 (1.5 ),
218- Steps : 32 ,
219- }, func () (bool , error ) {
220- c := & clusterv1.Cluster {}
221- if err := cl .Get (context .Background (), client.ObjectKey {
222- Name : clusterID .InfraID ,
223- Namespace : capiutils .Namespace ,
224- }, c ); err != nil {
225- if apierrors .IsNotFound (err ) {
226- return false , nil
227- }
228- return false , err
229- }
230- cluster = c
231- return cluster .Spec .ControlPlaneEndpoint .IsValid (), nil
232- }); err != nil {
233- return err
234- }
235- if cluster == nil {
236- return errors .New ("error occurred during load balancer ready check" )
237- }
238- if cluster .Spec .ControlPlaneEndpoint .Host == "" {
239- return errors .New ("control plane endpoint is not set" )
240- }
241- }
242-
243- // Run the post-provisioning steps for the platform we're on.
244- // TODO(vincepri): The following should probably be in a separate package with a clear
245- // interface and multiple hooks at different stages of the cluster lifecycle.
246- switch installConfig .Config .Platform .Name () {
247- case typesaws .Name :
248- ssn , err := installConfig .AWS .Session (context .TODO ())
249- if err != nil {
250- return fmt .Errorf ("failed to create session: %w" , err )
251- }
252- client := awsconfig .NewClient (ssn )
253- r53cfg := awsconfig .GetR53ClientCfg (ssn , "" )
254- err = client .CreateOrUpdateRecord (installConfig .Config , cluster .Spec .ControlPlaneEndpoint .Host , r53cfg )
255- if err != nil {
256- return fmt .Errorf ("failed to create route53 records: %w" , err )
257- }
258- logrus .Infof ("Created Route53 records to control plane load balancer." )
259- default :
260- }
261-
262- // For each manifest we created, retrieve it and store it in the asset.
263- for _ , m := range manifests {
264- key := client.ObjectKey {
265- Name : m .GetName (),
266- Namespace : m .GetNamespace (),
267- }
268- if err := cl .Get (context .Background (), key , m ); err != nil {
269- return fmt .Errorf ("failed to get manifest: %w" , err )
270- }
271-
272- gvk , err := cl .GroupVersionKindFor (m )
273- if err != nil {
274- return fmt .Errorf ("failed to get GVK for manifest: %w" , err )
275- }
276- fileName := fmt .Sprintf ("%s-%s-%s.yaml" , gvk .Kind , m .GetNamespace (), m .GetName ())
277- objData , err := yaml .Marshal (m )
278- if err != nil {
279- errMsg := fmt .Sprintf ("failed to create infrastructure manifest %s from InstallConfig" , fileName )
280- return errors .Wrapf (err , errMsg )
281- }
282- c .FileList = append (c .FileList , & asset.File {
283- Filename : fileName ,
284- Data : objData ,
285- })
286- }
287-
288- logrus .Infof ("Cluster API resources have been created. Waiting for cluster to become ready..." )
289- return nil
290- }
291-
292135// Files returns the FileList generated by the asset.
293136func (c * Cluster ) Files () []* asset.File {
294137 return c .FileList
0 commit comments