github.com/openshift/installer@v1.4.17/pkg/asset/installconfig/installconfig.go (about) 1 package installconfig 2 3 import ( 4 "context" 5 "fmt" 6 7 "github.com/pkg/errors" 8 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 9 "k8s.io/apimachinery/pkg/util/validation/field" 10 11 "github.com/openshift/installer/pkg/asset" 12 "github.com/openshift/installer/pkg/asset/installconfig/aws" 13 icazure "github.com/openshift/installer/pkg/asset/installconfig/azure" 14 icgcp "github.com/openshift/installer/pkg/asset/installconfig/gcp" 15 icibmcloud "github.com/openshift/installer/pkg/asset/installconfig/ibmcloud" 16 icnutanix "github.com/openshift/installer/pkg/asset/installconfig/nutanix" 17 icopenstack "github.com/openshift/installer/pkg/asset/installconfig/openstack" 18 icovirt "github.com/openshift/installer/pkg/asset/installconfig/ovirt" 19 icpowervs "github.com/openshift/installer/pkg/asset/installconfig/powervs" 20 icvsphere "github.com/openshift/installer/pkg/asset/installconfig/vsphere" 21 "github.com/openshift/installer/pkg/types" 22 "github.com/openshift/installer/pkg/types/defaults" 23 "github.com/openshift/installer/pkg/types/validation" 24 ) 25 26 const ( 27 installConfigFilename = "install-config.yaml" 28 ) 29 30 // InstallConfig generates the install-config.yaml file. 31 type InstallConfig struct { 32 AssetBase 33 AWS *aws.Metadata `json:"aws,omitempty"` 34 Azure *icazure.Metadata `json:"azure,omitempty"` 35 IBMCloud *icibmcloud.Metadata `json:"ibmcloud,omitempty"` 36 PowerVS *icpowervs.Metadata `json:"powervs,omitempty"` 37 VSphere *icvsphere.Metadata `json:"vsphere,omitempty"` 38 } 39 40 var _ asset.WritableAsset = (*InstallConfig)(nil) 41 42 // MakeAsset returns an InstallConfig asset containing a given InstallConfig CR. 43 func MakeAsset(config *types.InstallConfig) *InstallConfig { 44 return &InstallConfig{ 45 AssetBase: AssetBase{ 46 Config: config, 47 }, 48 } 49 } 50 51 // Dependencies returns all of the dependencies directly needed by an 52 // InstallConfig asset. 53 func (a *InstallConfig) Dependencies() []asset.Asset { 54 return []asset.Asset{ 55 &sshPublicKey{}, 56 &baseDomain{}, 57 &clusterName{}, 58 &pullSecret{}, 59 &platform{}, 60 } 61 } 62 63 // Generate the install-config.yaml file. 64 func (a *InstallConfig) Generate(ctx context.Context, parents asset.Parents) error { 65 sshPublicKey := &sshPublicKey{} 66 baseDomain := &baseDomain{} 67 clusterName := &clusterName{} 68 pullSecret := &pullSecret{} 69 platform := &platform{} 70 parents.Get( 71 sshPublicKey, 72 baseDomain, 73 clusterName, 74 pullSecret, 75 platform, 76 ) 77 78 a.Config = &types.InstallConfig{ 79 TypeMeta: metav1.TypeMeta{ 80 APIVersion: types.InstallConfigVersion, 81 }, 82 ObjectMeta: metav1.ObjectMeta{ 83 Name: clusterName.ClusterName, 84 }, 85 SSHKey: sshPublicKey.Key, 86 BaseDomain: baseDomain.BaseDomain, 87 Publish: baseDomain.Publish, 88 PullSecret: pullSecret.PullSecret, 89 } 90 91 a.Config.AWS = platform.AWS 92 a.Config.None = platform.None 93 a.Config.OpenStack = platform.OpenStack 94 a.Config.VSphere = platform.VSphere 95 a.Config.Azure = platform.Azure 96 a.Config.GCP = platform.GCP 97 a.Config.IBMCloud = platform.IBMCloud 98 a.Config.BareMetal = platform.BareMetal 99 a.Config.Ovirt = platform.Ovirt 100 a.Config.PowerVS = platform.PowerVS 101 a.Config.Nutanix = platform.Nutanix 102 103 defaults.SetInstallConfigDefaults(a.Config) 104 105 return a.finish(ctx, "") 106 } 107 108 // Load returns the installconfig from disk. 109 func (a *InstallConfig) Load(f asset.FileFetcher) (found bool, err error) { 110 ctx := context.TODO() 111 found, err = a.LoadFromFile(f) 112 if found && err == nil { 113 if err := a.finish(ctx, installConfigFilename); err != nil { 114 return false, errors.Wrap(err, asset.InstallConfigError) 115 } 116 } 117 118 return found, err 119 } 120 121 // finishAWS set defaults for AWS Platform before the config validation. 122 func (a *InstallConfig) finishAWS() error { 123 // Set the Default Edge Compute pool when the subnets in AWS Local Zones are defined, 124 // when installing a cluster in existing VPC. 125 if len(a.Config.Platform.AWS.Subnets) > 0 { 126 edgeSubnets, err := a.AWS.EdgeSubnets(context.TODO()) 127 if err != nil { 128 return errors.Wrap(err, fmt.Sprintf("unable to load edge subnets: %v", err)) 129 } 130 totalEdgeSubnets := int64(len(edgeSubnets)) 131 if totalEdgeSubnets == 0 { 132 return nil 133 } 134 if edgePool := defaults.CreateEdgeMachinePoolDefaults(a.Config.Compute, a.Config.Platform.Name(), totalEdgeSubnets); edgePool != nil { 135 a.Config.Compute = append(a.Config.Compute, *edgePool) 136 } 137 } 138 return nil 139 } 140 141 func (a *InstallConfig) finish(ctx context.Context, filename string) error { 142 if a.Config.AWS != nil { 143 a.AWS = aws.NewMetadata(a.Config.Platform.AWS.Region, a.Config.Platform.AWS.Subnets, a.Config.AWS.ServiceEndpoints) 144 if err := a.finishAWS(); err != nil { 145 return err 146 } 147 } 148 if a.Config.Azure != nil { 149 a.Azure = icazure.NewMetadata(a.Config.Azure.CloudName, a.Config.Azure.ARMEndpoint) 150 } 151 if a.Config.IBMCloud != nil { 152 a.IBMCloud = icibmcloud.NewMetadata(a.Config) 153 } 154 if a.Config.PowerVS != nil { 155 a.PowerVS = icpowervs.NewMetadata(a.Config) 156 } 157 if a.Config.VSphere != nil { 158 a.VSphere = icvsphere.NewMetadata() 159 160 for _, v := range a.Config.VSphere.VCenters { 161 _ = a.VSphere.AddCredentials(v.Server, v.Username, v.Password) 162 } 163 } 164 165 if err := validation.ValidateInstallConfig(a.Config, false).ToAggregate(); err != nil { 166 if filename == "" { 167 return errors.Wrap(err, "invalid install config") 168 } 169 return errors.Wrapf(err, "invalid %q file", filename) 170 } 171 172 if err := a.platformValidation(ctx); err != nil { 173 return err 174 } 175 176 return a.RecordFile() 177 } 178 179 // platformValidation runs validations that require connecting to the 180 // underlying platform. In some cases, platforms also duplicate validations 181 // that have already been checked by validation.ValidateInstallConfig(). 182 func (a *InstallConfig) platformValidation(ctx context.Context) error { 183 if a.Config.Platform.Azure != nil { 184 if a.Config.Platform.Azure.IsARO() { 185 // ARO performs platform validation in the Resource Provider before 186 // the Installer is called 187 return nil 188 } 189 client, err := a.Azure.Client() 190 if err != nil { 191 return err 192 } 193 return icazure.Validate(client, a.Config) 194 } 195 if a.Config.Platform.GCP != nil { 196 client, err := icgcp.NewClient(ctx) 197 if err != nil { 198 return err 199 } 200 return icgcp.Validate(client, a.Config) 201 } 202 if a.Config.Platform.IBMCloud != nil { 203 // Validate the Service Endpoints now, before performing any additional validation of the InstallConfig 204 err := icibmcloud.ValidateServiceEndpoints(a.Config) 205 if err != nil { 206 return err 207 } 208 client, err := icibmcloud.NewClient(a.Config.Platform.IBMCloud.ServiceEndpoints) 209 if err != nil { 210 return err 211 } 212 return icibmcloud.Validate(client, a.Config) 213 } 214 if a.Config.Platform.AWS != nil { 215 return aws.Validate(ctx, a.AWS, a.Config) 216 } 217 if a.Config.Platform.VSphere != nil { 218 return icvsphere.Validate(a.Config) 219 } 220 if a.Config.Platform.Ovirt != nil { 221 return icovirt.Validate(a.Config) 222 } 223 if a.Config.Platform.OpenStack != nil { 224 return icopenstack.Validate(ctx, a.Config) 225 } 226 if a.Config.Platform.PowerVS != nil { 227 return icpowervs.Validate(a.Config) 228 } 229 if a.Config.Platform.Nutanix != nil { 230 return icnutanix.Validate(a.Config) 231 } 232 return field.ErrorList{}.ToAggregate() 233 }