github.com/joelanford/operator-sdk@v0.8.2/internal/util/yamlutil/manifest.go (about) 1 // Copyright 2018 The Operator-SDK Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package yamlutil 16 17 import ( 18 "bytes" 19 "fmt" 20 "io/ioutil" 21 "os" 22 "path/filepath" 23 "strings" 24 25 "github.com/operator-framework/operator-sdk/internal/pkg/scaffold" 26 "github.com/operator-framework/operator-sdk/internal/util/fileutil" 27 28 log "github.com/sirupsen/logrus" 29 ) 30 31 var yamlSep = []byte("\n\n---\n\n") 32 33 // CombineManifests combines given manifests with a base manifest and adds yaml 34 // style separation. Nothing is appended if the manifest is empty or base 35 // already contains a trailing separator. 36 func CombineManifests(base []byte, manifests ...[]byte) []byte { 37 // Base already has manifests we're appending to. 38 base = bytes.Trim(base, " \n") 39 if len(base) > 0 && len(manifests) > 0 { 40 if i := bytes.LastIndex(base, bytes.Trim(yamlSep, "\n")); i != len(base)-3 { 41 base = append(base, yamlSep...) 42 } 43 } 44 for j, manifest := range manifests { 45 if len(manifest) > 0 { 46 base = append(base, bytes.Trim(manifest, " \n")...) 47 // Don't append sep if manifest is the last element in manifests. 48 if j < len(manifests)-1 { 49 base = append(base, yamlSep...) 50 } 51 } 52 } 53 return append(base, '\n') 54 } 55 56 // GenerateCombinedNamespacedManifest creates a temporary manifest yaml 57 // by combining all standard namespaced resource manifests in deployDir. 58 func GenerateCombinedNamespacedManifest(deployDir string) (*os.File, error) { 59 file, err := ioutil.TempFile("", "namespaced-manifest.yaml") 60 if err != nil { 61 return nil, err 62 } 63 defer func() { 64 if err := file.Close(); err != nil && !fileutil.IsClosedError(err) { 65 log.Errorf("Failed to close file %s: (%v)", file.Name(), err) 66 } 67 }() 68 69 sa, err := ioutil.ReadFile(filepath.Join(deployDir, scaffold.ServiceAccountYamlFile)) 70 if err != nil { 71 log.Warnf("Could not find the serviceaccount manifest: (%v)", err) 72 } 73 role, err := ioutil.ReadFile(filepath.Join(deployDir, scaffold.RoleYamlFile)) 74 if err != nil { 75 log.Warnf("Could not find role manifest: (%v)", err) 76 } 77 roleBinding, err := ioutil.ReadFile(filepath.Join(deployDir, scaffold.RoleBindingYamlFile)) 78 if err != nil { 79 log.Warnf("Could not find role_binding manifest: (%v)", err) 80 } 81 operator, err := ioutil.ReadFile(filepath.Join(deployDir, scaffold.OperatorYamlFile)) 82 if err != nil { 83 return nil, fmt.Errorf("could not find operator manifest: (%v)", err) 84 } 85 combined := []byte{} 86 combined = CombineManifests(combined, sa, role, roleBinding, operator) 87 88 if err := file.Chmod(os.FileMode(fileutil.DefaultFileMode)); err != nil { 89 return nil, fmt.Errorf("could not chown temporary namespaced manifest file: (%v)", err) 90 } 91 if _, err := file.Write(combined); err != nil { 92 return nil, fmt.Errorf("could not create temporary namespaced manifest file: (%v)", err) 93 } 94 if err := file.Close(); err != nil { 95 return nil, err 96 } 97 return file, nil 98 } 99 100 // GenerateCombinedGlobalManifest creates a temporary manifest yaml 101 // by combining all standard global resource manifests in crdsDir. 102 func GenerateCombinedGlobalManifest(crdsDir string) (*os.File, error) { 103 file, err := ioutil.TempFile("", "global-manifest.yaml") 104 if err != nil { 105 return nil, err 106 } 107 defer func() { 108 if err := file.Close(); err != nil && !fileutil.IsClosedError(err) { 109 log.Errorf("Failed to close file %s: (%v)", file.Name(), err) 110 } 111 }() 112 113 files, err := ioutil.ReadDir(crdsDir) 114 if err != nil { 115 return nil, fmt.Errorf("could not read deploy directory: (%v)", err) 116 } 117 combined := []byte{} 118 for _, file := range files { 119 if strings.HasSuffix(file.Name(), "crd.yaml") { 120 fileBytes, err := ioutil.ReadFile(filepath.Join(crdsDir, file.Name())) 121 if err != nil { 122 return nil, fmt.Errorf("could not read file %s: (%v)", filepath.Join(crdsDir, file.Name()), err) 123 } 124 combined = CombineManifests(combined, fileBytes) 125 } 126 } 127 128 if err := file.Chmod(os.FileMode(fileutil.DefaultFileMode)); err != nil { 129 return nil, fmt.Errorf("could not chown temporary global manifest file: (%v)", err) 130 } 131 if _, err := file.Write(combined); err != nil { 132 return nil, fmt.Errorf("could not create temporary global manifest file: (%v)", err) 133 } 134 if err := file.Close(); err != nil { 135 return nil, err 136 } 137 return file, nil 138 }