Fix MutatingWebhookConfig and ValidateWebhookConfig aren't updated

Signed-off-by: lonelyCZ <chengzhe@zju.edu.cn>
This commit is contained in:
lonelyCZ 2022-11-18 20:30:14 +08:00
parent 594ad9f44b
commit a239d538d1
8 changed files with 121 additions and 87 deletions

View File

@ -6,6 +6,7 @@ import (
"k8s.io/klog/v2" "k8s.io/klog/v2"
"github.com/karmada-io/karmada/pkg/karmadactl/cmdinit/utils" "github.com/karmada-io/karmada/pkg/karmadactl/cmdinit/utils"
cmdutil "github.com/karmada-io/karmada/pkg/karmadactl/util"
) )
const ( const (
@ -38,7 +39,7 @@ func AllowBootstrapTokensToPostCSRs(clientSet *kubernetes.Clientset) error {
Name: KarmadaAgentBootstrapTokenAuthGroup, Name: KarmadaAgentBootstrapTokenAuthGroup,
}, },
}, nil) }, nil)
return utils.CreateIfNotExistClusterRoleBinding(clientSet, clusterRoleBinding) return cmdutil.CreateOrUpdateClusterRoleBinding(clientSet, clusterRoleBinding)
} }
// AutoApproveKarmadaAgentBootstrapTokens creates RBAC rules in a way that makes Karmada Agent Bootstrap Tokens' CSR auto-approved by the csrapprover controller // AutoApproveKarmadaAgentBootstrapTokens creates RBAC rules in a way that makes Karmada Agent Bootstrap Tokens' CSR auto-approved by the csrapprover controller
@ -52,7 +53,7 @@ func AutoApproveKarmadaAgentBootstrapTokens(clientSet *kubernetes.Clientset) err
Name: KarmadaAgentBootstrapTokenAuthGroup, Name: KarmadaAgentBootstrapTokenAuthGroup,
}, },
}, nil) }, nil)
return utils.CreateIfNotExistClusterRoleBinding(clientSet, clusterRoleBinding) return cmdutil.CreateOrUpdateClusterRoleBinding(clientSet, clusterRoleBinding)
} }
// AutoApproveAgentCertificateRotation creates RBAC rules in a way that makes Agent certificate rotation CSR auto-approved by the csrapprover controller // AutoApproveAgentCertificateRotation creates RBAC rules in a way that makes Agent certificate rotation CSR auto-approved by the csrapprover controller
@ -66,5 +67,5 @@ func AutoApproveAgentCertificateRotation(clientSet *kubernetes.Clientset) error
Name: KarmadaAgentGroup, Name: KarmadaAgentGroup,
}, },
}, nil) }, nil)
return utils.CreateIfNotExistClusterRoleBinding(clientSet, clusterRoleBinding) return cmdutil.CreateOrUpdateClusterRoleBinding(clientSet, clusterRoleBinding)
} }

View File

@ -60,7 +60,7 @@ func CreateBootstrapConfigMapIfNotExists(clientSet *kubernetes.Clientset, file s
// CreateClusterInfoRBACRules creates the RBAC rules for exposing the cluster-info ConfigMap in the kube-public namespace to unauthenticated users // CreateClusterInfoRBACRules creates the RBAC rules for exposing the cluster-info ConfigMap in the kube-public namespace to unauthenticated users
func CreateClusterInfoRBACRules(clientSet *kubernetes.Clientset) error { func CreateClusterInfoRBACRules(clientSet *kubernetes.Clientset) error {
klog.V(1).Infoln("creating the RBAC rules for exposing the cluster-info ConfigMap in the kube-public namespace") klog.V(1).Info("creating the RBAC rules for exposing the cluster-info ConfigMap in the kube-public namespace")
err := cmdutil.CreateOrUpdateRole(clientSet, &rbacv1.Role{ err := cmdutil.CreateOrUpdateRole(clientSet, &rbacv1.Role{
ObjectMeta: metav1.ObjectMeta{ ObjectMeta: metav1.ObjectMeta{
Name: BootstrapSignerClusterRoleName, Name: BootstrapSignerClusterRoleName,

View File

@ -90,17 +90,18 @@ func InitKarmadaResources(dir, caBase64, systemNamespace string) error {
// create webhook configuration // create webhook configuration
// https://github.com/karmada-io/karmada/blob/master/artifacts/deploy/webhook-configuration.yaml // https://github.com/karmada-io/karmada/blob/master/artifacts/deploy/webhook-configuration.yaml
klog.Info("Create MutatingWebhookConfiguration mutating-config.") klog.Info("Create MutatingWebhookConfiguration mutating-config.")
if err = createMutatingWebhookConfiguration(clientSet, mutatingConfig(caBase64, systemNamespace)); err != nil { if err = createOrUpdateMutatingWebhookConfiguration(clientSet, mutatingConfig(caBase64, systemNamespace)); err != nil {
klog.Exitln(err) klog.Exitln(err)
} }
klog.Info("Create ValidatingWebhookConfiguration validating-config.") klog.Info("Create ValidatingWebhookConfiguration validating-config.")
if err = createValidatingWebhookConfiguration(clientSet, validatingConfig(caBase64, systemNamespace)); err != nil { if err = createOrUpdateValidatingWebhookConfiguration(clientSet, validatingConfig(caBase64, systemNamespace)); err != nil {
klog.Exitln(err) klog.Exitln(err)
} }
// karmada-aggregated-apiserver // karmada-aggregated-apiserver
if err = initAPIService(clientSet, restConfig, systemNamespace); err != nil { klog.Info("Create Service 'karmada-aggregated-apiserver' and APIService 'v1alpha1.cluster.karmada.io'.")
if err = initAggregatedAPIService(clientSet, restConfig, systemNamespace); err != nil {
klog.Exitln(err) klog.Exitln(err)
} }
@ -250,7 +251,7 @@ func getName(str, start, end string) string {
return str return str
} }
func initAPIService(clientSet *kubernetes.Clientset, restConfig *rest.Config, systemNamespace string) error { func initAggregatedAPIService(clientSet *kubernetes.Clientset, restConfig *rest.Config, systemNamespace string) error {
// https://github.com/karmada-io/karmada/blob/master/artifacts/deploy/karmada-aggregated-apiserver-apiservice.yaml // https://github.com/karmada-io/karmada/blob/master/artifacts/deploy/karmada-aggregated-apiserver-apiservice.yaml
aaService := &corev1.Service{ aaService := &corev1.Service{
TypeMeta: metav1.TypeMeta{ TypeMeta: metav1.TypeMeta{
@ -299,7 +300,6 @@ func initAPIService(clientSet *kubernetes.Clientset, restConfig *rest.Config, sy
}, },
} }
klog.Infof("Create APIService '%s'", aaAPIServiceObjName)
if err = cmdutil.CreateOrUpdateAPIService(apiRegistrationClient, aaAPIService); err != nil { if err = cmdutil.CreateOrUpdateAPIService(apiRegistrationClient, aaAPIService); err != nil {
return err return err
} }

View File

@ -3,8 +3,10 @@ package karmada
import ( import (
rbacv1 "k8s.io/api/rbac/v1" rbacv1 "k8s.io/api/rbac/v1"
"k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes"
"k8s.io/klog/v2"
"github.com/karmada-io/karmada/pkg/karmadactl/cmdinit/utils" "github.com/karmada-io/karmada/pkg/karmadactl/cmdinit/utils"
cmdutil "github.com/karmada-io/karmada/pkg/karmadactl/util"
) )
const ( const (
@ -21,7 +23,7 @@ func grantProxyPermissionToAdmin(clientSet kubernetes.Interface) error {
Verbs: []string{"*"}, Verbs: []string{"*"},
}, },
}, nil) }, nil)
err := utils.CreateIfNotExistClusterRole(clientSet, proxyAdminClusterRole) err := cmdutil.CreateOrUpdateClusterRole(clientSet, proxyAdminClusterRole)
if err != nil { if err != nil {
return err return err
} }
@ -32,7 +34,9 @@ func grantProxyPermissionToAdmin(clientSet kubernetes.Interface) error {
Kind: "User", Kind: "User",
Name: clusterProxyAdminUser, Name: clusterProxyAdminUser,
}}, nil) }}, nil)
err = utils.CreateIfNotExistClusterRoleBinding(clientSet, proxyAdminClusterRoleBinding)
klog.V(1).Info("grant cluster proxy permission to 'system:admin'")
err = cmdutil.CreateOrUpdateClusterRoleBinding(clientSet, proxyAdminClusterRoleBinding)
if err != nil { if err != nil {
return err return err
} }
@ -40,7 +44,7 @@ func grantProxyPermissionToAdmin(clientSet kubernetes.Interface) error {
return nil return nil
} }
// grantAccessPermissionToAgent grants the limited access permmission to 'karmada-agent' // grantAccessPermissionToAgent grants the limited access permission to 'karmada-agent'
func grantAccessPermissionToAgent(clientSet kubernetes.Interface) error { func grantAccessPermissionToAgent(clientSet kubernetes.Interface) error {
clusterRole := utils.ClusterRoleFromRules(karmadaAgentAccessClusterRole, []rbacv1.PolicyRule{ clusterRole := utils.ClusterRoleFromRules(karmadaAgentAccessClusterRole, []rbacv1.PolicyRule{
{ {
@ -104,7 +108,7 @@ func grantAccessPermissionToAgent(clientSet kubernetes.Interface) error {
Verbs: []string{"create", "patch", "update"}, Verbs: []string{"create", "patch", "update"},
}, },
}, nil) }, nil)
err := utils.CreateIfNotExistClusterRole(clientSet, clusterRole) err := cmdutil.CreateOrUpdateClusterRole(clientSet, clusterRole)
if err != nil { if err != nil {
return err return err
} }
@ -115,7 +119,9 @@ func grantAccessPermissionToAgent(clientSet kubernetes.Interface) error {
Kind: rbacv1.GroupKind, Kind: rbacv1.GroupKind,
Name: karmadaAgentGroup, Name: karmadaAgentGroup,
}}, nil) }}, nil)
err = utils.CreateIfNotExistClusterRoleBinding(clientSet, clusterRoleBinding)
klog.V(1).Info("grant the limited access permission to 'karmada-agent'")
err = cmdutil.CreateOrUpdateClusterRoleBinding(clientSet, clusterRoleBinding)
if err != nil { if err != nil {
return err return err
} }

View File

@ -160,7 +160,7 @@ webhooks:
timeoutSeconds: 3`, systemNamespace, caBundle) timeoutSeconds: 3`, systemNamespace, caBundle)
} }
func createValidatingWebhookConfiguration(c kubernetes.Interface, staticYaml string) error { func createOrUpdateValidatingWebhookConfiguration(c kubernetes.Interface, staticYaml string) error {
obj := admissionregistrationv1.ValidatingWebhookConfiguration{} obj := admissionregistrationv1.ValidatingWebhookConfiguration{}
if err := json.Unmarshal(utils.StaticYamlToJSONByte(staticYaml), &obj); err != nil { if err := json.Unmarshal(utils.StaticYamlToJSONByte(staticYaml), &obj); err != nil {
@ -172,15 +172,24 @@ func createValidatingWebhookConfiguration(c kubernetes.Interface, staticYaml str
if !apierrors.IsAlreadyExists(err) { if !apierrors.IsAlreadyExists(err) {
return err return err
} }
klog.Infof("ValidatingWebhookConfiguration %s already exists, skipping.", obj.Name)
return nil existVwc, err := c.AdmissionregistrationV1().ValidatingWebhookConfigurations().Get(context.TODO(), obj.Name, metav1.GetOptions{})
if err != nil {
return err
} }
klog.Infof("Create ValidatingWebhookConfiguration %s successfully.", obj.Name)
obj.ResourceVersion = existVwc.ResourceVersion
if _, err := c.AdmissionregistrationV1().ValidatingWebhookConfigurations().Update(context.TODO(), &obj, metav1.UpdateOptions{}); err != nil {
return err
}
}
klog.Infof("ValidatingWebhookConfiguration %s has been created or updated successfully.", obj.Name)
return nil return nil
} }
func createMutatingWebhookConfiguration(c kubernetes.Interface, staticYaml string) error { func createOrUpdateMutatingWebhookConfiguration(c kubernetes.Interface, staticYaml string) error {
obj := admissionregistrationv1.MutatingWebhookConfiguration{} obj := admissionregistrationv1.MutatingWebhookConfiguration{}
if err := json.Unmarshal(utils.StaticYamlToJSONByte(staticYaml), &obj); err != nil { if err := json.Unmarshal(utils.StaticYamlToJSONByte(staticYaml), &obj); err != nil {
@ -192,10 +201,19 @@ func createMutatingWebhookConfiguration(c kubernetes.Interface, staticYaml strin
if !apierrors.IsAlreadyExists(err) { if !apierrors.IsAlreadyExists(err) {
return err return err
} }
klog.Infof("MutatingWebhookConfiguration %s already exists, skipping.", obj.Name)
return nil existMwc, err := c.AdmissionregistrationV1().MutatingWebhookConfigurations().Get(context.TODO(), obj.Name, metav1.GetOptions{})
if err != nil {
return err
} }
klog.Infof("Create MutatingWebhookConfiguration %s successfully.", obj.Name) obj.ResourceVersion = existMwc.ResourceVersion
if _, err := c.AdmissionregistrationV1().MutatingWebhookConfigurations().Update(context.TODO(), &obj, metav1.UpdateOptions{}); err != nil {
return err
}
}
klog.Infof("MutatingWebhookConfiguration %s has been created or updated successfully.", obj.Name)
return nil return nil
} }

View File

@ -7,24 +7,24 @@ import (
"k8s.io/client-go/kubernetes/fake" "k8s.io/client-go/kubernetes/fake"
) )
func Test_createValidatingWebhookConfiguration(t *testing.T) { func Test_createOrUpdateValidatingWebhookConfiguration(t *testing.T) {
client := fake.NewSimpleClientset() client := fake.NewSimpleClientset()
cfg := validatingConfig(base64.StdEncoding.EncodeToString([]byte("foo")), "bar") cfg := validatingConfig(base64.StdEncoding.EncodeToString([]byte("foo")), "bar")
if cfg == "" { if cfg == "" {
t.Errorf("validatingConfig() return = %v, want yaml config", cfg) t.Errorf("validatingConfig() return = %v, want yaml config", cfg)
} }
if err := createValidatingWebhookConfiguration(client, cfg); err != nil { if err := createOrUpdateValidatingWebhookConfiguration(client, cfg); err != nil {
t.Errorf("createValidatingWebhookConfiguration() return = %v, want no error", err) t.Errorf("createOrUpdateValidatingWebhookConfiguration() return = %v, want no error", err)
} }
} }
func Test_createMutatingWebhookConfiguration(t *testing.T) { func Test_createOrUpdateMutatingWebhookConfiguration(t *testing.T) {
client := fake.NewSimpleClientset() client := fake.NewSimpleClientset()
cfg := mutatingConfig(base64.StdEncoding.EncodeToString([]byte("foo")), "bar") cfg := mutatingConfig(base64.StdEncoding.EncodeToString([]byte("foo")), "bar")
if cfg == "" { if cfg == "" {
t.Errorf("mutatingConfig() return = %v, want yaml config", cfg) t.Errorf("mutatingConfig() return = %v, want yaml config", cfg)
} }
if err := createMutatingWebhookConfiguration(client, cfg); err != nil { if err := createOrUpdateMutatingWebhookConfiguration(client, cfg); err != nil {
t.Errorf("createMutatingWebhookConfiguration() return = %v, want no error", err) t.Errorf("createOrUpdateMutatingWebhookConfiguration() return = %v, want no error", err)
} }
} }

View File

@ -1,14 +1,8 @@
package utils package utils
import ( import (
"context"
"fmt"
rbacv1 "k8s.io/api/rbac/v1" rbacv1 "k8s.io/api/rbac/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/klog/v2"
) )
// ClusterRoleFromRules ClusterRole Rules // ClusterRoleFromRules ClusterRole Rules
@ -45,45 +39,3 @@ func ClusterRoleBindingFromSubjects(clusterRoleBindingName, clusterRoleName stri
Subjects: sub, Subjects: sub,
} }
} }
// CreateIfNotExistClusterRole create ClusterRole when it doesn't exist
func CreateIfNotExistClusterRole(clientSet kubernetes.Interface, role *rbacv1.ClusterRole) error {
clusterRoleClient := clientSet.RbacV1().ClusterRoles()
_, err := clusterRoleClient.Get(context.TODO(), role.Name, metav1.GetOptions{})
if err != nil {
if apierrors.IsNotFound(err) {
_, err = clusterRoleClient.Create(context.TODO(), role, metav1.CreateOptions{})
if err != nil {
return fmt.Errorf("create ClusterRole %s failed: %v", role.Name, err)
}
klog.Infof("CreateClusterRole %s success.", role.Name)
return nil
}
return fmt.Errorf("get ClusterRole %s failed: %v", role.Name, err)
}
klog.Infof("CreateClusterRole %s already exists.", role.Name)
return nil
}
// CreateIfNotExistClusterRoleBinding create ClusterRoleBinding when it doesn't exist
func CreateIfNotExistClusterRoleBinding(clientSet kubernetes.Interface, binding *rbacv1.ClusterRoleBinding) error {
crbClient := clientSet.RbacV1().ClusterRoleBindings()
_, err := crbClient.Get(context.TODO(), binding.Name, metav1.GetOptions{})
if err != nil {
if apierrors.IsNotFound(err) {
_, err = crbClient.Create(context.TODO(), binding, metav1.CreateOptions{})
if err != nil {
return fmt.Errorf("create ClusterRoleBinding %s failed: %v", binding.Name, err)
}
klog.Infof("CreateClusterRoleBinding %s success.", binding.Name)
return nil
}
return fmt.Errorf("get ClusterRoleBinding %s failed: %v", binding.Name, err)
}
klog.Infof("CreateClusterRoleBinding %s already exists.", binding.Name)
return nil
}

View File

@ -16,7 +16,8 @@ import (
aggregator "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset" aggregator "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset"
) )
// CreateService creates a Service if the target resource doesn't exist. If the resource exists already, return directly // CreateService creates a Service if the target resource doesn't exist.
// If the resource exists already, return directly
func CreateService(client kubeclient.Interface, service *corev1.Service) error { func CreateService(client kubeclient.Interface, service *corev1.Service) error {
if _, err := client.CoreV1().Services(service.ObjectMeta.Namespace).Create(context.TODO(), service, metav1.CreateOptions{}); err != nil { if _, err := client.CoreV1().Services(service.ObjectMeta.Namespace).Create(context.TODO(), service, metav1.CreateOptions{}); err != nil {
if !apierrors.IsAlreadyExists(err) { if !apierrors.IsAlreadyExists(err) {
@ -28,7 +29,8 @@ func CreateService(client kubeclient.Interface, service *corev1.Service) error {
return nil return nil
} }
// CreateOrUpdateSecret creates a Secret if the target resource doesn't exist. If the resource exists already, this function will update the resource instead. // CreateOrUpdateSecret creates a Secret if the target resource doesn't exist.
// If the resource exists already, this function will update the resource instead.
func CreateOrUpdateSecret(client kubeclient.Interface, secret *corev1.Secret) error { func CreateOrUpdateSecret(client kubeclient.Interface, secret *corev1.Secret) error {
if _, err := client.CoreV1().Secrets(secret.Namespace).Create(context.TODO(), secret, metav1.CreateOptions{}); err != nil { if _, err := client.CoreV1().Secrets(secret.Namespace).Create(context.TODO(), secret, metav1.CreateOptions{}); err != nil {
if !apierrors.IsAlreadyExists(err) { if !apierrors.IsAlreadyExists(err) {
@ -49,7 +51,8 @@ func CreateOrUpdateSecret(client kubeclient.Interface, secret *corev1.Secret) er
return nil return nil
} }
// CreateOrUpdateDeployment creates a Deployment if the target resource doesn't exist. If the resource exists already, this function will update the resource instead. // CreateOrUpdateDeployment creates a Deployment if the target resource doesn't exist.
// If the resource exists already, this function will update the resource instead.
func CreateOrUpdateDeployment(client kubeclient.Interface, deploy *appsv1.Deployment) error { func CreateOrUpdateDeployment(client kubeclient.Interface, deploy *appsv1.Deployment) error {
if _, err := client.AppsV1().Deployments(deploy.Namespace).Create(context.TODO(), deploy, metav1.CreateOptions{}); err != nil { if _, err := client.AppsV1().Deployments(deploy.Namespace).Create(context.TODO(), deploy, metav1.CreateOptions{}); err != nil {
if !apierrors.IsAlreadyExists(err) { if !apierrors.IsAlreadyExists(err) {
@ -70,7 +73,8 @@ func CreateOrUpdateDeployment(client kubeclient.Interface, deploy *appsv1.Deploy
return nil return nil
} }
// CreateOrUpdateAPIService creates a ApiService if the target resource doesn't exist. If the resource exists already, this function will update the resource instead. // CreateOrUpdateAPIService creates a ApiService if the target resource doesn't exist.
// If the resource exists already, this function will update the resource instead.
func CreateOrUpdateAPIService(apiRegistrationClient *aggregator.Clientset, apiservice *apiregistrationv1.APIService) error { func CreateOrUpdateAPIService(apiRegistrationClient *aggregator.Clientset, apiservice *apiregistrationv1.APIService) error {
if _, err := apiRegistrationClient.ApiregistrationV1().APIServices().Create(context.TODO(), apiservice, metav1.CreateOptions{}); err != nil { if _, err := apiRegistrationClient.ApiregistrationV1().APIServices().Create(context.TODO(), apiservice, metav1.CreateOptions{}); err != nil {
if !apierrors.IsAlreadyExists(err) { if !apierrors.IsAlreadyExists(err) {
@ -93,7 +97,8 @@ func CreateOrUpdateAPIService(apiRegistrationClient *aggregator.Clientset, apise
return nil return nil
} }
// CreateOrUpdateRole creates a Role if the target resource doesn't exist. If the resource exists already, this function will update the resource instead. // CreateOrUpdateRole creates a Role if the target resource doesn't exist.
// If the resource exists already, this function will update the resource instead.
func CreateOrUpdateRole(client kubeclient.Interface, role *rbacv1.Role) error { func CreateOrUpdateRole(client kubeclient.Interface, role *rbacv1.Role) error {
if _, err := client.RbacV1().Roles(role.ObjectMeta.Namespace).Create(context.TODO(), role, metav1.CreateOptions{}); err != nil { if _, err := client.RbacV1().Roles(role.ObjectMeta.Namespace).Create(context.TODO(), role, metav1.CreateOptions{}); err != nil {
if !apierrors.IsAlreadyExists(err) { if !apierrors.IsAlreadyExists(err) {
@ -111,12 +116,13 @@ func CreateOrUpdateRole(client kubeclient.Interface, role *rbacv1.Role) error {
return fmt.Errorf("unable to update RBAC role: %v", err) return fmt.Errorf("unable to update RBAC role: %v", err)
} }
} }
klog.V(2).Infof("Role %s%s has been created or updated.", role.ObjectMeta.Namespace, role.ObjectMeta.Name) klog.V(2).Infof("Role %s/%s has been created or updated.", role.ObjectMeta.Namespace, role.ObjectMeta.Name)
return nil return nil
} }
// CreateOrUpdateRoleBinding creates a RoleBinding if the target resource doesn't exist. If the resource exists already, this function will update the resource instead. // CreateOrUpdateRoleBinding creates a RoleBinding if the target resource doesn't exist.
// If the resource exists already, this function will update the resource instead.
func CreateOrUpdateRoleBinding(client kubeclient.Interface, roleBinding *rbacv1.RoleBinding) error { func CreateOrUpdateRoleBinding(client kubeclient.Interface, roleBinding *rbacv1.RoleBinding) error {
if _, err := client.RbacV1().RoleBindings(roleBinding.ObjectMeta.Namespace).Create(context.TODO(), roleBinding, metav1.CreateOptions{}); err != nil { if _, err := client.RbacV1().RoleBindings(roleBinding.ObjectMeta.Namespace).Create(context.TODO(), roleBinding, metav1.CreateOptions{}); err != nil {
if !apierrors.IsAlreadyExists(err) { if !apierrors.IsAlreadyExists(err) {
@ -139,7 +145,56 @@ func CreateOrUpdateRoleBinding(client kubeclient.Interface, roleBinding *rbacv1.
return nil return nil
} }
// CreateOrUpdateConfigMap creates a ConfigMap if the target resource doesn't exist. If the resource exists already, this function will update the resource instead. // CreateOrUpdateClusterRole creates a ClusterRole if the target resource doesn't exist.
// If the resource exists already, this function will update the resource instead.
func CreateOrUpdateClusterRole(client kubeclient.Interface, clusterRole *rbacv1.ClusterRole) error {
if _, err := client.RbacV1().ClusterRoles().Create(context.TODO(), clusterRole, metav1.CreateOptions{}); err != nil {
if !apierrors.IsAlreadyExists(err) {
return fmt.Errorf("unable to create ClusterRole: %v", err)
}
existClusterRole, err := client.RbacV1().ClusterRoles().Get(context.TODO(), clusterRole.Name, metav1.GetOptions{})
if err != nil {
return err
}
clusterRole.ResourceVersion = existClusterRole.ResourceVersion
if _, err := client.RbacV1().ClusterRoles().Update(context.TODO(), clusterRole, metav1.UpdateOptions{}); err != nil {
return fmt.Errorf("unable to update ClusterRole: %v", err)
}
}
klog.V(2).Infof("ClusterRole %s has been created or updated.", clusterRole.Name)
return nil
}
// CreateOrUpdateClusterRoleBinding creates a ClusterRoleBinding if the target resource doesn't exist.
// If the resource exists already, this function will update the resource instead.
func CreateOrUpdateClusterRoleBinding(client kubernetes.Interface, clusterRoleBinding *rbacv1.ClusterRoleBinding) error {
if _, err := client.RbacV1().ClusterRoleBindings().Create(context.TODO(), clusterRoleBinding, metav1.CreateOptions{}); err != nil {
if !apierrors.IsAlreadyExists(err) {
return fmt.Errorf("unable to create ClusterRoleBinding: %v", err)
}
existCrb, err := client.RbacV1().ClusterRoleBindings().Get(context.TODO(), clusterRoleBinding.Name, metav1.GetOptions{})
if err != nil {
return err
}
clusterRoleBinding.ResourceVersion = existCrb.ResourceVersion
if _, err := client.RbacV1().ClusterRoleBindings().Update(context.TODO(), clusterRoleBinding, metav1.UpdateOptions{}); err != nil {
return fmt.Errorf("unable to update ClusterRolebinding: %v", err)
}
}
klog.V(2).Infof("ClusterRolebinding %s has been created or updated.", clusterRoleBinding.Name)
return nil
}
// CreateOrUpdateConfigMap creates a ConfigMap if the target resource doesn't exist.
// If the resource exists already, this function will update the resource instead.
func CreateOrUpdateConfigMap(client *kubeclient.Clientset, cm *corev1.ConfigMap) error { func CreateOrUpdateConfigMap(client *kubeclient.Clientset, cm *corev1.ConfigMap) error {
if _, err := client.CoreV1().ConfigMaps(cm.ObjectMeta.Namespace).Create(context.TODO(), cm, metav1.CreateOptions{}); err != nil { if _, err := client.CoreV1().ConfigMaps(cm.ObjectMeta.Namespace).Create(context.TODO(), cm, metav1.CreateOptions{}); err != nil {
if !apierrors.IsAlreadyExists(err) { if !apierrors.IsAlreadyExists(err) {
@ -171,7 +226,8 @@ func NewNamespace(name string) *corev1.Namespace {
} }
} }
// CreateOrUpdateNamespace creates a Namespaces if the target resource doesn't exist. If the resource exists already, this function will update the resource instead. // CreateOrUpdateNamespace creates a Namespaces if the target resource doesn't exist.
// If the resource exists already, this function will update the resource instead.
func CreateOrUpdateNamespace(client kubeclient.Interface, ns *corev1.Namespace) error { func CreateOrUpdateNamespace(client kubeclient.Interface, ns *corev1.Namespace) error {
if _, err := client.CoreV1().Namespaces().Create(context.TODO(), ns, metav1.CreateOptions{}); err != nil { if _, err := client.CoreV1().Namespaces().Create(context.TODO(), ns, metav1.CreateOptions{}); err != nil {
if !apierrors.IsAlreadyExists(err) { if !apierrors.IsAlreadyExists(err) {
@ -194,7 +250,8 @@ func CreateOrUpdateNamespace(client kubeclient.Interface, ns *corev1.Namespace)
return nil return nil
} }
// CreateOrUpdateService creates a Service if the target resource doesn't exist. If the resource exists already, this function will update the resource instead. // CreateOrUpdateService creates a Service if the target resource doesn't exist.
// If the resource exists already, this function will update the resource instead.
func CreateOrUpdateService(client kubernetes.Interface, svc *corev1.Service) error { func CreateOrUpdateService(client kubernetes.Interface, svc *corev1.Service) error {
if _, err := client.CoreV1().Services(svc.Namespace).Create(context.TODO(), svc, metav1.CreateOptions{}); err != nil { if _, err := client.CoreV1().Services(svc.Namespace).Create(context.TODO(), svc, metav1.CreateOptions{}); err != nil {
if !apierrors.IsAlreadyExists(err) { if !apierrors.IsAlreadyExists(err) {