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  }