github.com/metaprov/modela-operator@v0.0.0-20240118193048-f378be8b74d2/pkg/kube/resource.go (about) 1 package kube 2 3 import ( 4 "context" 5 "io/ioutil" 6 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" 7 "k8s.io/apimachinery/pkg/runtime/schema" 8 "k8s.io/apimachinery/pkg/util/sets" 9 "k8s.io/cli-runtime/pkg/genericclioptions" 10 "k8s.io/cli-runtime/pkg/printers" 11 "k8s.io/cli-runtime/pkg/resource" 12 13 "k8s.io/kubectl/pkg/cmd/apply" 14 k8sdelete "k8s.io/kubectl/pkg/cmd/delete" 15 "k8s.io/kubectl/pkg/cmd/util" 16 "k8s.io/kubectl/pkg/scheme" 17 "log" 18 "path/filepath" 19 ctrl "sigs.k8s.io/controller-runtime" 20 "sigs.k8s.io/controller-runtime/pkg/client" 21 "sigs.k8s.io/controller-runtime/pkg/client/config" 22 "sigs.k8s.io/kustomize/api/krusty" 23 "sigs.k8s.io/kustomize/kyaml/filesys" 24 "sigs.k8s.io/kustomize/kyaml/kio" 25 "strings" 26 ) 27 28 var kustomizer = krusty.MakeKustomizer(krusty.MakeDefaultOptions()) 29 30 func LoadResources(folder string, filters []kio.Filter, loadAll bool) ([]byte, int, error) { 31 path, _ := filepath.Abs("./manifests") 32 resMap, err := kustomizer.Run(filesys.MakeFsOnDisk(), filepath.Join(path, folder)) 33 if err != nil { 34 return nil, 0, err 35 } 36 for _, filter := range filters { 37 if err = resMap.ApplyFilter(filter); err != nil { 38 return nil, 0, err 39 } 40 } 41 42 var missing = 0 43 k8sclient, err := client.New(config.GetConfigOrDie(), client.Options{}) 44 45 if !loadAll { 46 for _, res := range resMap.Resources() { 47 obj := &unstructured.Unstructured{} 48 obj.SetGroupVersionKind(schema.GroupVersionKind{ 49 Group: res.GetGvk().Group, 50 Version: res.GetGvk().Version, 51 Kind: res.GetGvk().Kind, 52 }) 53 err := k8sclient.Get(context.Background(), client.ObjectKey{Namespace: res.GetNamespace(), Name: res.GetName()}, obj) 54 if err != nil { 55 missing++ 56 } else { 57 _ = resMap.Remove(res.OrgId()) 58 } 59 } 60 } 61 62 if yaml, err := resMap.AsYaml(); err == nil { 63 return yaml, missing, nil 64 } else { 65 return nil, missing, err 66 } 67 } 68 69 func ApplyYaml(yaml string) error { 70 f := util.NewFactory(RESTClientGetter{RestConfig: ctrl.GetConfigOrDie()}) 71 mapper, err := f.ToRESTMapper() 72 if err != nil { 73 return err 74 } 75 dynamicClient, err := f.DynamicClient() 76 if err != nil { 77 return err 78 } 79 openAPISchema, _ := f.OpenAPISchema() 80 81 tmpfile, _ := ioutil.TempFile("", "*kubectl_manifest.yaml") 82 _, _ = tmpfile.Write([]byte(yaml)) 83 _ = tmpfile.Close() 84 85 applyOptions := &apply.ApplyOptions{ 86 IOStreams: genericclioptions.IOStreams{ 87 In: strings.NewReader(yaml), 88 Out: log.Writer(), 89 ErrOut: log.Writer(), 90 }, 91 Builder: f.NewBuilder(), 92 DynamicClient: dynamicClient, 93 Mapper: mapper, 94 OpenAPISchema: openAPISchema, 95 Recorder: genericclioptions.NoopRecorder{}, 96 ToPrinter: func(string) (printers.ResourcePrinter, error) { 97 return &printers.NamePrinter{Operation: "serverside-applied"}, nil 98 }, 99 DeleteOptions: &k8sdelete.DeleteOptions{ 100 FilenameOptions: resource.FilenameOptions{ 101 Filenames: []string{tmpfile.Name()}, 102 }, 103 }, 104 EnforceNamespace: false, 105 106 VisitedUids: sets.NewString(), 107 VisitedNamespaces: sets.NewString(), 108 PrintFlags: genericclioptions.NewPrintFlags("created").WithTypeSetter(scheme.Scheme), 109 Overwrite: true, 110 ServerSideApply: true, 111 FieldManager: "kubectl", 112 ForceConflicts: true, 113 } 114 115 err = applyOptions.Run() 116 if err != nil { 117 return err 118 } 119 120 return nil 121 122 } 123 124 func ApplyUrlKustomize(url string) error { 125 f := util.NewFactory(RESTClientGetter{RestConfig: ctrl.GetConfigOrDie()}) 126 mapper, err := f.ToRESTMapper() 127 if err != nil { 128 return err 129 } 130 dynamicClient, err := f.DynamicClient() 131 if err != nil { 132 return err 133 } 134 openAPISchema, _ := f.OpenAPISchema() 135 applyOptions := &apply.ApplyOptions{ 136 IOStreams: genericclioptions.IOStreams{ 137 Out: log.Writer(), 138 ErrOut: log.Writer(), 139 }, 140 Builder: f.NewBuilder(), 141 DynamicClient: dynamicClient, 142 Mapper: mapper, 143 OpenAPISchema: openAPISchema, 144 Recorder: genericclioptions.NoopRecorder{}, 145 ToPrinter: func(string) (printers.ResourcePrinter, error) { 146 return &printers.NamePrinter{Operation: "serverside-applied"}, nil 147 }, 148 DeleteOptions: &k8sdelete.DeleteOptions{ 149 FilenameOptions: resource.FilenameOptions{ 150 Kustomize: url, 151 }, 152 }, 153 EnforceNamespace: false, 154 155 VisitedUids: sets.NewString(), 156 VisitedNamespaces: sets.NewString(), 157 PrintFlags: genericclioptions.NewPrintFlags("created").WithTypeSetter(scheme.Scheme), 158 Overwrite: true, 159 ServerSideApply: true, 160 FieldManager: "kubectl", 161 } 162 163 err = applyOptions.Run() 164 if err != nil { 165 return err 166 } 167 168 return nil 169 }