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 }