Merge pull request #2724 from lonelyCZ/pr-karmadactl-util-idempotency
Fix and unify `CreateOrUpdateXXX` functions for karmadactl
This commit is contained in:
commit
f32741e13f
|
@ -15,6 +15,7 @@ import (
|
|||
addonutils "github.com/karmada-io/karmada/pkg/karmadactl/addons/utils"
|
||||
"github.com/karmada-io/karmada/pkg/karmadactl/cmdinit/kubernetes"
|
||||
initutils "github.com/karmada-io/karmada/pkg/karmadactl/cmdinit/utils"
|
||||
cmdutil "github.com/karmada-io/karmada/pkg/karmadactl/util"
|
||||
)
|
||||
|
||||
var karmadaDeschedulerLabels = map[string]string{"app": addoninit.DeschedulerResourceName}
|
||||
|
@ -59,7 +60,7 @@ var enableDescheduler = func(opts *addoninit.CommandAddonsEnableOption) error {
|
|||
return fmt.Errorf("decode descheduler deployment error: %v", err)
|
||||
}
|
||||
|
||||
if err := addonutils.CreateOrUpdateDeployment(opts.KubeClientSet, karmadaDeschedulerDeployment); err != nil {
|
||||
if err := cmdutil.CreateOrUpdateDeployment(opts.KubeClientSet, karmadaDeschedulerDeployment); err != nil {
|
||||
return fmt.Errorf("create karmada descheduler deployment error: %v", err)
|
||||
}
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ import (
|
|||
addonutils "github.com/karmada-io/karmada/pkg/karmadactl/addons/utils"
|
||||
"github.com/karmada-io/karmada/pkg/karmadactl/cmdinit/kubernetes"
|
||||
initutils "github.com/karmada-io/karmada/pkg/karmadactl/cmdinit/utils"
|
||||
cmdutil "github.com/karmada-io/karmada/pkg/karmadactl/util"
|
||||
"github.com/karmada-io/karmada/pkg/util/names"
|
||||
)
|
||||
|
||||
|
@ -72,7 +73,7 @@ var enableEstimator = func(opts *addoninit.CommandAddonsEnableOption) error {
|
|||
|
||||
secretName := fmt.Sprintf("%s-kubeconfig", opts.Cluster)
|
||||
secret := secretFromSpec(secretName, opts.Namespace, corev1.SecretTypeOpaque, map[string]string{secretName: string(configBytes)})
|
||||
if err := addonutils.CreateOrUpdateSecret(opts.KubeClientSet, secret); err != nil {
|
||||
if err := cmdutil.CreateOrUpdateSecret(opts.KubeClientSet, secret); err != nil {
|
||||
return fmt.Errorf("create or update scheduler estimator secret error: %v", err)
|
||||
}
|
||||
|
||||
|
@ -89,7 +90,7 @@ var enableEstimator = func(opts *addoninit.CommandAddonsEnableOption) error {
|
|||
if err := kuberuntime.DecodeInto(clientsetscheme.Codecs.UniversalDecoder(), karmadaEstimatorServiceBytes, karmadaEstimatorService); err != nil {
|
||||
return fmt.Errorf("decode karmada scheduler estimator service error: %v", err)
|
||||
}
|
||||
if err := addonutils.CreateService(opts.KubeClientSet, karmadaEstimatorService); err != nil {
|
||||
if err := cmdutil.CreateService(opts.KubeClientSet, karmadaEstimatorService); err != nil {
|
||||
return fmt.Errorf("create or update scheduler estimator service error: %v", err)
|
||||
}
|
||||
|
||||
|
@ -108,7 +109,7 @@ var enableEstimator = func(opts *addoninit.CommandAddonsEnableOption) error {
|
|||
if err := kuberuntime.DecodeInto(clientsetscheme.Codecs.UniversalDecoder(), karmadaEstimatorDeploymentBytes, karmadaEstimatorDeployment); err != nil {
|
||||
return fmt.Errorf("decode karmada scheduler estimator deployment error: %v", err)
|
||||
}
|
||||
if err := addonutils.CreateOrUpdateDeployment(opts.KubeClientSet, karmadaEstimatorDeployment); err != nil {
|
||||
if err := cmdutil.CreateOrUpdateDeployment(opts.KubeClientSet, karmadaEstimatorDeployment); err != nil {
|
||||
return fmt.Errorf("create or update scheduler estimator deployment error: %v", err)
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ import (
|
|||
initkarmada "github.com/karmada-io/karmada/pkg/karmadactl/cmdinit/karmada"
|
||||
"github.com/karmada-io/karmada/pkg/karmadactl/cmdinit/kubernetes"
|
||||
initutils "github.com/karmada-io/karmada/pkg/karmadactl/cmdinit/utils"
|
||||
cmdutil "github.com/karmada-io/karmada/pkg/karmadactl/util"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -135,7 +136,7 @@ func installComponentsOnHostCluster(opts *addoninit.CommandAddonsEnableOption) e
|
|||
return fmt.Errorf("decode karmada search service error: %v", err)
|
||||
}
|
||||
|
||||
if err := addonutils.CreateService(opts.KubeClientSet, karmadaSearchService); err != nil {
|
||||
if err := cmdutil.CreateService(opts.KubeClientSet, karmadaSearchService); err != nil {
|
||||
return fmt.Errorf("create karmada search service error: %v", err)
|
||||
}
|
||||
|
||||
|
@ -161,7 +162,7 @@ func installComponentsOnHostCluster(opts *addoninit.CommandAddonsEnableOption) e
|
|||
if err := kuberuntime.DecodeInto(clientsetscheme.Codecs.UniversalDecoder(), karmadaSearchDeploymentBytes, karmadaSearchDeployment); err != nil {
|
||||
return fmt.Errorf("decode karmada search deployment error: %v", err)
|
||||
}
|
||||
if err := addonutils.CreateOrUpdateDeployment(opts.KubeClientSet, karmadaSearchDeployment); err != nil {
|
||||
if err := cmdutil.CreateOrUpdateDeployment(opts.KubeClientSet, karmadaSearchDeployment); err != nil {
|
||||
return fmt.Errorf("create karmada search deployment error: %v", err)
|
||||
}
|
||||
|
||||
|
@ -186,7 +187,7 @@ func installComponentsOnKarmadaControlPlane(opts *addoninit.CommandAddonsEnableO
|
|||
if err := kuberuntime.DecodeInto(clientsetscheme.Codecs.UniversalDecoder(), aaServiceBytes, aaService); err != nil {
|
||||
return fmt.Errorf("decode karmada search AA service error: %v", err)
|
||||
}
|
||||
if err := addonutils.CreateService(opts.KarmadaKubeClientSet, aaService); err != nil {
|
||||
if err := cmdutil.CreateService(opts.KarmadaKubeClientSet, aaService); err != nil {
|
||||
return fmt.Errorf("create karmada search AA service error: %v", err)
|
||||
}
|
||||
|
||||
|
@ -204,7 +205,7 @@ func installComponentsOnKarmadaControlPlane(opts *addoninit.CommandAddonsEnableO
|
|||
return fmt.Errorf("decode karmada search AA apiservice error: %v", err)
|
||||
}
|
||||
|
||||
if err = addonutils.CreateOrUpdateAPIService(opts.KarmadaAggregatorClientSet, aaAPIService); err != nil {
|
||||
if err = cmdutil.CreateOrUpdateAPIService(opts.KarmadaAggregatorClientSet, aaAPIService); err != nil {
|
||||
return fmt.Errorf("craete karmada search AA apiservice error: %v", err)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,76 +0,0 @@
|
|||
package utils
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/klog/v2"
|
||||
apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1"
|
||||
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
|
||||
func CreateService(KubeClientSet *kubernetes.Clientset, service *corev1.Service) error {
|
||||
if _, err := KubeClientSet.CoreV1().Services(service.ObjectMeta.Namespace).Create(context.TODO(), service, metav1.CreateOptions{}); err != nil {
|
||||
if !apierrors.IsAlreadyExists(err) {
|
||||
return fmt.Errorf("unable to create service: %v", err)
|
||||
}
|
||||
|
||||
klog.Warningf("Service %s is existed, creation process will skip", service.ObjectMeta.Name)
|
||||
}
|
||||
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.
|
||||
func CreateOrUpdateSecret(KubeClientSet *kubernetes.Clientset, secret *corev1.Secret) error {
|
||||
if _, err := KubeClientSet.CoreV1().Secrets(secret.ObjectMeta.Namespace).Create(context.TODO(), secret, metav1.CreateOptions{}); err != nil {
|
||||
if !apierrors.IsAlreadyExists(err) {
|
||||
return fmt.Errorf("unable to create service: %v", err)
|
||||
}
|
||||
|
||||
if _, err := KubeClientSet.CoreV1().Secrets(secret.ObjectMeta.Namespace).Update(context.TODO(), secret, metav1.UpdateOptions{}); err != nil {
|
||||
return fmt.Errorf("unable to update deployment: %v", err)
|
||||
}
|
||||
}
|
||||
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.
|
||||
func CreateOrUpdateDeployment(client kubernetes.Interface, deploy *appsv1.Deployment) error {
|
||||
if _, err := client.AppsV1().Deployments(deploy.ObjectMeta.Namespace).Create(context.TODO(), deploy, metav1.CreateOptions{}); err != nil {
|
||||
if !apierrors.IsAlreadyExists(err) {
|
||||
return fmt.Errorf("unable to create deployment: %v", err)
|
||||
}
|
||||
|
||||
if _, err := client.AppsV1().Deployments(deploy.ObjectMeta.Namespace).Update(context.TODO(), deploy, metav1.UpdateOptions{}); err != nil {
|
||||
return fmt.Errorf("unable to update deployment: %v", err)
|
||||
}
|
||||
}
|
||||
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.
|
||||
func CreateOrUpdateAPIService(apiRegistrationClient *aggregator.Clientset, apiservice *apiregistrationv1.APIService) error {
|
||||
if _, err := apiRegistrationClient.ApiregistrationV1().APIServices().Create(context.TODO(), apiservice, metav1.CreateOptions{}); err != nil {
|
||||
if !apierrors.IsAlreadyExists(err) {
|
||||
return fmt.Errorf("unable to create apiService: %v", err)
|
||||
}
|
||||
|
||||
existAPIService, err := apiRegistrationClient.ApiregistrationV1().APIServices().Get(context.TODO(), apiservice.ObjectMeta.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
apiservice.ObjectMeta.ResourceVersion = existAPIService.ObjectMeta.ResourceVersion
|
||||
|
||||
if _, err := apiRegistrationClient.ApiregistrationV1().APIServices().Update(context.TODO(), apiservice, metav1.UpdateOptions{}); err != nil {
|
||||
return fmt.Errorf("unable to update apiService: %v", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -13,7 +13,7 @@ import (
|
|||
bootstrapapi "k8s.io/cluster-bootstrap/token/api"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
"github.com/karmada-io/karmada/pkg/karmadactl/cmdinit/utils"
|
||||
cmdutil "github.com/karmada-io/karmada/pkg/karmadactl/util"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -47,7 +47,7 @@ func CreateBootstrapConfigMapIfNotExists(clientSet *kubernetes.Clientset, file s
|
|||
|
||||
// Create or update the ConfigMap in the kube-public namespace
|
||||
klog.V(1).Infoln("[bootstrap-token] creating/updating ConfigMap in kube-public namespace")
|
||||
return utils.CreateOrUpdateConfigMap(clientSet, &corev1.ConfigMap{
|
||||
return cmdutil.CreateOrUpdateConfigMap(clientSet, &corev1.ConfigMap{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: bootstrapapi.ConfigMapClusterInfo,
|
||||
Namespace: metav1.NamespacePublic,
|
||||
|
@ -61,7 +61,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
|
||||
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")
|
||||
err := utils.CreateOrUpdateRole(clientSet, &rbacv1.Role{
|
||||
err := cmdutil.CreateOrUpdateRole(clientSet, &rbacv1.Role{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: BootstrapSignerClusterRoleName,
|
||||
Namespace: metav1.NamespacePublic,
|
||||
|
@ -79,7 +79,7 @@ func CreateClusterInfoRBACRules(clientSet *kubernetes.Clientset) error {
|
|||
return err
|
||||
}
|
||||
|
||||
return utils.CreateOrUpdateRoleBinding(clientSet, &rbacv1.RoleBinding{
|
||||
return cmdutil.CreateOrUpdateRoleBinding(clientSet, &rbacv1.RoleBinding{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Name: BootstrapSignerClusterRoleName,
|
||||
Namespace: metav1.NamespacePublic,
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
package utils
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/klog/v2"
|
||||
)
|
||||
|
||||
// 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(clientSet *kubernetes.Clientset, cm *corev1.ConfigMap) error {
|
||||
if _, err := clientSet.CoreV1().ConfigMaps(cm.ObjectMeta.Namespace).Create(context.TODO(), cm, metav1.CreateOptions{}); err != nil {
|
||||
if !apierrors.IsAlreadyExists(err) {
|
||||
return fmt.Errorf("unable to create ConfigMap: %v", err)
|
||||
}
|
||||
|
||||
if _, err := clientSet.CoreV1().ConfigMaps(cm.ObjectMeta.Namespace).Update(context.TODO(), cm, metav1.UpdateOptions{}); err != nil {
|
||||
return fmt.Errorf("unable to update ConfigMap: %v", err)
|
||||
}
|
||||
}
|
||||
klog.Infof("ConfigMap %s/%s has been created or updated.", cm.ObjectMeta.Namespace, cm.ObjectMeta.Name)
|
||||
|
||||
return nil
|
||||
}
|
|
@ -87,35 +87,3 @@ func CreateIfNotExistClusterRoleBinding(clientSet kubernetes.Interface, binding
|
|||
|
||||
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.
|
||||
func CreateOrUpdateRole(clientSet kubernetes.Interface, role *rbacv1.Role) error {
|
||||
if _, err := clientSet.RbacV1().Roles(role.ObjectMeta.Namespace).Create(context.TODO(), role, metav1.CreateOptions{}); err != nil {
|
||||
if !apierrors.IsAlreadyExists(err) {
|
||||
return fmt.Errorf("unable to create RBAC role: %v", err)
|
||||
}
|
||||
|
||||
if _, err := clientSet.RbacV1().Roles(role.ObjectMeta.Namespace).Update(context.TODO(), role, metav1.UpdateOptions{}); err != nil {
|
||||
return fmt.Errorf("unable to update RBAC role: %v", err)
|
||||
}
|
||||
}
|
||||
klog.Infof("Role %s%s has been created or updated.", role.ObjectMeta.Namespace, role.ObjectMeta.Name)
|
||||
|
||||
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.
|
||||
func CreateOrUpdateRoleBinding(clientSet kubernetes.Interface, roleBinding *rbacv1.RoleBinding) error {
|
||||
if _, err := clientSet.RbacV1().RoleBindings(roleBinding.ObjectMeta.Namespace).Create(context.TODO(), roleBinding, metav1.CreateOptions{}); err != nil {
|
||||
if !apierrors.IsAlreadyExists(err) {
|
||||
return fmt.Errorf("unable to create RBAC rolebinding: %v", err)
|
||||
}
|
||||
|
||||
if _, err := clientSet.RbacV1().RoleBindings(roleBinding.ObjectMeta.Namespace).Update(context.TODO(), roleBinding, metav1.UpdateOptions{}); err != nil {
|
||||
return fmt.Errorf("unable to update RBAC rolebinding: %v", err)
|
||||
}
|
||||
}
|
||||
klog.Infof("RoleBinding %s/%s has been created or updated.", roleBinding.ObjectMeta.Namespace, roleBinding.ObjectMeta.Name)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ import (
|
|||
check "github.com/karmada-io/karmada/pkg/karmadactl/cmdinit/kubernetes"
|
||||
"github.com/karmada-io/karmada/pkg/karmadactl/cmdinit/utils"
|
||||
"github.com/karmada-io/karmada/pkg/karmadactl/options"
|
||||
"github.com/karmada-io/karmada/pkg/karmadactl/util"
|
||||
cmdutil "github.com/karmada-io/karmada/pkg/karmadactl/util"
|
||||
tokenutil "github.com/karmada-io/karmada/pkg/karmadactl/util/bootstraptoken"
|
||||
karmadautil "github.com/karmada-io/karmada/pkg/util"
|
||||
"github.com/karmada-io/karmada/pkg/util/lifted/pubkeypin"
|
||||
|
@ -148,7 +148,7 @@ func NewCmdRegister(parentCommand string) *cobra.Command {
|
|||
return nil
|
||||
},
|
||||
Annotations: map[string]string{
|
||||
util.TagCommandGroup: util.GroupClusterRegistration,
|
||||
cmdutil.TagCommandGroup: cmdutil.GroupClusterRegistration,
|
||||
},
|
||||
}
|
||||
flags := cmd.Flags()
|
||||
|
@ -570,7 +570,7 @@ func (o *CommandRegisterOption) createSecretAndRBACInMemberCluster(karmadaAgentC
|
|||
}
|
||||
|
||||
// cerate karmada-kubeconfig secret to be used by karmada-agent component.
|
||||
if err := karmadautil.CreateOrUpdateSecret(o.memberClusterClient, kubeConfigSecret); err != nil {
|
||||
if err := cmdutil.CreateOrUpdateSecret(o.memberClusterClient, kubeConfigSecret); err != nil {
|
||||
return fmt.Errorf("create secret %s failed: %v", kubeConfigSecret.Name, err)
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ import (
|
|||
bootstrapsecretutil "k8s.io/cluster-bootstrap/util/secrets"
|
||||
"k8s.io/klog/v2"
|
||||
|
||||
karmadautil "github.com/karmada-io/karmada/pkg/util"
|
||||
cmdutil "github.com/karmada-io/karmada/pkg/karmadactl/util"
|
||||
"github.com/karmada-io/karmada/pkg/util/lifted/pubkeypin"
|
||||
)
|
||||
|
||||
|
@ -322,7 +322,7 @@ func UpdateOrCreateToken(client kubeclient.Interface, failIfExists bool, token *
|
|||
updatedOrNewSecret := ConvertBootstrapTokenToSecret(token)
|
||||
// Try to create or update the token with an exponential backoff
|
||||
err = TryRunCommand(func() error {
|
||||
if err := karmadautil.CreateOrUpdateSecret(client, updatedOrNewSecret); err != nil {
|
||||
if err := cmdutil.CreateOrUpdateSecret(client, updatedOrNewSecret); err != nil {
|
||||
return fmt.Errorf("failed to create or update bootstrap token with name %s, err: %w", secretName, err)
|
||||
}
|
||||
return nil
|
||||
|
|
|
@ -0,0 +1,160 @@
|
|||
package util
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
rbacv1 "k8s.io/api/rbac/v1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
kubeclient "k8s.io/client-go/kubernetes"
|
||||
"k8s.io/klog/v2"
|
||||
apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1"
|
||||
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
|
||||
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 !apierrors.IsAlreadyExists(err) {
|
||||
return fmt.Errorf("unable to create service: %v", err)
|
||||
}
|
||||
|
||||
klog.Warningf("Service %s is existed, creation process will skip", service.ObjectMeta.Name)
|
||||
}
|
||||
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.
|
||||
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 !apierrors.IsAlreadyExists(err) {
|
||||
return fmt.Errorf("unable to create service: %v", err)
|
||||
}
|
||||
|
||||
existSecret, err := client.CoreV1().Secrets(secret.Namespace).Get(context.TODO(), secret.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
secret.ResourceVersion = existSecret.ResourceVersion
|
||||
|
||||
if _, err := client.CoreV1().Secrets(secret.ObjectMeta.Namespace).Update(context.TODO(), secret, metav1.UpdateOptions{}); err != nil {
|
||||
return fmt.Errorf("unable to update deployment: %v", err)
|
||||
}
|
||||
}
|
||||
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.
|
||||
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 !apierrors.IsAlreadyExists(err) {
|
||||
return fmt.Errorf("unable to create deployment: %v", err)
|
||||
}
|
||||
|
||||
existDeployment, err := client.AppsV1().Deployments(deploy.Namespace).Get(context.TODO(), deploy.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
deploy.ResourceVersion = existDeployment.ResourceVersion
|
||||
|
||||
if _, err := client.AppsV1().Deployments(deploy.ObjectMeta.Namespace).Update(context.TODO(), deploy, metav1.UpdateOptions{}); err != nil {
|
||||
return fmt.Errorf("unable to update deployment: %v", err)
|
||||
}
|
||||
}
|
||||
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.
|
||||
func CreateOrUpdateAPIService(apiRegistrationClient *aggregator.Clientset, apiservice *apiregistrationv1.APIService) error {
|
||||
if _, err := apiRegistrationClient.ApiregistrationV1().APIServices().Create(context.TODO(), apiservice, metav1.CreateOptions{}); err != nil {
|
||||
if !apierrors.IsAlreadyExists(err) {
|
||||
return fmt.Errorf("unable to create apiService: %v", err)
|
||||
}
|
||||
|
||||
existAPIService, err := apiRegistrationClient.ApiregistrationV1().APIServices().Get(context.TODO(), apiservice.ObjectMeta.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
apiservice.ObjectMeta.ResourceVersion = existAPIService.ObjectMeta.ResourceVersion
|
||||
|
||||
if _, err := apiRegistrationClient.ApiregistrationV1().APIServices().Update(context.TODO(), apiservice, metav1.UpdateOptions{}); err != nil {
|
||||
return fmt.Errorf("unable to update apiService: %v", err)
|
||||
}
|
||||
}
|
||||
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.
|
||||
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 !apierrors.IsAlreadyExists(err) {
|
||||
return fmt.Errorf("unable to create RBAC role: %v", err)
|
||||
}
|
||||
|
||||
existRole, err := client.AppsV1().Deployments(role.Namespace).Get(context.TODO(), role.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
role.ResourceVersion = existRole.ResourceVersion
|
||||
|
||||
if _, err := client.RbacV1().Roles(role.ObjectMeta.Namespace).Update(context.TODO(), role, metav1.UpdateOptions{}); err != nil {
|
||||
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)
|
||||
|
||||
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.
|
||||
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 !apierrors.IsAlreadyExists(err) {
|
||||
return fmt.Errorf("unable to create RBAC rolebinding: %v", err)
|
||||
}
|
||||
|
||||
existRoleBinding, err := client.AppsV1().Deployments(roleBinding.Namespace).Get(context.TODO(), roleBinding.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
roleBinding.ResourceVersion = existRoleBinding.ResourceVersion
|
||||
|
||||
if _, err := client.RbacV1().RoleBindings(roleBinding.ObjectMeta.Namespace).Update(context.TODO(), roleBinding, metav1.UpdateOptions{}); err != nil {
|
||||
return fmt.Errorf("unable to update RBAC rolebinding: %v", err)
|
||||
}
|
||||
}
|
||||
klog.V(2).Infof("RoleBinding %s/%s has been created or updated.", roleBinding.ObjectMeta.Namespace, roleBinding.ObjectMeta.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 {
|
||||
if _, err := client.CoreV1().ConfigMaps(cm.ObjectMeta.Namespace).Create(context.TODO(), cm, metav1.CreateOptions{}); err != nil {
|
||||
if !apierrors.IsAlreadyExists(err) {
|
||||
return fmt.Errorf("unable to create ConfigMap: %v", err)
|
||||
}
|
||||
|
||||
existCm, err := client.AppsV1().Deployments(cm.Namespace).Get(context.TODO(), cm.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cm.ResourceVersion = existCm.ResourceVersion
|
||||
|
||||
if _, err := client.CoreV1().ConfigMaps(cm.ObjectMeta.Namespace).Update(context.TODO(), cm, metav1.UpdateOptions{}); err != nil {
|
||||
return fmt.Errorf("unable to update ConfigMap: %v", err)
|
||||
}
|
||||
}
|
||||
klog.V(2).Infof("ConfigMap %s/%s has been created or updated.", cm.ObjectMeta.Namespace, cm.ObjectMeta.Name)
|
||||
|
||||
return nil
|
||||
}
|
|
@ -0,0 +1,86 @@
|
|||
package util
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
coretesting "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
func TestCreateOrUpdateSecret(t *testing.T) {
|
||||
type args struct {
|
||||
client kubernetes.Interface
|
||||
secret *corev1.Secret
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "create success",
|
||||
args: args{
|
||||
client: fake.NewSimpleClientset(),
|
||||
secret: makeSecret("test"),
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "update success",
|
||||
args: args{
|
||||
client: fake.NewSimpleClientset(makeSecret("test")),
|
||||
secret: makeSecret("test"),
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "create error",
|
||||
args: args{
|
||||
client: func() kubernetes.Interface {
|
||||
c := fake.NewSimpleClientset()
|
||||
c.PrependReactor("create", "*", func(action coretesting.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, nil, errors.New("create secret error")
|
||||
})
|
||||
return c
|
||||
}(),
|
||||
secret: makeSecret("test"),
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "update error",
|
||||
args: args{
|
||||
client: func() kubernetes.Interface {
|
||||
c := fake.NewSimpleClientset(makeSecret("test"))
|
||||
c.PrependReactor("update", "*", func(action coretesting.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, nil, errors.New("update secret error")
|
||||
})
|
||||
return c
|
||||
}(),
|
||||
secret: makeSecret("test"),
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if err := CreateOrUpdateSecret(tt.args.client, tt.args.secret); (err != nil) != tt.wantErr {
|
||||
t.Errorf("CreateOrUpdateSecret() error = %v, wantErr %v", err, tt.wantErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func makeSecret(name string) *corev1.Secret {
|
||||
return &corev1.Secret{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
Namespace: metav1.NamespaceDefault,
|
||||
Name: name,
|
||||
},
|
||||
}
|
||||
}
|
|
@ -3,7 +3,6 @@ package util
|
|||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
|
@ -45,17 +44,3 @@ func PatchSecret(client kubeclient.Interface, namespace, name string, pt types.P
|
|||
}
|
||||
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.
|
||||
func CreateOrUpdateSecret(client kubeclient.Interface, secret *corev1.Secret) error {
|
||||
if _, err := client.CoreV1().Secrets(secret.ObjectMeta.Namespace).Create(context.TODO(), secret, metav1.CreateOptions{}); err != nil {
|
||||
if !apierrors.IsAlreadyExists(err) {
|
||||
return fmt.Errorf("unable to create secret, err: %w", err)
|
||||
}
|
||||
|
||||
if _, err := client.CoreV1().Secrets(secret.ObjectMeta.Namespace).Update(context.TODO(), secret, metav1.UpdateOptions{}); err != nil {
|
||||
return fmt.Errorf("unable to update secret, err: %w", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -1,83 +1,16 @@
|
|||
package util
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
"k8s.io/client-go/kubernetes/fake"
|
||||
coretesting "k8s.io/client-go/testing"
|
||||
)
|
||||
|
||||
func TestCreateOrUpdateSecret(t *testing.T) {
|
||||
type args struct {
|
||||
client kubernetes.Interface
|
||||
secret *corev1.Secret
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "create success",
|
||||
args: args{
|
||||
client: fake.NewSimpleClientset(),
|
||||
secret: makeSecret("test"),
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "update success",
|
||||
args: args{
|
||||
client: fake.NewSimpleClientset(makeSecret("test")),
|
||||
secret: makeSecret("test"),
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "create error",
|
||||
args: args{
|
||||
client: func() kubernetes.Interface {
|
||||
c := fake.NewSimpleClientset()
|
||||
c.PrependReactor("create", "*", func(action coretesting.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, nil, errors.New("create secret error")
|
||||
})
|
||||
return c
|
||||
}(),
|
||||
secret: makeSecret("test"),
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "update error",
|
||||
args: args{
|
||||
client: func() kubernetes.Interface {
|
||||
c := fake.NewSimpleClientset(makeSecret("test"))
|
||||
c.PrependReactor("update", "*", func(action coretesting.Action) (handled bool, ret runtime.Object, err error) {
|
||||
return true, nil, errors.New("update secret error")
|
||||
})
|
||||
return c
|
||||
}(),
|
||||
secret: makeSecret("test"),
|
||||
},
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if err := CreateOrUpdateSecret(tt.args.client, tt.args.secret); (err != nil) != tt.wantErr {
|
||||
t.Errorf("CreateOrUpdateSecret() error = %v, wantErr %v", err, tt.wantErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateSecret(t *testing.T) {
|
||||
type args struct {
|
||||
client kubernetes.Interface
|
||||
|
|
Loading…
Reference in New Issue