github.com/openshift/installer@v1.4.17/pkg/asset/imagebased/configimage/installconfig.go (about) 1 package configimage 2 3 import ( 4 "context" 5 "fmt" 6 7 "github.com/sirupsen/logrus" 8 "k8s.io/apimachinery/pkg/util/validation/field" 9 10 configv1 "github.com/openshift/api/config/v1" 11 "github.com/openshift/installer/pkg/asset" 12 "github.com/openshift/installer/pkg/asset/installconfig" 13 "github.com/openshift/installer/pkg/types" 14 "github.com/openshift/installer/pkg/types/none" 15 "github.com/openshift/installer/pkg/types/validation" 16 ) 17 18 const ( 19 // InstallConfigFilename is the file containing the install-config. 20 InstallConfigFilename = "install-config.yaml" 21 ) 22 23 // InstallConfig is an InstallConfig where the default is empty, rather 24 // than generated from running the survey. 25 type InstallConfig struct { 26 installconfig.AssetBase 27 } 28 29 var _ asset.WritableAsset = (*InstallConfig)(nil) 30 31 // Dependencies returns all of the dependencies directly needed by an 32 // InstallConfig asset. 33 func (i *InstallConfig) Dependencies() []asset.Asset { 34 // Return no dependencies for the Image-based install config, because it is 35 // optional. We don't need to run the survey if it doesn't exist, since it 36 // does not support the `none` platform. 37 return []asset.Asset{} 38 } 39 40 // Generate generates the install-config.yaml file. 41 func (i *InstallConfig) Generate(_ context.Context, parents asset.Parents) error { 42 // Just generate an empty install config, since we have no dependencies. 43 return nil 44 } 45 46 // Load returns the installconfig from disk. 47 func (i *InstallConfig) Load(f asset.FileFetcher) (bool, error) { 48 found, err := i.LoadFromFile(f) 49 if found && err == nil { 50 if err := i.validateInstallConfig(i.Config).ToAggregate(); err != nil { 51 return false, fmt.Errorf("invalid install-config configuration: %w", err) 52 } 53 if err := i.RecordFile(); err != nil { 54 return false, err 55 } 56 } 57 return found, err 58 } 59 60 func (i *InstallConfig) validateInstallConfig(installConfig *types.InstallConfig) field.ErrorList { 61 var allErrs field.ErrorList 62 if err := validation.ValidateInstallConfig(i.Config, true); err != nil { 63 allErrs = append(allErrs, err...) 64 } 65 66 if err := i.validateSupportedPlatforms(installConfig); err != nil { 67 allErrs = append(allErrs, err...) 68 } 69 70 if installConfig.FeatureSet != configv1.Default { 71 allErrs = append(allErrs, field.NotSupported(field.NewPath("FeatureSet"), installConfig.FeatureSet, []string{string(configv1.Default)})) 72 } 73 74 warnUnusedConfig(installConfig) 75 76 if err := i.validateSNOConfiguration(installConfig); err != nil { 77 allErrs = append(allErrs, err...) 78 } 79 80 return allErrs 81 } 82 83 func (i *InstallConfig) validateSupportedPlatforms(installConfig *types.InstallConfig) field.ErrorList { 84 var allErrs field.ErrorList 85 86 fieldPath := field.NewPath("Platform") 87 88 if installConfig.Platform.Name() != "" && installConfig.Platform.Name() != none.Name { 89 allErrs = append(allErrs, field.NotSupported(fieldPath, installConfig.Platform.Name(), []string{none.Name})) 90 } 91 92 return allErrs 93 } 94 95 func (i *InstallConfig) validateSNOConfiguration(installConfig *types.InstallConfig) field.ErrorList { 96 var allErrs field.ErrorList 97 var fieldPath *field.Path 98 99 controlPlaneReplicas := *installConfig.ControlPlane.Replicas 100 if installConfig.ControlPlane != nil && controlPlaneReplicas != 1 { 101 fieldPath = field.NewPath("ControlPlane", "Replicas") 102 allErrs = append(allErrs, field.Required(fieldPath, fmt.Sprintf("Only Single Node OpenShift (SNO) is supported, total number of ControlPlane.Replicas must be 1. Found %v", controlPlaneReplicas))) 103 } 104 105 var workers int 106 for _, worker := range installConfig.Compute { 107 workers += int(*worker.Replicas) 108 } 109 if workers != 0 { 110 fieldPath = field.NewPath("Compute", "Replicas") 111 allErrs = append(allErrs, field.Required(fieldPath, fmt.Sprintf("Total number of Compute.Replicas must be 0 when ControlPlane.Replicas is 1 for platform %s. Found %v", none.Name, workers))) 112 } 113 114 if installConfig.Networking.NetworkType != "OVNKubernetes" { 115 fieldPath = field.NewPath("Networking", "NetworkType") 116 allErrs = append(allErrs, field.Invalid(fieldPath, installConfig.Networking.NetworkType, "Only OVNKubernetes network type is allowed for Single Node OpenShift (SNO) cluster")) 117 } 118 119 machineNetworksCount := len(installConfig.Networking.MachineNetwork) 120 if machineNetworksCount != 1 { 121 fieldPath = field.NewPath("Networking", "MachineNetwork") 122 allErrs = append(allErrs, field.TooMany(fieldPath, machineNetworksCount, 1)) 123 } 124 125 return allErrs 126 } 127 128 // ClusterName returns the name of the cluster, or a default name if no 129 // InstallConfig is supplied. 130 func (i *InstallConfig) ClusterName() string { 131 if i.Config != nil && i.Config.ObjectMeta.Name != "" { 132 return i.Config.ObjectMeta.Name 133 } 134 return "imagebased-sno-cluster" 135 } 136 137 // ClusterNamespace returns the namespace of the cluster. 138 func (i *InstallConfig) ClusterNamespace() string { 139 if i.Config != nil && i.Config.ObjectMeta.Namespace != "" { 140 return i.Config.ObjectMeta.Namespace 141 } 142 return "" 143 } 144 145 func warnUnusedConfig(installConfig *types.InstallConfig) { 146 // "Proxyonly" is the default set from generic install config code 147 if installConfig.AdditionalTrustBundlePolicy != "Proxyonly" { 148 fieldPath := field.NewPath("AdditionalTrustBundlePolicy") 149 logrus.Warnf(fmt.Sprintf("%s: %s is ignored", fieldPath, installConfig.AdditionalTrustBundlePolicy)) 150 } 151 152 for i, compute := range installConfig.Compute { 153 if compute.Hyperthreading != "Enabled" { 154 fieldPath := field.NewPath(fmt.Sprintf("Compute[%d]", i), "Hyperthreading") 155 logrus.Warnf(fmt.Sprintf("%s: %s is ignored", fieldPath, compute.Hyperthreading)) 156 } 157 158 if compute.Platform != (types.MachinePoolPlatform{}) { 159 fieldPath := field.NewPath(fmt.Sprintf("Compute[%d]", i), "Platform") 160 logrus.Warnf(fmt.Sprintf("%s is ignored", fieldPath)) 161 } 162 } 163 164 if installConfig.ControlPlane.Hyperthreading != "Enabled" { 165 fieldPath := field.NewPath("ControlPlane", "Hyperthreading") 166 logrus.Warnf(fmt.Sprintf("%s: %s is ignored", fieldPath, installConfig.ControlPlane.Hyperthreading)) 167 } 168 169 if installConfig.ControlPlane.Platform != (types.MachinePoolPlatform{}) { 170 fieldPath := field.NewPath("ControlPlane", "Platform") 171 logrus.Warnf(fmt.Sprintf("%s is ignored", fieldPath)) 172 } 173 }