github.com/openshift/installer@v1.4.17/pkg/asset/manifests/infrastructure.go (about) 1 package manifests 2 3 import ( 4 "context" 5 "fmt" 6 "path/filepath" 7 "sort" 8 9 "github.com/pkg/errors" 10 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 11 "sigs.k8s.io/yaml" 12 13 configv1 "github.com/openshift/api/config/v1" 14 "github.com/openshift/installer/pkg/asset" 15 "github.com/openshift/installer/pkg/asset/installconfig" 16 externalinfra "github.com/openshift/installer/pkg/asset/manifests/external" 17 gcpmanifests "github.com/openshift/installer/pkg/asset/manifests/gcp" 18 nutanixinfra "github.com/openshift/installer/pkg/asset/manifests/nutanix" 19 vsphereinfra "github.com/openshift/installer/pkg/asset/manifests/vsphere" 20 "github.com/openshift/installer/pkg/types" 21 "github.com/openshift/installer/pkg/types/aws" 22 "github.com/openshift/installer/pkg/types/azure" 23 "github.com/openshift/installer/pkg/types/baremetal" 24 "github.com/openshift/installer/pkg/types/external" 25 "github.com/openshift/installer/pkg/types/gcp" 26 "github.com/openshift/installer/pkg/types/ibmcloud" 27 "github.com/openshift/installer/pkg/types/none" 28 "github.com/openshift/installer/pkg/types/nutanix" 29 "github.com/openshift/installer/pkg/types/openstack" 30 "github.com/openshift/installer/pkg/types/ovirt" 31 "github.com/openshift/installer/pkg/types/powervs" 32 "github.com/openshift/installer/pkg/types/vsphere" 33 ) 34 35 var ( 36 infraCfgFilename = filepath.Join(manifestDir, "cluster-infrastructure-02-config.yml") 37 cloudControllerUIDFilename = filepath.Join(manifestDir, "cloud-controller-uid-config.yml") 38 ) 39 40 // Infrastructure generates the cluster-infrastructure-*.yml files. 41 type Infrastructure struct { 42 FileList []*asset.File 43 } 44 45 var _ asset.WritableAsset = (*Infrastructure)(nil) 46 47 // Name returns a human friendly name for the asset. 48 func (*Infrastructure) Name() string { 49 return "Infrastructure Config" 50 } 51 52 // Dependencies returns all of the dependencies directly needed to generate 53 // the asset. 54 func (*Infrastructure) Dependencies() []asset.Asset { 55 return []asset.Asset{ 56 &installconfig.ClusterID{}, 57 &installconfig.InstallConfig{}, 58 &CloudProviderConfig{}, 59 &AdditionalTrustBundleConfig{}, 60 } 61 } 62 63 // Generate generates the Infrastructure config and its CRD. 64 // 65 //nolint:gocyclo 66 func (i *Infrastructure) Generate(ctx context.Context, dependencies asset.Parents) error { 67 cloudProviderConfigMapKey := cloudProviderConfigDataKey 68 clusterID := &installconfig.ClusterID{} 69 installConfig := &installconfig.InstallConfig{} 70 cloudproviderconfig := &CloudProviderConfig{} 71 trustbundleconfig := &AdditionalTrustBundleConfig{} 72 dependencies.Get(clusterID, installConfig, cloudproviderconfig, trustbundleconfig) 73 74 config := &configv1.Infrastructure{ 75 TypeMeta: metav1.TypeMeta{ 76 APIVersion: configv1.SchemeGroupVersion.String(), 77 Kind: "Infrastructure", 78 }, 79 ObjectMeta: metav1.ObjectMeta{ 80 Name: "cluster", 81 // not namespaced 82 }, 83 Spec: configv1.InfrastructureSpec{ 84 PlatformSpec: configv1.PlatformSpec{}, 85 }, 86 Status: configv1.InfrastructureStatus{ 87 InfrastructureName: clusterID.InfraID, 88 APIServerURL: getAPIServerURL(installConfig.Config), 89 APIServerInternalURL: getInternalAPIServerURL(installConfig.Config), 90 PlatformStatus: &configv1.PlatformStatus{}, 91 }, 92 } 93 94 controlPlaneTopology, infrastructureTopology := determineTopologies(installConfig.Config) 95 96 config.Status.InfrastructureTopology = infrastructureTopology 97 config.Status.ControlPlaneTopology = controlPlaneTopology 98 config.Status.CPUPartitioning = determineCPUPartitioning(installConfig.Config) 99 100 switch installConfig.Config.Platform.Name() { 101 case aws.Name: 102 config.Spec.PlatformSpec.Type = configv1.AWSPlatformType 103 config.Spec.PlatformSpec.AWS = &configv1.AWSPlatformSpec{} 104 105 var resourceTags []configv1.AWSResourceTag 106 if installConfig.Config.AWS.PropagateUserTag { 107 resourceTags = make([]configv1.AWSResourceTag, 0, len(installConfig.Config.AWS.UserTags)) 108 for k, v := range installConfig.Config.AWS.UserTags { 109 resourceTags = append(resourceTags, configv1.AWSResourceTag{Key: k, Value: v}) 110 } 111 } 112 config.Status.PlatformStatus.AWS = &configv1.AWSPlatformStatus{ 113 Region: installConfig.Config.Platform.AWS.Region, 114 ResourceTags: resourceTags, 115 } 116 117 for _, service := range installConfig.Config.Platform.AWS.ServiceEndpoints { 118 config.Spec.PlatformSpec.AWS.ServiceEndpoints = append(config.Spec.PlatformSpec.AWS.ServiceEndpoints, configv1.AWSServiceEndpoint{ 119 Name: service.Name, 120 URL: service.URL, 121 }) 122 config.Status.PlatformStatus.AWS.ServiceEndpoints = append(config.Status.PlatformStatus.AWS.ServiceEndpoints, configv1.AWSServiceEndpoint{ 123 Name: service.Name, 124 URL: service.URL, 125 }) 126 sort.Slice(config.Status.PlatformStatus.AWS.ServiceEndpoints, func(i, j int) bool { 127 return config.Status.PlatformStatus.AWS.ServiceEndpoints[i].Name < 128 config.Status.PlatformStatus.AWS.ServiceEndpoints[j].Name 129 }) 130 } 131 case azure.Name: 132 config.Spec.PlatformSpec.Type = configv1.AzurePlatformType 133 134 rg := installConfig.Config.Azure.ClusterResourceGroupName(clusterID.InfraID) 135 config.Status.PlatformStatus.Azure = &configv1.AzurePlatformStatus{ 136 ResourceGroupName: rg, 137 NetworkResourceGroupName: rg, 138 CloudName: configv1.AzureCloudEnvironment(installConfig.Config.Platform.Azure.CloudName), 139 } 140 if nrg := installConfig.Config.Platform.Azure.NetworkResourceGroupName; nrg != "" { 141 config.Status.PlatformStatus.Azure.NetworkResourceGroupName = nrg 142 } 143 if installConfig.Config.Platform.Azure.CloudName == azure.StackCloud { 144 config.Status.PlatformStatus.Azure.ARMEndpoint = installConfig.Config.Platform.Azure.ARMEndpoint 145 } 146 if len(installConfig.Config.Azure.UserTags) > 0 { 147 resourceTags := make([]configv1.AzureResourceTag, 0, len(installConfig.Config.Azure.UserTags)) 148 for k, v := range installConfig.Config.Azure.UserTags { 149 resourceTags = append(resourceTags, configv1.AzureResourceTag{Key: k, Value: v}) 150 } 151 config.Status.PlatformStatus.Azure.ResourceTags = resourceTags 152 } 153 case baremetal.Name: 154 config.Spec.PlatformSpec.Type = configv1.BareMetalPlatformType 155 config.Spec.PlatformSpec.BareMetal = &configv1.BareMetalPlatformSpec{} 156 config.Status.PlatformStatus.BareMetal = &configv1.BareMetalPlatformStatus{ 157 APIServerInternalIP: installConfig.Config.Platform.BareMetal.APIVIPs[0], 158 IngressIP: installConfig.Config.Platform.BareMetal.IngressVIPs[0], 159 APIServerInternalIPs: installConfig.Config.Platform.BareMetal.APIVIPs, 160 IngressIPs: installConfig.Config.Platform.BareMetal.IngressVIPs, 161 LoadBalancer: installConfig.Config.Platform.BareMetal.LoadBalancer, 162 } 163 config.Spec.PlatformSpec.BareMetal.APIServerInternalIPs = types.StringsToIPs(installConfig.Config.Platform.BareMetal.APIVIPs) 164 config.Spec.PlatformSpec.BareMetal.IngressIPs = types.StringsToIPs(installConfig.Config.Platform.BareMetal.IngressVIPs) 165 config.Spec.PlatformSpec.BareMetal.MachineNetworks = types.MachineNetworksToCIDRs(installConfig.Config.MachineNetwork) 166 config.Status.PlatformStatus.BareMetal.MachineNetworks = types.MachineNetworksToCIDRs(installConfig.Config.MachineNetwork) 167 case gcp.Name: 168 config.Spec.PlatformSpec.Type = configv1.GCPPlatformType 169 config.Status.PlatformStatus.GCP = &configv1.GCPPlatformStatus{ 170 ProjectID: installConfig.Config.Platform.GCP.ProjectID, 171 Region: installConfig.Config.Platform.GCP.Region, 172 } 173 uidConfigMap := gcpmanifests.CloudControllerUID(clusterID.InfraID) 174 content, err := yaml.Marshal(uidConfigMap) 175 if err != nil { 176 return errors.Wrapf(err, "cannot marshal GCP cloud controller UID config map") 177 } 178 i.FileList = append(i.FileList, &asset.File{ 179 Filename: cloudControllerUIDFilename, 180 Data: content, 181 }) 182 if len(installConfig.Config.GCP.UserLabels) > 0 { 183 resourceLabels := make([]configv1.GCPResourceLabel, len(installConfig.Config.GCP.UserLabels)) 184 for i, label := range installConfig.Config.GCP.UserLabels { 185 resourceLabels[i] = configv1.GCPResourceLabel{Key: label.Key, Value: label.Value} 186 } 187 config.Status.PlatformStatus.GCP.ResourceLabels = resourceLabels 188 } 189 if len(installConfig.Config.GCP.UserTags) > 0 { 190 resourceTags := make([]configv1.GCPResourceTag, len(installConfig.Config.GCP.UserTags)) 191 for i, tag := range installConfig.Config.GCP.UserTags { 192 resourceTags[i] = configv1.GCPResourceTag{ParentID: tag.ParentID, Key: tag.Key, Value: tag.Value} 193 } 194 config.Status.PlatformStatus.GCP.ResourceTags = resourceTags 195 } 196 // If the user has requested the use of a DNS provisioned by them, then OpenShift needs to 197 // start an in-cluster DNS for the installation to succeed. The user can then configure their 198 // DNS post-install. 199 config.Status.PlatformStatus.GCP.CloudLoadBalancerConfig = &configv1.CloudLoadBalancerConfig{} 200 config.Status.PlatformStatus.GCP.CloudLoadBalancerConfig.DNSType = configv1.PlatformDefaultDNSType 201 if installConfig.Config.GCP.UserProvisionedDNS == gcp.UserProvisionedDNSEnabled { 202 config.Status.PlatformStatus.GCP.CloudLoadBalancerConfig.DNSType = configv1.ClusterHostedDNSType 203 } 204 case ibmcloud.Name: 205 config.Spec.PlatformSpec.Type = configv1.IBMCloudPlatformType 206 var cisInstanceCRN, dnsInstanceCRN string 207 if installConfig.Config.Publish == types.InternalPublishingStrategy { 208 dnsInstance, err := installConfig.IBMCloud.DNSInstance(ctx) 209 if err != nil { 210 return errors.Wrap(err, "cannot retrieve IBM DNS Services instance CRN") 211 } 212 dnsInstanceCRN = dnsInstance.CRN 213 } else { 214 crn, err := installConfig.IBMCloud.CISInstanceCRN(ctx) 215 if err != nil { 216 return errors.Wrap(err, "cannot retrieve IBM Cloud Internet Services instance CRN") 217 } 218 cisInstanceCRN = crn 219 } 220 config.Status.PlatformStatus.IBMCloud = &configv1.IBMCloudPlatformStatus{ 221 Location: installConfig.Config.Platform.IBMCloud.Region, 222 ResourceGroupName: installConfig.Config.Platform.IBMCloud.ClusterResourceGroupName(clusterID.InfraID), 223 CISInstanceCRN: cisInstanceCRN, 224 DNSInstanceCRN: dnsInstanceCRN, 225 ProviderType: configv1.IBMCloudProviderTypeVPC, 226 ServiceEndpoints: installConfig.Config.Platform.IBMCloud.ServiceEndpoints, 227 } 228 case external.Name: 229 config.Spec.PlatformSpec.Type = configv1.ExternalPlatformType 230 config.Spec.PlatformSpec.External = externalinfra.GetInfraPlatformSpec(installConfig) 231 config.Status.PlatformStatus.External = externalinfra.GetInfraPlatformStatus(installConfig) 232 case none.Name: 233 config.Spec.PlatformSpec.Type = configv1.NonePlatformType 234 case openstack.Name: 235 config.Spec.PlatformSpec.Type = configv1.OpenStackPlatformType 236 config.Spec.PlatformSpec.OpenStack = &configv1.OpenStackPlatformSpec{} 237 config.Status.PlatformStatus.OpenStack = &configv1.OpenStackPlatformStatus{ 238 APIServerInternalIP: installConfig.Config.OpenStack.APIVIPs[0], 239 IngressIP: installConfig.Config.OpenStack.IngressVIPs[0], 240 APIServerInternalIPs: installConfig.Config.OpenStack.APIVIPs, 241 IngressIPs: installConfig.Config.OpenStack.IngressVIPs, 242 LoadBalancer: installConfig.Config.OpenStack.LoadBalancer, 243 } 244 config.Spec.PlatformSpec.OpenStack.APIServerInternalIPs = types.StringsToIPs(installConfig.Config.Platform.OpenStack.APIVIPs) 245 config.Spec.PlatformSpec.OpenStack.IngressIPs = types.StringsToIPs(installConfig.Config.Platform.OpenStack.IngressVIPs) 246 config.Spec.PlatformSpec.OpenStack.MachineNetworks = types.MachineNetworksToCIDRs(installConfig.Config.MachineNetwork) 247 config.Status.PlatformStatus.OpenStack.MachineNetworks = types.MachineNetworksToCIDRs(installConfig.Config.MachineNetwork) 248 case vsphere.Name: 249 config.Spec.PlatformSpec.Type = configv1.VSpherePlatformType 250 config.Spec.PlatformSpec.VSphere = &configv1.VSpherePlatformSpec{} 251 if len(installConfig.Config.VSphere.APIVIPs) > 0 { 252 config.Status.PlatformStatus.VSphere = &configv1.VSpherePlatformStatus{ 253 APIServerInternalIP: installConfig.Config.VSphere.APIVIPs[0], 254 IngressIP: installConfig.Config.VSphere.IngressVIPs[0], 255 APIServerInternalIPs: installConfig.Config.VSphere.APIVIPs, 256 IngressIPs: installConfig.Config.VSphere.IngressVIPs, 257 LoadBalancer: installConfig.Config.VSphere.LoadBalancer, 258 } 259 } else { 260 config.Status.PlatformStatus.VSphere = &configv1.VSpherePlatformStatus{} 261 } 262 263 config.Spec.PlatformSpec.VSphere = vsphereinfra.GetInfraPlatformSpec(installConfig, clusterID.InfraID) 264 if _, exists := cloudproviderconfig.ConfigMap.Data["vsphere.conf"]; exists { 265 cloudProviderConfigMapKey = "vsphere.conf" 266 } 267 268 config.Status.PlatformStatus.VSphere.MachineNetworks = types.MachineNetworksToCIDRs(installConfig.Config.MachineNetwork) 269 case ovirt.Name: 270 config.Spec.PlatformSpec.Type = configv1.OvirtPlatformType 271 config.Status.PlatformStatus.Ovirt = &configv1.OvirtPlatformStatus{ 272 APIServerInternalIP: installConfig.Config.Ovirt.APIVIPs[0], 273 IngressIP: installConfig.Config.Ovirt.IngressVIPs[0], 274 APIServerInternalIPs: installConfig.Config.Ovirt.APIVIPs, 275 IngressIPs: installConfig.Config.Ovirt.IngressVIPs, 276 LoadBalancer: installConfig.Config.Ovirt.LoadBalancer, 277 } 278 case powervs.Name: 279 config.Spec.PlatformSpec.Type = configv1.PowerVSPlatformType 280 config.Spec.PlatformSpec.PowerVS = &configv1.PowerVSPlatformSpec{} 281 var cisInstanceCRN, dnsInstanceCRN string 282 var err error 283 switch installConfig.Config.Publish { 284 case types.InternalPublishingStrategy: 285 dnsInstanceCRN, err = installConfig.PowerVS.DNSInstanceCRN(ctx) 286 if err != nil { 287 return errors.Wrapf(err, "failed to get instance CRN") 288 } 289 case types.ExternalPublishingStrategy: 290 cisInstanceCRN, err = installConfig.PowerVS.CISInstanceCRN(ctx) 291 if err != nil { 292 return errors.Wrapf(err, "failed to get instance CRN") 293 } 294 default: 295 return errors.New("unknown publishing strategy") 296 } 297 for _, service := range installConfig.Config.Platform.PowerVS.ServiceEndpoints { 298 config.Spec.PlatformSpec.PowerVS.ServiceEndpoints = append(config.Spec.PlatformSpec.PowerVS.ServiceEndpoints, configv1.PowerVSServiceEndpoint{ 299 Name: service.Name, 300 URL: service.URL, 301 }) 302 } 303 config.Status.PlatformStatus.PowerVS = &configv1.PowerVSPlatformStatus{ 304 Region: installConfig.Config.Platform.PowerVS.Region, 305 Zone: installConfig.Config.Platform.PowerVS.Zone, 306 ResourceGroup: installConfig.Config.Platform.PowerVS.PowerVSResourceGroup, 307 CISInstanceCRN: cisInstanceCRN, 308 DNSInstanceCRN: dnsInstanceCRN, 309 ServiceEndpoints: installConfig.Config.Platform.PowerVS.ServiceEndpoints, 310 } 311 case nutanix.Name: 312 config.Spec.PlatformSpec.Type = configv1.NutanixPlatformType 313 314 platformSpec, err := nutanixinfra.GetInfrastructureNutanixPlatformSpec(installConfig) 315 if err != nil { 316 return fmt.Errorf("failed to create Infrastructure manifest Nutanix platformSpec: %w", err) 317 } 318 config.Spec.PlatformSpec.Nutanix = platformSpec 319 320 if len(installConfig.Config.Nutanix.APIVIPs) > 0 { 321 config.Status.PlatformStatus.Nutanix = &configv1.NutanixPlatformStatus{ 322 APIServerInternalIP: installConfig.Config.Nutanix.APIVIPs[0], 323 IngressIP: installConfig.Config.Nutanix.IngressVIPs[0], 324 APIServerInternalIPs: installConfig.Config.Nutanix.APIVIPs, 325 IngressIPs: installConfig.Config.Nutanix.IngressVIPs, 326 LoadBalancer: installConfig.Config.Nutanix.LoadBalancer, 327 } 328 } 329 default: 330 config.Spec.PlatformSpec.Type = configv1.NonePlatformType 331 } 332 config.Status.Platform = config.Spec.PlatformSpec.Type 333 config.Status.PlatformStatus.Type = config.Spec.PlatformSpec.Type 334 335 if cloudproviderconfig.ConfigMap != nil { 336 // set the configmap reference. 337 config.Spec.CloudConfig = configv1.ConfigMapFileReference{Name: cloudproviderconfig.ConfigMap.Name, Key: cloudProviderConfigMapKey} 338 i.FileList = append(i.FileList, cloudproviderconfig.File) 339 } 340 341 if trustbundleconfig.ConfigMap != nil { 342 i.FileList = append(i.FileList, trustbundleconfig.Files()...) 343 } 344 345 configData, err := yaml.Marshal(config) 346 if err != nil { 347 return errors.Wrapf(err, "failed to marshal config: %#v", config) 348 } 349 i.FileList = append(i.FileList, &asset.File{ 350 Filename: infraCfgFilename, 351 Data: configData, 352 }) 353 return nil 354 } 355 356 // Files returns the files generated by the asset. 357 func (i *Infrastructure) Files() []*asset.File { 358 return i.FileList 359 } 360 361 // Load returns false since this asset is not written to disk by the installer. 362 func (i *Infrastructure) Load(f asset.FileFetcher) (bool, error) { 363 return false, nil 364 }