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  }