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  }