github.com/openshift/installer@v1.4.17/pkg/asset/ignition/bootstrap/cvoignore.go (about) 1 package bootstrap 2 3 import ( 4 "context" 5 "encoding/json" 6 "fmt" 7 8 "github.com/pkg/errors" 9 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" 10 "sigs.k8s.io/yaml" 11 12 configv1 "github.com/openshift/api/config/v1" 13 "github.com/openshift/installer/pkg/asset" 14 "github.com/openshift/installer/pkg/asset/manifests" 15 ) 16 17 var ( 18 _ asset.WritableAsset = (*CVOIgnore)(nil) 19 ) 20 21 const ( 22 cvoOverridesFilename = "manifests/cvo-overrides.yaml" 23 originalOverridesFilename = "original_cvo_overrides.patch" 24 ) 25 26 // CVOIgnore adds bootstrap files needed to inform CVO to ignore resources for which the installer is providing manifests. 27 type CVOIgnore struct { 28 FileList []*asset.File 29 } 30 31 // Name returns a human friendly name for the operator 32 func (a *CVOIgnore) Name() string { 33 return "CVO Ignore" 34 } 35 36 // Dependencies returns all of the dependencies directly needed by the CVOIgnore asset 37 func (a *CVOIgnore) Dependencies() []asset.Asset { 38 return []asset.Asset{ 39 &manifests.Manifests{}, 40 &manifests.Openshift{}, 41 } 42 } 43 44 // Generate generates the respective operator config.yml files 45 func (a *CVOIgnore) Generate(_ context.Context, dependencies asset.Parents) error { 46 operators := &manifests.Manifests{} 47 openshiftManifests := &manifests.Openshift{} 48 dependencies.Get(operators, openshiftManifests) 49 50 var clusterVersion *unstructured.Unstructured 51 var ignoredResources []interface{} 52 var files []*asset.File 53 files = append(files, operators.FileList...) 54 files = append(files, openshiftManifests.FileList...) 55 56 seen := make(map[string]string, len(files)) 57 for _, file := range files { 58 u := &unstructured.Unstructured{} 59 if err := yaml.Unmarshal(file.Data, u); err != nil { 60 return errors.Wrapf(err, "could not unmarshal %q", file.Filename) 61 } 62 group := u.GetObjectKind().GroupVersionKind().Group 63 kind := u.GetKind() 64 namespace := u.GetNamespace() 65 name := u.GetName() 66 67 key := fmt.Sprintf("%s |! %s |! %s |! %s", group, kind, namespace, name) 68 if previousFile, ok := seen[key]; ok { 69 return fmt.Errorf("multiple manifests for group %s kind %s namespace %s name %s: %s, %s", group, kind, namespace, name, previousFile, file.Filename) 70 } 71 seen[key] = file.Filename 72 73 if file.Filename == cvoOverridesFilename { 74 clusterVersion = u 75 continue 76 } 77 ignoredResources = append(ignoredResources, 78 configv1.ComponentOverride{ 79 Kind: kind, 80 Group: group, 81 Namespace: namespace, 82 Name: name, 83 Unmanaged: true, 84 }) 85 } 86 87 specAsInterface, ok := clusterVersion.Object["spec"] 88 if !ok { 89 specAsInterface = map[string]interface{}{} 90 clusterVersion.Object["spec"] = specAsInterface 91 } 92 spec, ok := specAsInterface.(map[string]interface{}) 93 if !ok { 94 return errors.Errorf("unexpected type (%T) for .spec in clusterversion", specAsInterface) 95 } 96 originalOverridesAsInterface := spec["overrides"] 97 originalOverrides, ok := originalOverridesAsInterface.([]interface{}) 98 if !ok && originalOverridesAsInterface != nil { 99 return errors.Errorf("unexpected type (%T) for .spec.overrides in clusterversion", originalOverridesAsInterface) 100 } 101 originalOverridesPatch := map[string]interface{}{ 102 "spec": map[string]interface{}{ 103 "overrides": originalOverrides, 104 }, 105 } 106 spec["overrides"] = append(ignoredResources, originalOverrides...) 107 108 cvData, err := yaml.Marshal(clusterVersion) 109 if err != nil { 110 return errors.Wrap(err, "error marshalling clusterversion") 111 } 112 a.FileList = append(a.FileList, &asset.File{ 113 Filename: cvoOverridesFilename, 114 Data: cvData, 115 }) 116 117 origOverrideData, err := json.Marshal(originalOverridesPatch) 118 if err != nil { 119 return errors.Wrap(err, "error marshalling original overrides") 120 } 121 a.FileList = append(a.FileList, &asset.File{ 122 Filename: originalOverridesFilename, 123 Data: origOverrideData, 124 }) 125 126 return nil 127 } 128 129 // Files returns the files generated by the asset. 130 func (a *CVOIgnore) Files() []*asset.File { 131 return a.FileList 132 } 133 134 // Load does nothing as the file should not be loaded from disk. 135 func (a *CVOIgnore) Load(f asset.FileFetcher) (bool, error) { 136 return false, nil 137 }