github.com/openshift/installer@v1.4.17/pkg/asset/manifests/network.go (about) 1 package manifests 2 3 import ( 4 "context" 5 "fmt" 6 "path/filepath" 7 8 "github.com/pkg/errors" 9 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 10 "sigs.k8s.io/yaml" 11 12 configv1 "github.com/openshift/api/config/v1" 13 operatorv1 "github.com/openshift/api/operator/v1" 14 "github.com/openshift/installer/pkg/asset" 15 "github.com/openshift/installer/pkg/asset/installconfig" 16 "github.com/openshift/installer/pkg/types" 17 "github.com/openshift/installer/pkg/types/aws" 18 "github.com/openshift/installer/pkg/types/powervs" 19 ) 20 21 var ( 22 noCfgFilename = filepath.Join(manifestDir, "cluster-network-02-config.yml") 23 cnoCfgFilename = filepath.Join(manifestDir, "cluster-network-03-config.yml") 24 // Cluster Network MTU for AWS Local Zone deployments on edge machine pools. 25 ovnKubernetesNetworkMtuEdge uint32 = 1200 26 ) 27 28 // Networking generates the cluster-network-*.yml files. 29 type Networking struct { 30 Config *configv1.Network 31 FileList []*asset.File 32 } 33 34 var _ asset.WritableAsset = (*Networking)(nil) 35 36 // Name returns a human friendly name for the operator. 37 func (no *Networking) Name() string { 38 return "Network Config" 39 } 40 41 // Dependencies returns all of the dependencies directly needed to generate 42 // network configuration. 43 func (no *Networking) Dependencies() []asset.Asset { 44 return []asset.Asset{ 45 &installconfig.InstallConfig{}, 46 } 47 } 48 49 // Generate generates the network operator config. 50 func (no *Networking) Generate(_ context.Context, dependencies asset.Parents) error { 51 installConfig := &installconfig.InstallConfig{} 52 dependencies.Get(installConfig) 53 54 netConfig := installConfig.Config.Networking 55 56 clusterNet := []configv1.ClusterNetworkEntry{} 57 if len(netConfig.ClusterNetwork) > 0 { 58 for _, net := range netConfig.ClusterNetwork { 59 clusterNet = append(clusterNet, configv1.ClusterNetworkEntry{ 60 CIDR: net.CIDR.String(), 61 HostPrefix: uint32(net.HostPrefix), 62 }) 63 } 64 } else { 65 return errors.Errorf("ClusterNetworks must be specified") 66 } 67 68 serviceNet := []string{} 69 for _, sn := range netConfig.ServiceNetwork { 70 serviceNet = append(serviceNet, sn.String()) 71 } 72 73 no.Config = &configv1.Network{ 74 TypeMeta: metav1.TypeMeta{ 75 APIVersion: configv1.SchemeGroupVersion.String(), 76 Kind: "Network", 77 }, 78 ObjectMeta: metav1.ObjectMeta{ 79 Name: "cluster", 80 // not namespaced 81 }, 82 Spec: configv1.NetworkSpec{ 83 ClusterNetwork: clusterNet, 84 ServiceNetwork: serviceNet, 85 NetworkType: netConfig.NetworkType, 86 // Block all Service.ExternalIPs by default 87 ExternalIP: &configv1.ExternalIPConfig{ 88 Policy: &configv1.ExternalIPPolicy{}, 89 }, 90 }, 91 } 92 93 configData, err := yaml.Marshal(no.Config) 94 if err != nil { 95 return errors.Wrapf(err, "failed to create %s manifests from InstallConfig", no.Name()) 96 } 97 98 no.FileList = []*asset.File{ 99 { 100 Filename: noCfgFilename, 101 Data: configData, 102 }, 103 } 104 105 switch installConfig.Config.Platform.Name() { 106 case aws.Name: 107 defaultNetworkConfig, err := no.GenerateCustomNetworkConfigMTU(installConfig) 108 if err != nil { 109 return err 110 } 111 if defaultNetworkConfig != nil { 112 cnoConfig, err := no.generateCustomCnoConfig(defaultNetworkConfig) 113 if err != nil { 114 return fmt.Errorf("cannot generate DefaultNetworkConfig for %s: %w", netConfig.NetworkType, err) 115 } 116 no.FileList = append(no.FileList, &asset.File{ 117 Filename: cnoCfgFilename, 118 Data: cnoConfig, 119 }) 120 } 121 122 case powervs.Name: 123 if netConfig.NetworkType == "OVNKubernetes" { 124 ovnConfig, err := OvnKubeConfig(clusterNet, serviceNet, true) 125 if err != nil { 126 return errors.Wrapf(err, "cannot marshal Power VS OVNKube Config") 127 } 128 no.FileList = append(no.FileList, &asset.File{ 129 Filename: cnoCfgFilename, 130 Data: ovnConfig, 131 }) 132 } 133 } 134 135 return nil 136 } 137 138 // Files returns the files generated by the asset. 139 func (no *Networking) Files() []*asset.File { 140 return no.FileList 141 } 142 143 // Load returns false since this asset is not written to disk by the installer. 144 func (no *Networking) Load(f asset.FileFetcher) (bool, error) { 145 return false, nil 146 } 147 148 // generateCustomCnoConfig generates the defaultNetwork for Cluster Network Operator 149 // configuration, and returns the byte data with Cluster Network Operator manifest. 150 func (no *Networking) generateCustomCnoConfig(defaultNetwork *operatorv1.DefaultNetworkDefinition) ([]byte, error) { 151 if defaultNetwork == nil { 152 return nil, errors.New("defaultNetwork must be specified") 153 } 154 dnConfig := operatorv1.Network{ 155 TypeMeta: metav1.TypeMeta{ 156 APIVersion: operatorv1.SchemeGroupVersion.String(), 157 Kind: "Network", 158 }, 159 ObjectMeta: metav1.ObjectMeta{ 160 Name: "cluster", 161 }, 162 Spec: operatorv1.NetworkSpec{ 163 OperatorSpec: operatorv1.OperatorSpec{ManagementState: operatorv1.Managed}, 164 DefaultNetwork: *defaultNetwork, 165 }, 166 } 167 168 return yaml.Marshal(dnConfig) 169 } 170 171 // GenerateCustomNetworkConfigMTU generates and return the DefaultNetwork configuration, when there are 172 // customizations in the install-config.yaml. 173 func (no *Networking) GenerateCustomNetworkConfigMTU(ic *installconfig.InstallConfig) (*operatorv1.DefaultNetworkDefinition, error) { 174 if ic.Config == nil { 175 return nil, nil 176 } 177 if ic.Config.Networking == nil { 178 return nil, nil 179 } 180 181 var defNetCfg *operatorv1.DefaultNetworkDefinition 182 mtu := uint32(0) 183 hasCustomMTU := false 184 hasEdgePool := false 185 netConfig := ic.Config.Networking 186 187 if ic.Config.Platform.Name() == aws.Name { 188 for _, mp := range ic.Config.Compute { 189 // Check if there is an edge compute pool in install config, and generate the 190 // CNO object to set DefaultNetwork for CNI with custom MTU. 191 // EC2 Instances running on AWS Local and Wavelength zones generally 192 // requires (newer zones are supporting higger) MTU set to 1300 to 193 // communicate with regular zones in the Region. 194 // The number of MTU must be decreased from the network plugin overhead. 195 // https://docs.aws.amazon.com/local-zones/latest/ug/how-local-zones-work.html 196 if mp.Name == types.MachinePoolEdgeRoleName { 197 hasCustomMTU = true 198 hasEdgePool = true 199 } 200 } 201 if ic.Config.Networking != nil && ic.Config.Networking.ClusterNetworkMTU > 0 { 202 hasCustomMTU = true 203 mtu = ic.Config.Networking.ClusterNetworkMTU 204 } 205 } 206 207 if !hasCustomMTU { 208 return nil, nil 209 } 210 211 if netConfig.NetworkType == string(operatorv1.NetworkTypeOVNKubernetes) { 212 // User-defined Cluster MTU has precedence over standard edge zone for each plugin. 213 if hasEdgePool && mtu == 0 { 214 mtu = ovnKubernetesNetworkMtuEdge 215 } 216 defNetCfg = &operatorv1.DefaultNetworkDefinition{ 217 Type: operatorv1.NetworkTypeOVNKubernetes, 218 OVNKubernetesConfig: &operatorv1.OVNKubernetesConfig{ 219 MTU: &mtu, 220 }, 221 } 222 } 223 224 return defNetCfg, nil 225 }