github.com/stefanmcshane/helm@v0.0.0-20221213002717-88a4a2c6e77d/pkg/action/lazyclient.go (about) 1 /* 2 Copyright The Helm Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package action 18 19 import ( 20 "context" 21 "sync" 22 23 v1 "k8s.io/api/core/v1" 24 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 25 "k8s.io/apimachinery/pkg/types" 26 "k8s.io/apimachinery/pkg/watch" 27 applycorev1 "k8s.io/client-go/applyconfigurations/core/v1" 28 "k8s.io/client-go/kubernetes" 29 corev1 "k8s.io/client-go/kubernetes/typed/core/v1" 30 ) 31 32 // lazyClient is a workaround to deal with Kubernetes having an unstable client API. 33 // In Kubernetes v1.18 the defaults where removed which broke creating a 34 // client without an explicit configuration. ಠ_ಠ 35 type lazyClient struct { 36 // client caches an initialized kubernetes client 37 initClient sync.Once 38 client kubernetes.Interface 39 clientErr error 40 41 // clientFn loads a kubernetes client 42 clientFn func() (*kubernetes.Clientset, error) 43 44 // namespace passed to each client request 45 namespace string 46 } 47 48 func (s *lazyClient) init() error { 49 s.initClient.Do(func() { 50 s.client, s.clientErr = s.clientFn() 51 }) 52 return s.clientErr 53 } 54 55 // secretClient implements a corev1.SecretsInterface 56 type secretClient struct{ *lazyClient } 57 58 var _ corev1.SecretInterface = (*secretClient)(nil) 59 60 func newSecretClient(lc *lazyClient) *secretClient { 61 return &secretClient{lazyClient: lc} 62 } 63 64 func (s *secretClient) Create(ctx context.Context, secret *v1.Secret, opts metav1.CreateOptions) (result *v1.Secret, err error) { 65 if err := s.init(); err != nil { 66 return nil, err 67 } 68 return s.client.CoreV1().Secrets(s.namespace).Create(ctx, secret, opts) 69 } 70 71 func (s *secretClient) Update(ctx context.Context, secret *v1.Secret, opts metav1.UpdateOptions) (*v1.Secret, error) { 72 if err := s.init(); err != nil { 73 return nil, err 74 } 75 return s.client.CoreV1().Secrets(s.namespace).Update(ctx, secret, opts) 76 } 77 78 func (s *secretClient) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { 79 if err := s.init(); err != nil { 80 return err 81 } 82 return s.client.CoreV1().Secrets(s.namespace).Delete(ctx, name, opts) 83 } 84 85 func (s *secretClient) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { 86 if err := s.init(); err != nil { 87 return err 88 } 89 return s.client.CoreV1().Secrets(s.namespace).DeleteCollection(ctx, opts, listOpts) 90 } 91 92 func (s *secretClient) Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.Secret, error) { 93 if err := s.init(); err != nil { 94 return nil, err 95 } 96 return s.client.CoreV1().Secrets(s.namespace).Get(ctx, name, opts) 97 } 98 99 func (s *secretClient) List(ctx context.Context, opts metav1.ListOptions) (*v1.SecretList, error) { 100 if err := s.init(); err != nil { 101 return nil, err 102 } 103 return s.client.CoreV1().Secrets(s.namespace).List(ctx, opts) 104 } 105 106 func (s *secretClient) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { 107 if err := s.init(); err != nil { 108 return nil, err 109 } 110 return s.client.CoreV1().Secrets(s.namespace).Watch(ctx, opts) 111 } 112 113 func (s *secretClient) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (*v1.Secret, error) { 114 if err := s.init(); err != nil { 115 return nil, err 116 } 117 return s.client.CoreV1().Secrets(s.namespace).Patch(ctx, name, pt, data, opts, subresources...) 118 } 119 120 func (s *secretClient) Apply(ctx context.Context, secretConfiguration *applycorev1.SecretApplyConfiguration, opts metav1.ApplyOptions) (*v1.Secret, error) { 121 if err := s.init(); err != nil { 122 return nil, err 123 } 124 return s.client.CoreV1().Secrets(s.namespace).Apply(ctx, secretConfiguration, opts) 125 } 126 127 // configMapClient implements a corev1.ConfigMapInterface 128 type configMapClient struct{ *lazyClient } 129 130 var _ corev1.ConfigMapInterface = (*configMapClient)(nil) 131 132 func newConfigMapClient(lc *lazyClient) *configMapClient { 133 return &configMapClient{lazyClient: lc} 134 } 135 136 func (c *configMapClient) Create(ctx context.Context, configMap *v1.ConfigMap, opts metav1.CreateOptions) (*v1.ConfigMap, error) { 137 if err := c.init(); err != nil { 138 return nil, err 139 } 140 return c.client.CoreV1().ConfigMaps(c.namespace).Create(ctx, configMap, opts) 141 } 142 143 func (c *configMapClient) Update(ctx context.Context, configMap *v1.ConfigMap, opts metav1.UpdateOptions) (*v1.ConfigMap, error) { 144 if err := c.init(); err != nil { 145 return nil, err 146 } 147 return c.client.CoreV1().ConfigMaps(c.namespace).Update(ctx, configMap, opts) 148 } 149 150 func (c *configMapClient) Delete(ctx context.Context, name string, opts metav1.DeleteOptions) error { 151 if err := c.init(); err != nil { 152 return err 153 } 154 return c.client.CoreV1().ConfigMaps(c.namespace).Delete(ctx, name, opts) 155 } 156 157 func (c *configMapClient) DeleteCollection(ctx context.Context, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { 158 if err := c.init(); err != nil { 159 return err 160 } 161 return c.client.CoreV1().ConfigMaps(c.namespace).DeleteCollection(ctx, opts, listOpts) 162 } 163 164 func (c *configMapClient) Get(ctx context.Context, name string, opts metav1.GetOptions) (*v1.ConfigMap, error) { 165 if err := c.init(); err != nil { 166 return nil, err 167 } 168 return c.client.CoreV1().ConfigMaps(c.namespace).Get(ctx, name, opts) 169 } 170 171 func (c *configMapClient) List(ctx context.Context, opts metav1.ListOptions) (*v1.ConfigMapList, error) { 172 if err := c.init(); err != nil { 173 return nil, err 174 } 175 return c.client.CoreV1().ConfigMaps(c.namespace).List(ctx, opts) 176 } 177 178 func (c *configMapClient) Watch(ctx context.Context, opts metav1.ListOptions) (watch.Interface, error) { 179 if err := c.init(); err != nil { 180 return nil, err 181 } 182 return c.client.CoreV1().ConfigMaps(c.namespace).Watch(ctx, opts) 183 } 184 185 func (c *configMapClient) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts metav1.PatchOptions, subresources ...string) (*v1.ConfigMap, error) { 186 if err := c.init(); err != nil { 187 return nil, err 188 } 189 return c.client.CoreV1().ConfigMaps(c.namespace).Patch(ctx, name, pt, data, opts, subresources...) 190 } 191 192 func (c *configMapClient) Apply(ctx context.Context, configMap *applycorev1.ConfigMapApplyConfiguration, opts metav1.ApplyOptions) (*v1.ConfigMap, error) { 193 if err := c.init(); err != nil { 194 return nil, err 195 } 196 return c.client.CoreV1().ConfigMaps(c.namespace).Apply(ctx, configMap, opts) 197 }