github.com/SamarSidharth/kpt@v0.0.0-20231122062228-c7d747ae3ace/internal/util/porch/client.go (about) 1 // Copyright 2022 The kpt 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 porch 16 17 import ( 18 "context" 19 20 porchapi "github.com/GoogleContainerTools/kpt/porch/api/porch/v1alpha1" 21 configapi "github.com/GoogleContainerTools/kpt/porch/api/porchconfig/v1alpha1" 22 coreapi "k8s.io/api/core/v1" 23 "k8s.io/apimachinery/pkg/api/meta" 24 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 25 "k8s.io/apimachinery/pkg/runtime" 26 "k8s.io/apimachinery/pkg/runtime/schema" 27 "k8s.io/apimachinery/pkg/runtime/serializer" 28 "k8s.io/cli-runtime/pkg/genericclioptions" 29 "k8s.io/client-go/rest" 30 "sigs.k8s.io/controller-runtime/pkg/client" 31 ) 32 33 func CreateClient(config *rest.Config) (client.Client, error) { 34 scheme, err := createScheme() 35 if err != nil { 36 return nil, err 37 } 38 39 c, err := client.New(config, client.Options{ 40 Scheme: scheme, 41 Mapper: createRESTMapper(), 42 }) 43 if err != nil { 44 return nil, err 45 } 46 47 return c, nil 48 } 49 50 func CreateClientWithFlags(flags *genericclioptions.ConfigFlags) (client.Client, error) { 51 config, err := flags.ToRESTConfig() 52 if err != nil { 53 return nil, err 54 } 55 56 return CreateClient(config) 57 } 58 59 func CreateDynamicClient(flags *genericclioptions.ConfigFlags) (client.WithWatch, error) { 60 config, err := flags.ToRESTConfig() 61 if err != nil { 62 return nil, err 63 } 64 65 scheme, err := createScheme() 66 if err != nil { 67 return nil, err 68 } 69 70 c, err := client.NewWithWatch(config, client.Options{ 71 Scheme: scheme, 72 }) 73 if err != nil { 74 return nil, err 75 } 76 77 return c, nil 78 } 79 80 // controller-runtime does not support subresources so we use REST client directly. 81 // TODO: Separate Porch clientset into its own module (similar to k8s clientsets) to use it 82 // without causing circular reference. 83 func CreateRESTClient(flags *genericclioptions.ConfigFlags) (rest.Interface, error) { 84 config, err := flags.ToRESTConfig() 85 if err != nil { 86 return nil, err 87 } 88 89 scheme, err := createScheme() 90 if err != nil { 91 return nil, err 92 } 93 94 codecs := serializer.NewCodecFactory(scheme) 95 96 gv := porchapi.SchemeGroupVersion 97 config.GroupVersion = &gv 98 config.APIPath = "/apis" 99 config.NegotiatedSerializer = codecs.WithoutConversion() 100 101 return rest.RESTClientFor(config) 102 } 103 104 func createScheme() (*runtime.Scheme, error) { 105 scheme := runtime.NewScheme() 106 107 for _, api := range (runtime.SchemeBuilder{ 108 configapi.AddToScheme, 109 porchapi.AddToScheme, 110 coreapi.AddToScheme, 111 metav1.AddMetaToScheme, 112 }) { 113 if err := api(scheme); err != nil { 114 return nil, err 115 } 116 } 117 return scheme, nil 118 } 119 120 func createRESTMapper() meta.RESTMapper { 121 rm := meta.NewDefaultRESTMapper([]schema.GroupVersion{ 122 configapi.GroupVersion, 123 porchapi.SchemeGroupVersion, 124 coreapi.SchemeGroupVersion, 125 metav1.SchemeGroupVersion, 126 }) 127 128 for _, r := range []struct { 129 kind schema.GroupVersionKind 130 plural, singular string 131 }{ 132 {kind: configapi.GroupVersion.WithKind("Repository"), plural: "repositories", singular: "repository"}, 133 {kind: porchapi.SchemeGroupVersion.WithKind("PackageRevision"), plural: "packagerevisions", singular: "packagerevision"}, 134 {kind: porchapi.SchemeGroupVersion.WithKind("PackageRevisionResources"), plural: "packagerevisionresources", singular: "packagerevisionresources"}, 135 {kind: porchapi.SchemeGroupVersion.WithKind("Function"), plural: "functions", singular: "function"}, 136 {kind: coreapi.SchemeGroupVersion.WithKind("Secret"), plural: "secrets", singular: "secret"}, 137 {kind: metav1.SchemeGroupVersion.WithKind("Table"), plural: "tables", singular: "table"}, 138 } { 139 rm.AddSpecific( 140 r.kind, 141 r.kind.GroupVersion().WithResource(r.plural), 142 r.kind.GroupVersion().WithResource(r.singular), 143 meta.RESTScopeNamespace, 144 ) 145 } 146 147 return rm 148 } 149 150 func Apply(ctx context.Context, api client.Client, obj client.Object) error { 151 return api.Patch(ctx, obj, client.Apply, client.FieldOwner("kubectl")) 152 }