github.com/openshift/installer@v1.4.17/pkg/asset/lbconfig/lbconfig.go (about)

     1  package lbconfig
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  	"net"
     7  	"os"
     8  	"path/filepath"
     9  
    10  	corev1 "k8s.io/api/core/v1"
    11  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    12  	"sigs.k8s.io/yaml"
    13  
    14  	"github.com/openshift/installer/pkg/asset"
    15  )
    16  
    17  // LoadBalancerCategory describes the type of load balancer data.
    18  type LoadBalancerCategory string
    19  
    20  var (
    21  	// ConfigName is the name of the load balancer config file.
    22  	ConfigName = "openshift-lb-config.yaml"
    23  
    24  	// ConfigPath is the path to the load balancer config file.
    25  	ConfigPath = filepath.Join("openshift", ConfigName)
    26  
    27  	// PublicLoadBalancer indicates that the data is related to public load balancers.
    28  	PublicLoadBalancer LoadBalancerCategory = "external-api-lb-ips"
    29  
    30  	// PrivateLoadBalancer indicates that the data is related to private load balancers.
    31  	PrivateLoadBalancer LoadBalancerCategory = "internal-api-lb-ips"
    32  )
    33  
    34  // Config generates the lbConfigForDNS ConfigMap.
    35  type Config struct {
    36  	File *asset.File
    37  }
    38  
    39  var _ asset.WritableAsset = (*Config)(nil)
    40  
    41  // Name returns a human friendly name for the asset.
    42  func (*Config) Name() string {
    43  	return "OpenShift Load Balancer Config"
    44  }
    45  
    46  // Dependencies returns all the dependencies directly needed to generate
    47  // the asset.
    48  func (*Config) Dependencies() []asset.Asset {
    49  	return []asset.Asset{}
    50  }
    51  
    52  // Generate generates the openshift-install ConfigMap.
    53  func (i *Config) Generate(_ context.Context, dependencies asset.Parents) error {
    54  	cm, err := CreateLBConfigMap("openshift-lb-config", "", "")
    55  	if err != nil {
    56  		return err
    57  	}
    58  
    59  	i.File = &asset.File{
    60  		Filename: ConfigPath,
    61  		Data:     []byte(cm),
    62  	}
    63  
    64  	return nil
    65  }
    66  
    67  // GenerateLBConfigOverride generates an LBConfig an overrides the file data.
    68  func GenerateLBConfigOverride(lbIntDNS, lbDNS string) (*Config, error) {
    69  	config := &Config{}
    70  	if err := config.Generate(context.TODO(), asset.Parents{}); err != nil {
    71  		return nil, err
    72  	}
    73  
    74  	output, err := CreateLBConfigMap("openshift-lb-config", lbIntDNS, lbDNS)
    75  	if err != nil {
    76  		return nil, fmt.Errorf("failed to override the lb config: %w", err)
    77  	}
    78  	config.File.Data = []byte(output)
    79  	return config, nil
    80  }
    81  
    82  // Files returns the files generated by the asset.
    83  func (i *Config) Files() []*asset.File {
    84  	if i.File != nil {
    85  		return []*asset.File{i.File}
    86  	}
    87  	return []*asset.File{}
    88  }
    89  
    90  // Load loads the already-rendered files back from disk.
    91  func (i *Config) Load(f asset.FileFetcher) (bool, error) {
    92  	file, err := f.FetchByName(ConfigPath)
    93  	if os.IsNotExist(err) {
    94  		return false, nil
    95  	} else if err != nil {
    96  		return false, err
    97  	}
    98  	i.File = file
    99  	return true, nil
   100  }
   101  
   102  // CreateLBConfigMap creates a ConfigMap containing API and APi-Int
   103  // LB configuration. Returns an error if marshalling to YAML fails.
   104  func CreateLBConfigMap(name, lbIntDNS, lbDNS string) (string, error) {
   105  	if lbIntDNS == "" && lbDNS == "" {
   106  		return "", nil
   107  	}
   108  
   109  	cm := &corev1.ConfigMap{
   110  		TypeMeta: metav1.TypeMeta{
   111  			APIVersion: corev1.SchemeGroupVersion.String(),
   112  			Kind:       "ConfigMap",
   113  		},
   114  		ObjectMeta: metav1.ObjectMeta{
   115  			Namespace: "openshift-infra",
   116  			Name:      name,
   117  		},
   118  		Data: map[string]string{
   119  			string(PrivateLoadBalancer): lbIntDNS,
   120  			string(PublicLoadBalancer):  lbDNS,
   121  		},
   122  	}
   123  
   124  	cmData, err := yaml.Marshal(cm)
   125  	if err != nil {
   126  		return "", fmt.Errorf("failed to create %q ConfigMap: %w", name, err)
   127  	}
   128  
   129  	return string(cmData), nil
   130  }
   131  
   132  // ParseDNSDataFromConfig parses the ip addresses and DNS names from the config map.
   133  func (i *Config) ParseDNSDataFromConfig(loadBalancerType LoadBalancerCategory) ([]string, []net.IP, error) {
   134  	ipAddresses := []net.IP{}
   135  	dnsNames := []string{}
   136  
   137  	// Load Data from LBConfig
   138  	lbData := make(map[string]interface{})
   139  	if err := yaml.Unmarshal(i.File.Data, &lbData); err != nil {
   140  		return dnsNames, ipAddresses, err
   141  	}
   142  
   143  	if internalData, ok := lbData["data"]; ok {
   144  		if lbStoredData, ok := internalData.(map[string]interface{})[string(loadBalancerType)]; ok {
   145  			// TODO: make this parse a comma separated string
   146  			parsedIP := net.ParseIP(lbStoredData.(string))
   147  			if parsedIP != nil {
   148  				ipAddresses = append(ipAddresses, parsedIP)
   149  			} else {
   150  				// assume the data is a dns entry
   151  				dnsNames = append(dnsNames, lbStoredData.(string))
   152  			}
   153  		}
   154  	}
   155  
   156  	return dnsNames, ipAddresses, nil
   157  }