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

     1  // Package manifests deals with creating manifests for all manifests to be installed for the cluster
     2  package manifests
     3  
     4  import (
     5  	"bytes"
     6  	"context"
     7  	"encoding/base64"
     8  	"path/filepath"
     9  	"strings"
    10  	"text/template"
    11  
    12  	"github.com/pkg/errors"
    13  	"sigs.k8s.io/yaml"
    14  
    15  	"github.com/openshift/installer/pkg/asset"
    16  	"github.com/openshift/installer/pkg/asset/installconfig"
    17  	"github.com/openshift/installer/pkg/asset/templates/content/bootkube"
    18  	"github.com/openshift/installer/pkg/asset/tls"
    19  	"github.com/openshift/installer/pkg/types"
    20  	"github.com/openshift/installer/pkg/types/vsphere"
    21  )
    22  
    23  const (
    24  	manifestDir = "manifests"
    25  )
    26  
    27  var (
    28  	kubeSysConfigPath = filepath.Join(manifestDir, "cluster-config.yaml")
    29  
    30  	_ asset.WritableAsset = (*Manifests)(nil)
    31  
    32  	customTmplFuncs = template.FuncMap{
    33  		"indent": indent,
    34  		"add": func(i, j int) int {
    35  			return i + j
    36  		},
    37  	}
    38  )
    39  
    40  // Manifests generates the dependent operator config.yaml files
    41  type Manifests struct {
    42  	KubeSysConfig *configurationObject
    43  	FileList      []*asset.File
    44  }
    45  
    46  type genericData map[string]string
    47  
    48  // Name returns a human friendly name for the operator
    49  func (m *Manifests) Name() string {
    50  	return "Common Manifests"
    51  }
    52  
    53  // Dependencies returns all of the dependencies directly needed by a
    54  // Manifests asset.
    55  func (m *Manifests) Dependencies() []asset.Asset {
    56  	return []asset.Asset{
    57  		&installconfig.ClusterID{},
    58  		&installconfig.InstallConfig{},
    59  		&Ingress{},
    60  		&DNS{},
    61  		&Infrastructure{},
    62  		&Networking{},
    63  		&Proxy{},
    64  		&Scheduler{},
    65  		&ImageContentSourcePolicy{},
    66  		&ClusterCSIDriverConfig{},
    67  		&ImageDigestMirrorSet{},
    68  		&tls.RootCA{},
    69  		&tls.MCSCertKey{},
    70  
    71  		&bootkube.CVOOverrides{},
    72  		&bootkube.KubeCloudConfig{},
    73  		&bootkube.KubeSystemConfigmapRootCA{},
    74  		&bootkube.MachineConfigServerTLSSecret{},
    75  		&bootkube.OpenshiftConfigSecretPullSecret{},
    76  	}
    77  }
    78  
    79  // Generate generates the respective operator config.yml files
    80  func (m *Manifests) Generate(_ context.Context, dependencies asset.Parents) error {
    81  	ingress := &Ingress{}
    82  	dns := &DNS{}
    83  	network := &Networking{}
    84  	infra := &Infrastructure{}
    85  	installConfig := &installconfig.InstallConfig{}
    86  	proxy := &Proxy{}
    87  	scheduler := &Scheduler{}
    88  	imageContentSourcePolicy := &ImageContentSourcePolicy{}
    89  	clusterCSIDriverConfig := &ClusterCSIDriverConfig{}
    90  	imageDigestMirrorSet := &ImageDigestMirrorSet{}
    91  
    92  	dependencies.Get(installConfig, ingress, dns, network, infra, proxy, scheduler, imageContentSourcePolicy, imageDigestMirrorSet, clusterCSIDriverConfig)
    93  
    94  	redactedConfig, err := redactedInstallConfig(*installConfig.Config)
    95  	if err != nil {
    96  		return errors.Wrap(err, "failed to redact install-config")
    97  	}
    98  	// mao go to kube-system config map
    99  	m.KubeSysConfig = configMap("kube-system", "cluster-config-v1", genericData{
   100  		"install-config": string(redactedConfig),
   101  	})
   102  	if m.KubeSysConfig.Metadata.Annotations == nil {
   103  		m.KubeSysConfig.Metadata.Annotations = make(map[string]string, 1)
   104  	}
   105  	m.KubeSysConfig.Metadata.Annotations["kubernetes.io/description"] = "The install-config content used to create the cluster.  The cluster configuration may have evolved since installation, so check cluster configuration resources directly if you are interested in the current cluster state."
   106  
   107  	kubeSysConfigData, err := yaml.Marshal(m.KubeSysConfig)
   108  	if err != nil {
   109  		return errors.Wrap(err, "failed to create kube-system/cluster-config-v1 configmap")
   110  	}
   111  
   112  	m.FileList = []*asset.File{
   113  		{
   114  			Filename: kubeSysConfigPath,
   115  			Data:     kubeSysConfigData,
   116  		},
   117  	}
   118  	m.FileList = append(m.FileList, m.generateBootKubeManifests(dependencies)...)
   119  
   120  	m.FileList = append(m.FileList, ingress.Files()...)
   121  	m.FileList = append(m.FileList, dns.Files()...)
   122  	m.FileList = append(m.FileList, network.Files()...)
   123  	m.FileList = append(m.FileList, infra.Files()...)
   124  	m.FileList = append(m.FileList, proxy.Files()...)
   125  	m.FileList = append(m.FileList, scheduler.Files()...)
   126  	m.FileList = append(m.FileList, imageContentSourcePolicy.Files()...)
   127  	m.FileList = append(m.FileList, clusterCSIDriverConfig.Files()...)
   128  	m.FileList = append(m.FileList, imageDigestMirrorSet.Files()...)
   129  
   130  	asset.SortFiles(m.FileList)
   131  
   132  	return nil
   133  }
   134  
   135  // Files returns the files generated by the asset.
   136  func (m *Manifests) Files() []*asset.File {
   137  	return m.FileList
   138  }
   139  
   140  func (m *Manifests) generateBootKubeManifests(dependencies asset.Parents) []*asset.File {
   141  	clusterID := &installconfig.ClusterID{}
   142  	installConfig := &installconfig.InstallConfig{}
   143  	mcsCertKey := &tls.MCSCertKey{}
   144  	rootCA := &tls.RootCA{}
   145  	dependencies.Get(
   146  		clusterID,
   147  		installConfig,
   148  		mcsCertKey,
   149  		rootCA,
   150  	)
   151  
   152  	templateData := &bootkubeTemplateData{
   153  		CVOCapabilities:  installConfig.Config.Capabilities,
   154  		CVOClusterID:     clusterID.UUID,
   155  		McsTLSCert:       base64.StdEncoding.EncodeToString(mcsCertKey.Cert()),
   156  		McsTLSKey:        base64.StdEncoding.EncodeToString(mcsCertKey.Key()),
   157  		PullSecretBase64: base64.StdEncoding.EncodeToString([]byte(installConfig.Config.PullSecret)),
   158  		RootCaCert:       string(rootCA.Cert()),
   159  		IsFCOS:           installConfig.Config.IsFCOS(),
   160  		IsSCOS:           installConfig.Config.IsSCOS(),
   161  		IsOKD:            installConfig.Config.IsOKD(),
   162  	}
   163  
   164  	files := []*asset.File{}
   165  	for _, a := range []asset.WritableAsset{
   166  		&bootkube.CVOOverrides{},
   167  		&bootkube.KubeCloudConfig{},
   168  		&bootkube.KubeSystemConfigmapRootCA{},
   169  		&bootkube.MachineConfigServerTLSSecret{},
   170  		&bootkube.OpenshiftConfigSecretPullSecret{},
   171  	} {
   172  		dependencies.Get(a)
   173  		for _, f := range a.Files() {
   174  			files = append(files, &asset.File{
   175  				Filename: filepath.Join(manifestDir, strings.TrimSuffix(filepath.Base(f.Filename), ".template")),
   176  				Data:     applyTemplateData(f.Data, templateData),
   177  			})
   178  		}
   179  	}
   180  	return files
   181  }
   182  
   183  func applyTemplateData(data []byte, templateData interface{}) []byte {
   184  	template := template.Must(template.New("template").Funcs(customTmplFuncs).Parse(string(data)))
   185  	buf := &bytes.Buffer{}
   186  	if err := template.Execute(buf, templateData); err != nil {
   187  		panic(err)
   188  	}
   189  	return buf.Bytes()
   190  }
   191  
   192  // Load returns the manifests asset from disk.
   193  func (m *Manifests) Load(f asset.FileFetcher) (bool, error) {
   194  	yamlFileList, err := f.FetchByPattern(filepath.Join(manifestDir, "*.yaml"))
   195  	if err != nil {
   196  		return false, errors.Wrap(err, "failed to load *.yaml files")
   197  	}
   198  	ymlFileList, err := f.FetchByPattern(filepath.Join(manifestDir, "*.yml"))
   199  	if err != nil {
   200  		return false, errors.Wrap(err, "failed to load *.yml files")
   201  	}
   202  	jsonFileList, err := f.FetchByPattern(filepath.Join(manifestDir, "*.json"))
   203  	if err != nil {
   204  		return false, errors.Wrap(err, "failed to load *.json files")
   205  	}
   206  	fileList := append(yamlFileList, ymlFileList...)
   207  	fileList = append(fileList, jsonFileList...)
   208  
   209  	if len(fileList) == 0 {
   210  		return false, nil
   211  	}
   212  
   213  	kubeSysConfig := &configurationObject{}
   214  	var found bool
   215  	for _, file := range fileList {
   216  		if file.Filename == kubeSysConfigPath {
   217  			if err := yaml.Unmarshal(file.Data, kubeSysConfig); err != nil {
   218  				return false, errors.Wrapf(err, "failed to unmarshal %s", kubeSysConfigPath)
   219  			}
   220  			found = true
   221  		}
   222  	}
   223  
   224  	if !found {
   225  		return false, nil
   226  
   227  	}
   228  
   229  	m.FileList, m.KubeSysConfig = fileList, kubeSysConfig
   230  
   231  	asset.SortFiles(m.FileList)
   232  
   233  	return true, nil
   234  }
   235  
   236  func redactedInstallConfig(config types.InstallConfig) ([]byte, error) {
   237  	newConfig := config
   238  
   239  	newConfig.PullSecret = ""
   240  	if newConfig.Platform.VSphere != nil {
   241  		p := config.VSphere
   242  		newVCenters := make([]vsphere.VCenter, len(p.VCenters))
   243  		for i, v := range p.VCenters {
   244  			newVCenters[i].Server = v.Server
   245  			newVCenters[i].Datacenters = v.Datacenters
   246  		}
   247  		newVSpherePlatform := vsphere.Platform{
   248  			DeprecatedVCenter:          p.DeprecatedVCenter,
   249  			DeprecatedUsername:         "",
   250  			DeprecatedPassword:         "",
   251  			DeprecatedDatacenter:       p.DeprecatedDatacenter,
   252  			DeprecatedDefaultDatastore: p.DeprecatedDefaultDatastore,
   253  			DeprecatedFolder:           p.DeprecatedFolder,
   254  			DeprecatedCluster:          p.DeprecatedCluster,
   255  			DeprecatedResourcePool:     p.DeprecatedResourcePool,
   256  			ClusterOSImage:             p.ClusterOSImage,
   257  			DeprecatedAPIVIP:           p.DeprecatedAPIVIP,
   258  			APIVIPs:                    p.APIVIPs,
   259  			DeprecatedIngressVIP:       p.DeprecatedIngressVIP,
   260  			IngressVIPs:                p.IngressVIPs,
   261  			DefaultMachinePlatform:     p.DefaultMachinePlatform,
   262  			DeprecatedNetwork:          p.DeprecatedNetwork,
   263  			DiskType:                   p.DiskType,
   264  			VCenters:                   newVCenters,
   265  			FailureDomains:             p.FailureDomains,
   266  		}
   267  		newConfig.Platform.VSphere = &newVSpherePlatform
   268  	}
   269  
   270  	return yaml.Marshal(newConfig)
   271  }
   272  
   273  func indent(indention int, v string) string {
   274  	newline := "\n" + strings.Repeat(" ", indention)
   275  	return strings.Replace(v, "\n", newline, -1)
   276  }