mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-25 11:31:44 +00:00
Merge pull request #128650 from skitt/kubeadm-generic-idempotency
kubeadm: generalise CreateOrUpdate etc.
This commit is contained in:
commit
29101e9774
@ -28,6 +28,7 @@ import (
|
||||
rbac "k8s.io/api/rbac/v1"
|
||||
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/types"
|
||||
"k8s.io/apimachinery/pkg/util/strategicpatch"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
@ -37,28 +38,40 @@ import (
|
||||
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||
)
|
||||
|
||||
// ConfigMapMutator is a function that mutates the given ConfigMap and optionally returns an error
|
||||
type ConfigMapMutator func(*v1.ConfigMap) error
|
||||
// objectMutator is a function that mutates the given runtime object and optionally returns an error
|
||||
type objectMutator[T runtime.Object] func(T) error
|
||||
|
||||
// apiCallRetryInterval holds a local copy of apiCallRetryInterval for testing purposes
|
||||
var apiCallRetryInterval = constants.KubernetesAPICallRetryInterval
|
||||
|
||||
// TODO: We should invent a dynamic mechanism for this using the dynamic client instead of hard-coding these functions per-type
|
||||
type kubernetesInterface[T kubernetesObject] interface {
|
||||
Create(ctx context.Context, obj T, opts metav1.CreateOptions) (T, error)
|
||||
Get(ctx context.Context, name string, opts metav1.GetOptions) (T, error)
|
||||
Update(ctx context.Context, obj T, opts metav1.UpdateOptions) (T, error)
|
||||
}
|
||||
|
||||
// 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 clientset.Interface, cm *v1.ConfigMap) error {
|
||||
type kubernetesObject interface {
|
||||
runtime.Object
|
||||
metav1.Object
|
||||
}
|
||||
|
||||
// CreateOrUpdate creates a runtime object if the target resource doesn't exist.
|
||||
// If the resource exists already, this function will update the resource instead.
|
||||
func CreateOrUpdate[T kubernetesObject](ctx context.Context, client kubernetesInterface[T], obj T) error {
|
||||
var lastError error
|
||||
err := wait.PollUntilContextTimeout(context.Background(),
|
||||
err := wait.PollUntilContextTimeout(ctx,
|
||||
apiCallRetryInterval, kubeadmapi.GetActiveTimeouts().KubernetesAPICall.Duration,
|
||||
true, func(_ context.Context) (bool, error) {
|
||||
// This uses a background context for API calls to avoid confusing callers that don't
|
||||
// expect context-related errors.
|
||||
ctx := context.Background()
|
||||
if _, err := client.CoreV1().ConfigMaps(cm.ObjectMeta.Namespace).Create(ctx, cm, metav1.CreateOptions{}); err != nil {
|
||||
if _, err := client.Create(ctx, obj, metav1.CreateOptions{}); err != nil {
|
||||
if !apierrors.IsAlreadyExists(err) {
|
||||
lastError = errors.Wrap(err, "unable to create ConfigMap")
|
||||
lastError = errors.Wrapf(err, "unable to create %T", obj)
|
||||
return false, nil
|
||||
}
|
||||
if _, err := client.CoreV1().ConfigMaps(cm.ObjectMeta.Namespace).Update(ctx, cm, metav1.UpdateOptions{}); err != nil {
|
||||
lastError = errors.Wrap(err, "unable to update ConfigMap")
|
||||
if _, err := client.Update(ctx, obj, metav1.UpdateOptions{}); err != nil {
|
||||
lastError = errors.Wrapf(err, "unable to update %T", obj)
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
@ -70,19 +83,30 @@ func CreateOrUpdateConfigMap(client clientset.Interface, cm *v1.ConfigMap) error
|
||||
return lastError
|
||||
}
|
||||
|
||||
// CreateOrMutateConfigMap tries to create the ConfigMap provided as cm. If the resource exists already, the latest version will be fetched from
|
||||
// the cluster and mutator callback will be called on it, then an Update of the mutated ConfigMap will be performed. This function is resilient
|
||||
// to conflicts, and a retry will be issued if the ConfigMap was modified on the server between the refresh and the update (while the mutation was
|
||||
// taking place)
|
||||
func CreateOrMutateConfigMap(client clientset.Interface, cm *v1.ConfigMap, mutator ConfigMapMutator) error {
|
||||
// CreateOrUpdateConfigMap creates a ConfigMap if the target resource doesn't exist.
|
||||
// If the resource exists already, this function will update the resource instead.
|
||||
//
|
||||
// Deprecated: use CreateOrUpdate() instead.
|
||||
func CreateOrUpdateConfigMap(client clientset.Interface, cm *v1.ConfigMap) error {
|
||||
return CreateOrUpdate(context.Background(), client.CoreV1().ConfigMaps(cm.ObjectMeta.Namespace), cm)
|
||||
}
|
||||
|
||||
// CreateOrMutate tries to create the provided object. If the resource exists already, the latest version will be fetched from
|
||||
// the cluster and mutator callback will be called on it, then an Update of the mutated object will be performed. This function is resilient
|
||||
// to conflicts, and a retry will be issued if the object was modified on the server between the refresh and the update (while the mutation was
|
||||
// taking place).
|
||||
func CreateOrMutate[T kubernetesObject](ctx context.Context, client kubernetesInterface[T], obj T, mutator objectMutator[T]) error {
|
||||
var lastError error
|
||||
err := wait.PollUntilContextTimeout(context.Background(),
|
||||
err := wait.PollUntilContextTimeout(ctx,
|
||||
apiCallRetryInterval, kubeadmapi.GetActiveTimeouts().KubernetesAPICall.Duration,
|
||||
true, func(_ context.Context) (bool, error) {
|
||||
if _, err := client.CoreV1().ConfigMaps(cm.ObjectMeta.Namespace).Create(context.Background(), cm, metav1.CreateOptions{}); err != nil {
|
||||
// This uses a background context for API calls to avoid confusing callers that don't
|
||||
// expect context-related errors.
|
||||
ctx := context.Background()
|
||||
if _, err := client.Create(ctx, obj, metav1.CreateOptions{}); err != nil {
|
||||
lastError = err
|
||||
if apierrors.IsAlreadyExists(err) {
|
||||
lastError = mutateConfigMap(client, metav1.ObjectMeta{Namespace: cm.ObjectMeta.Namespace, Name: cm.ObjectMeta.Name}, mutator)
|
||||
lastError = mutate(ctx, client, metav1.ObjectMeta{Namespace: obj.GetNamespace(), Name: obj.GetName()}, mutator)
|
||||
return lastError == nil, nil
|
||||
}
|
||||
return false, nil
|
||||
@ -95,273 +119,138 @@ func CreateOrMutateConfigMap(client clientset.Interface, cm *v1.ConfigMap, mutat
|
||||
return lastError
|
||||
}
|
||||
|
||||
// mutateConfigMap takes a ConfigMap Object Meta (namespace and name), retrieves the resource from the server and tries to mutate it
|
||||
// by calling to the mutator callback, then an Update of the mutated ConfigMap will be performed. This function is resilient
|
||||
// CreateOrMutateConfigMap tries to create the ConfigMap provided as cm. If the resource exists already, the latest version will be fetched from
|
||||
// the cluster and mutator callback will be called on it, then an Update of the mutated ConfigMap will be performed. This function is resilient
|
||||
// to conflicts, and a retry will be issued if the ConfigMap was modified on the server between the refresh and the update (while the mutation was
|
||||
// taking place).
|
||||
func mutateConfigMap(client clientset.Interface, meta metav1.ObjectMeta, mutator ConfigMapMutator) error {
|
||||
ctx := context.Background()
|
||||
configMap, err := client.CoreV1().ConfigMaps(meta.Namespace).Get(ctx, meta.Name, metav1.GetOptions{})
|
||||
//
|
||||
// Deprecated: use CreateOrMutate() instead.
|
||||
func CreateOrMutateConfigMap(client clientset.Interface, cm *v1.ConfigMap, mutator objectMutator[*v1.ConfigMap]) error {
|
||||
return CreateOrMutate(context.Background(), client.CoreV1().ConfigMaps(cm.ObjectMeta.Namespace), cm, mutator)
|
||||
}
|
||||
|
||||
// mutate takes an Object Meta (namespace and name), retrieves the resource from the server and tries to mutate it
|
||||
// by calling to the mutator callback, then an Update of the mutated object will be performed. This function is resilient
|
||||
// to conflicts, and a retry will be issued if the object was modified on the server between the refresh and the update (while the mutation was
|
||||
// taking place).
|
||||
func mutate[T kubernetesObject](ctx context.Context, client kubernetesInterface[T], meta metav1.ObjectMeta, mutator objectMutator[T]) error {
|
||||
obj, err := client.Get(ctx, meta.Name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "unable to get ConfigMap")
|
||||
return errors.Wrapf(err, "unable to get %T", obj)
|
||||
}
|
||||
if err = mutator(configMap); err != nil {
|
||||
return errors.Wrap(err, "unable to mutate ConfigMap")
|
||||
if err = mutator(obj); err != nil {
|
||||
return errors.Wrapf(err, "unable to mutate %T", obj)
|
||||
}
|
||||
_, err = client.CoreV1().ConfigMaps(configMap.ObjectMeta.Namespace).Update(ctx, configMap, metav1.UpdateOptions{})
|
||||
_, err = client.Update(ctx, obj, metav1.UpdateOptions{})
|
||||
return err
|
||||
}
|
||||
|
||||
// CreateOrRetainConfigMap creates a ConfigMap if the target resource doesn't exist. If the resource exists already, this function will retain the resource instead.
|
||||
// CreateOrRetain creates a runtime object if the target resource doesn't exist.
|
||||
// If the resource exists already, this function will retain the resource instead.
|
||||
func CreateOrRetain[T kubernetesObject](ctx context.Context, client kubernetesInterface[T], obj T) error {
|
||||
var lastError error
|
||||
err := wait.PollUntilContextTimeout(ctx,
|
||||
apiCallRetryInterval, kubeadmapi.GetActiveTimeouts().KubernetesAPICall.Duration,
|
||||
true, func(_ context.Context) (bool, error) {
|
||||
// This uses a background context for API calls to avoid confusing callers that don't
|
||||
// expect context-related errors.
|
||||
ctx := context.Background()
|
||||
if _, err := client.Get(ctx, obj.GetName(), metav1.GetOptions{}); err != nil {
|
||||
if !apierrors.IsNotFound(err) {
|
||||
lastError = errors.Wrapf(err, "unable to get %T", obj)
|
||||
return false, nil
|
||||
}
|
||||
if _, err := client.Create(ctx, obj, metav1.CreateOptions{}); err != nil {
|
||||
lastError = errors.Wrapf(err, "unable to create %T", obj)
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
return true, nil
|
||||
})
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
return lastError
|
||||
}
|
||||
|
||||
// CreateOrRetainConfigMap creates a ConfigMap if the target resource doesn't exist.
|
||||
// If the resource exists already, this function will retain the resource instead.
|
||||
//
|
||||
// Deprecated: use CreateOrRetain() instead.
|
||||
func CreateOrRetainConfigMap(client clientset.Interface, cm *v1.ConfigMap, configMapName string) error {
|
||||
var lastError error
|
||||
err := wait.PollUntilContextTimeout(context.Background(),
|
||||
apiCallRetryInterval, kubeadmapi.GetActiveTimeouts().KubernetesAPICall.Duration,
|
||||
true, func(_ context.Context) (bool, error) {
|
||||
ctx := context.Background()
|
||||
if _, err := client.CoreV1().ConfigMaps(cm.ObjectMeta.Namespace).Get(ctx, configMapName, metav1.GetOptions{}); err != nil {
|
||||
if !apierrors.IsNotFound(err) {
|
||||
lastError = errors.Wrap(err, "unable to get ConfigMap")
|
||||
return false, nil
|
||||
}
|
||||
if _, err := client.CoreV1().ConfigMaps(cm.ObjectMeta.Namespace).Create(ctx, cm, metav1.CreateOptions{}); err != nil {
|
||||
lastError = errors.Wrap(err, "unable to create ConfigMap")
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
return true, nil
|
||||
})
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
return lastError
|
||||
return CreateOrRetain(context.Background(), client.CoreV1().ConfigMaps(cm.Namespace), cm)
|
||||
}
|
||||
|
||||
// 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.
|
||||
//
|
||||
// Deprecated: use CreateOrUpdate() instead.
|
||||
func CreateOrUpdateSecret(client clientset.Interface, secret *v1.Secret) error {
|
||||
var lastError error
|
||||
err := wait.PollUntilContextTimeout(context.Background(),
|
||||
apiCallRetryInterval, kubeadmapi.GetActiveTimeouts().KubernetesAPICall.Duration,
|
||||
true, func(_ context.Context) (bool, error) {
|
||||
ctx := context.Background()
|
||||
if _, err := client.CoreV1().Secrets(secret.ObjectMeta.Namespace).Create(ctx, secret, metav1.CreateOptions{}); err != nil {
|
||||
if !apierrors.IsAlreadyExists(err) {
|
||||
lastError = errors.Wrap(err, "unable to create Secret")
|
||||
return false, nil
|
||||
}
|
||||
if _, err := client.CoreV1().Secrets(secret.ObjectMeta.Namespace).Update(ctx, secret, metav1.UpdateOptions{}); err != nil {
|
||||
lastError = errors.Wrap(err, "unable to update Secret")
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
return true, nil
|
||||
})
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
return lastError
|
||||
return CreateOrUpdate(context.Background(), client.CoreV1().Secrets(secret.Namespace), secret)
|
||||
}
|
||||
|
||||
// CreateOrUpdateServiceAccount creates a ServiceAccount if the target resource doesn't exist. If the resource exists already, this function will update the resource instead.
|
||||
// CreateOrUpdateServiceAccount creates a ServiceAccount if the target resource doesn't exist.
|
||||
// If the resource exists already, this function will update the resource instead.
|
||||
//
|
||||
// Deprecated: use CreateOrUpdate() instead.
|
||||
func CreateOrUpdateServiceAccount(client clientset.Interface, sa *v1.ServiceAccount) error {
|
||||
var lastError error
|
||||
err := wait.PollUntilContextTimeout(context.Background(),
|
||||
apiCallRetryInterval, kubeadmapi.GetActiveTimeouts().KubernetesAPICall.Duration,
|
||||
true, func(_ context.Context) (bool, error) {
|
||||
ctx := context.Background()
|
||||
if _, err := client.CoreV1().ServiceAccounts(sa.ObjectMeta.Namespace).Create(ctx, sa, metav1.CreateOptions{}); err != nil {
|
||||
if !apierrors.IsAlreadyExists(err) {
|
||||
lastError = errors.Wrap(err, "unable to create ServicAccount")
|
||||
return false, nil
|
||||
}
|
||||
if _, err := client.CoreV1().ServiceAccounts(sa.ObjectMeta.Namespace).Update(ctx, sa, metav1.UpdateOptions{}); err != nil {
|
||||
lastError = errors.Wrap(err, "unable to update ServicAccount")
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
return true, nil
|
||||
})
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
return lastError
|
||||
return CreateOrUpdate(context.Background(), client.CoreV1().ServiceAccounts(sa.Namespace), sa)
|
||||
}
|
||||
|
||||
// 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.
|
||||
//
|
||||
// Deprecated: use CreateOrUpdate() instead.
|
||||
func CreateOrUpdateDeployment(client clientset.Interface, deploy *apps.Deployment) error {
|
||||
var lastError error
|
||||
err := wait.PollUntilContextTimeout(context.Background(),
|
||||
apiCallRetryInterval, kubeadmapi.GetActiveTimeouts().KubernetesAPICall.Duration,
|
||||
true, func(_ context.Context) (bool, error) {
|
||||
ctx := context.Background()
|
||||
if _, err := client.AppsV1().Deployments(deploy.ObjectMeta.Namespace).Create(ctx, deploy, metav1.CreateOptions{}); err != nil {
|
||||
if !apierrors.IsAlreadyExists(err) {
|
||||
lastError = errors.Wrap(err, "unable to create Deployment")
|
||||
return false, nil
|
||||
}
|
||||
if _, err := client.AppsV1().Deployments(deploy.ObjectMeta.Namespace).Update(ctx, deploy, metav1.UpdateOptions{}); err != nil {
|
||||
lastError = errors.Wrap(err, "unable to update Deployment")
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
return true, nil
|
||||
})
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
return lastError
|
||||
return CreateOrUpdate(context.Background(), client.AppsV1().Deployments(deploy.Namespace), deploy)
|
||||
}
|
||||
|
||||
// CreateOrRetainDeployment creates a Deployment if the target resource doesn't exist. If the resource exists already, this function will retain the resource instead.
|
||||
// CreateOrRetainDeployment creates a Deployment if the target resource doesn't exist.
|
||||
// If the resource exists already, this function will retain the resource instead.
|
||||
//
|
||||
// Deprecated: use CreateOrRetain() instead.
|
||||
func CreateOrRetainDeployment(client clientset.Interface, deploy *apps.Deployment, deployName string) error {
|
||||
var lastError error
|
||||
err := wait.PollUntilContextTimeout(context.Background(),
|
||||
apiCallRetryInterval, kubeadmapi.GetActiveTimeouts().KubernetesAPICall.Duration,
|
||||
true, func(_ context.Context) (bool, error) {
|
||||
ctx := context.Background()
|
||||
if _, err := client.AppsV1().Deployments(deploy.ObjectMeta.Namespace).Get(ctx, deployName, metav1.GetOptions{}); err != nil {
|
||||
if !apierrors.IsNotFound(err) {
|
||||
lastError = errors.Wrap(err, "unable to get Deployment")
|
||||
return false, nil
|
||||
}
|
||||
if _, err := client.AppsV1().Deployments(deploy.ObjectMeta.Namespace).Create(ctx, deploy, metav1.CreateOptions{}); err != nil {
|
||||
if !apierrors.IsAlreadyExists(err) {
|
||||
lastError = errors.Wrap(err, "unable to create Deployment")
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
return true, nil
|
||||
})
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
return lastError
|
||||
return CreateOrRetain(context.Background(), client.AppsV1().Deployments(deploy.Namespace), deploy)
|
||||
}
|
||||
|
||||
// CreateOrUpdateDaemonSet creates a DaemonSet if the target resource doesn't exist. If the resource exists already, this function will update the resource instead.
|
||||
// CreateOrUpdateDaemonSet creates a DaemonSet if the target resource doesn't exist.
|
||||
// If the resource exists already, this function will update the resource instead.
|
||||
//
|
||||
// Deprecated: use CreateOrUpdate() instead.
|
||||
func CreateOrUpdateDaemonSet(client clientset.Interface, ds *apps.DaemonSet) error {
|
||||
var lastError error
|
||||
err := wait.PollUntilContextTimeout(context.Background(),
|
||||
apiCallRetryInterval, kubeadmapi.GetActiveTimeouts().KubernetesAPICall.Duration,
|
||||
true, func(_ context.Context) (bool, error) {
|
||||
ctx := context.Background()
|
||||
if _, err := client.AppsV1().DaemonSets(ds.ObjectMeta.Namespace).Create(ctx, ds, metav1.CreateOptions{}); err != nil {
|
||||
if !apierrors.IsAlreadyExists(err) {
|
||||
lastError = errors.Wrap(err, "unable to create DaemonSet")
|
||||
return false, nil
|
||||
}
|
||||
if _, err := client.AppsV1().DaemonSets(ds.ObjectMeta.Namespace).Update(ctx, ds, metav1.UpdateOptions{}); err != nil {
|
||||
lastError = errors.Wrap(err, "unable to update DaemonSet")
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
return true, nil
|
||||
})
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
return lastError
|
||||
return CreateOrUpdate(context.Background(), client.AppsV1().DaemonSets(ds.Namespace), ds)
|
||||
}
|
||||
|
||||
// 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.
|
||||
//
|
||||
// Deprecated: use CreateOrUpdate() instead.
|
||||
func CreateOrUpdateRole(client clientset.Interface, role *rbac.Role) error {
|
||||
var lastError error
|
||||
err := wait.PollUntilContextTimeout(context.Background(),
|
||||
apiCallRetryInterval, kubeadmapi.GetActiveTimeouts().KubernetesAPICall.Duration,
|
||||
true, func(_ context.Context) (bool, error) {
|
||||
ctx := context.Background()
|
||||
if _, err := client.RbacV1().Roles(role.ObjectMeta.Namespace).Create(ctx, role, metav1.CreateOptions{}); err != nil {
|
||||
if !apierrors.IsAlreadyExists(err) {
|
||||
lastError = errors.Wrap(err, "unable to create Role")
|
||||
return false, nil
|
||||
}
|
||||
if _, err := client.RbacV1().Roles(role.ObjectMeta.Namespace).Update(ctx, role, metav1.UpdateOptions{}); err != nil {
|
||||
lastError = errors.Wrap(err, "unable to update Role")
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
return true, nil
|
||||
})
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
return lastError
|
||||
return CreateOrUpdate(context.Background(), client.RbacV1().Roles(role.Namespace), role)
|
||||
}
|
||||
|
||||
// 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.
|
||||
//
|
||||
// Deprecated: use CreateOrUpdate() instead.
|
||||
func CreateOrUpdateRoleBinding(client clientset.Interface, roleBinding *rbac.RoleBinding) error {
|
||||
var lastError error
|
||||
err := wait.PollUntilContextTimeout(context.Background(),
|
||||
apiCallRetryInterval, kubeadmapi.GetActiveTimeouts().KubernetesAPICall.Duration,
|
||||
true, func(_ context.Context) (bool, error) {
|
||||
ctx := context.Background()
|
||||
if _, err := client.RbacV1().RoleBindings(roleBinding.ObjectMeta.Namespace).Create(ctx, roleBinding, metav1.CreateOptions{}); err != nil {
|
||||
if !apierrors.IsAlreadyExists(err) {
|
||||
lastError = errors.Wrap(err, "unable to create RoleBinding")
|
||||
return false, nil
|
||||
}
|
||||
if _, err := client.RbacV1().RoleBindings(roleBinding.ObjectMeta.Namespace).Update(ctx, roleBinding, metav1.UpdateOptions{}); err != nil {
|
||||
lastError = errors.Wrap(err, "unable to update RoleBinding")
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
return true, nil
|
||||
})
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
return lastError
|
||||
return CreateOrUpdate(context.Background(), client.RbacV1().RoleBindings(roleBinding.Namespace), roleBinding)
|
||||
}
|
||||
|
||||
// CreateOrUpdateClusterRole creates a ClusterRole 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.
|
||||
//
|
||||
// Deprecated: use CreateOrUpdate() instead.
|
||||
func CreateOrUpdateClusterRole(client clientset.Interface, clusterRole *rbac.ClusterRole) error {
|
||||
var lastError error
|
||||
err := wait.PollUntilContextTimeout(context.Background(),
|
||||
apiCallRetryInterval, kubeadmapi.GetActiveTimeouts().KubernetesAPICall.Duration,
|
||||
true, func(_ context.Context) (bool, error) {
|
||||
ctx := context.Background()
|
||||
if _, err := client.RbacV1().ClusterRoles().Create(ctx, clusterRole, metav1.CreateOptions{}); err != nil {
|
||||
if !apierrors.IsAlreadyExists(err) {
|
||||
lastError = errors.Wrap(err, "unable to create ClusterRole")
|
||||
return false, nil
|
||||
}
|
||||
if _, err := client.RbacV1().ClusterRoles().Update(ctx, clusterRole, metav1.UpdateOptions{}); err != nil {
|
||||
lastError = errors.Wrap(err, "unable to update ClusterRole")
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
return true, nil
|
||||
})
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
return lastError
|
||||
return CreateOrUpdate(context.Background(), client.RbacV1().ClusterRoles(), clusterRole)
|
||||
}
|
||||
|
||||
// CreateOrUpdateClusterRoleBinding creates a ClusterRoleBinding if the target resource doesn't exist. If the resource exists already, this function will update the resource instead.
|
||||
// CreateOrUpdateClusterRoleBinding creates a ClusterRoleBinding if the target resource doesn't exist.
|
||||
// If the resource exists already, this function will update the resource instead.
|
||||
//
|
||||
// Deprecated: use CreateOrUpdate() instead.
|
||||
func CreateOrUpdateClusterRoleBinding(client clientset.Interface, clusterRoleBinding *rbac.ClusterRoleBinding) error {
|
||||
var lastError error
|
||||
err := wait.PollUntilContextTimeout(context.Background(),
|
||||
apiCallRetryInterval, kubeadmapi.GetActiveTimeouts().KubernetesAPICall.Duration,
|
||||
true, func(_ context.Context) (bool, error) {
|
||||
ctx := context.Background()
|
||||
if _, err := client.RbacV1().ClusterRoleBindings().Create(ctx, clusterRoleBinding, metav1.CreateOptions{}); err != nil {
|
||||
if !apierrors.IsAlreadyExists(err) {
|
||||
lastError = errors.Wrap(err, "unable to create ClusterRoleBinding")
|
||||
return false, nil
|
||||
}
|
||||
if _, err := client.RbacV1().ClusterRoleBindings().Update(ctx, clusterRoleBinding, metav1.UpdateOptions{}); err != nil {
|
||||
lastError = errors.Wrap(err, "unable to update ClusterRoleBinding")
|
||||
return false, nil
|
||||
}
|
||||
}
|
||||
return true, nil
|
||||
})
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
return lastError
|
||||
return CreateOrUpdate(context.Background(), client.RbacV1().ClusterRoleBindings(), clusterRoleBinding)
|
||||
}
|
||||
|
||||
// PatchNodeOnce executes patchFn on the node object found by the node name.
|
||||
|
@ -18,6 +18,7 @@ package apiclient
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"testing"
|
||||
"time"
|
||||
@ -32,6 +33,7 @@ import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/client-go/kubernetes"
|
||||
clientsetfake "k8s.io/client-go/kubernetes/fake"
|
||||
clientgotesting "k8s.io/client-go/testing"
|
||||
|
||||
@ -56,49 +58,49 @@ func TestMain(m *testing.M) {
|
||||
os.Exit(exitVal)
|
||||
}
|
||||
|
||||
func TestCreateOrUpdateConfigMap(t *testing.T) {
|
||||
func testCreateOrUpdate[T kubernetesObject](t *testing.T, resource, resources string, empty T, clientBuilder func(kubernetes.Interface, T) kubernetesInterface[T]) {
|
||||
tests := []struct {
|
||||
name string
|
||||
setupClient func(*clientsetfake.Clientset)
|
||||
nameFormat string
|
||||
setupClient func(*clientsetfake.Clientset, string)
|
||||
expectedError bool
|
||||
}{
|
||||
{
|
||||
name: "create configmap success",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("create", "configmaps", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
nameFormat: "create %s success",
|
||||
setupClient: func(client *clientsetfake.Clientset, resources string) {
|
||||
client.PrependReactor("create", resources, func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, nil
|
||||
})
|
||||
},
|
||||
expectedError: false,
|
||||
},
|
||||
{
|
||||
name: "create configmap returns error",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("create", "configmaps", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
nameFormat: "create %s returns error",
|
||||
setupClient: func(client *clientsetfake.Clientset, resources string) {
|
||||
client.PrependReactor("create", resources, func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, errors.New("unknown error")
|
||||
})
|
||||
},
|
||||
expectedError: true,
|
||||
},
|
||||
{
|
||||
name: "configmap exists, update it",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("create", "configmaps", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
nameFormat: "%s exists, update it",
|
||||
setupClient: func(client *clientsetfake.Clientset, resources string) {
|
||||
client.PrependReactor("create", resources, func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, apierrors.NewAlreadyExists(schema.GroupResource{}, "name")
|
||||
})
|
||||
client.PrependReactor("update", "configmaps", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
client.PrependReactor("update", resources, func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, nil
|
||||
})
|
||||
},
|
||||
expectedError: false,
|
||||
},
|
||||
{
|
||||
name: "configmap exists, update error",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("create", "configmaps", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
nameFormat: "%s exists, update error",
|
||||
setupClient: func(client *clientsetfake.Clientset, resources string) {
|
||||
client.PrependReactor("create", resources, func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, apierrors.NewAlreadyExists(schema.GroupResource{}, "name")
|
||||
})
|
||||
client.PrependReactor("update", "configmaps", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
client.PrependReactor("update", resources, func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, errors.New("")
|
||||
})
|
||||
},
|
||||
@ -107,10 +109,103 @@ func TestCreateOrUpdateConfigMap(t *testing.T) {
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Run(fmt.Sprintf(tc.nameFormat, resource), func(t *testing.T) {
|
||||
client := clientsetfake.NewSimpleClientset()
|
||||
tc.setupClient(client, resources)
|
||||
err := CreateOrUpdate(context.Background(), clientBuilder(client, empty), empty)
|
||||
if (err != nil) != tc.expectedError {
|
||||
t.Fatalf("expected error: %v, got %v, error: %v", tc.expectedError, err != nil, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateOrUpdateConfigMap(t *testing.T) {
|
||||
testCreateOrUpdate(t, "configmap", "configmaps", &v1.ConfigMap{},
|
||||
func(client kubernetes.Interface, obj *v1.ConfigMap) kubernetesInterface[*v1.ConfigMap] {
|
||||
return client.CoreV1().ConfigMaps(obj.ObjectMeta.Namespace)
|
||||
})
|
||||
}
|
||||
|
||||
func testCreateOrMutate[T kubernetesObject](t *testing.T, resource, resources string, empty T, clientBuilder func(kubernetes.Interface, T) kubernetesInterface[T]) {
|
||||
tests := []struct {
|
||||
nameFormat string
|
||||
setupClient func(*clientsetfake.Clientset)
|
||||
mutator objectMutator[T]
|
||||
expectedError bool
|
||||
}{
|
||||
{
|
||||
nameFormat: "create %s",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("create", resources, func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, nil
|
||||
})
|
||||
client.PrependReactor("get", resources, func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, nil
|
||||
})
|
||||
client.PrependReactor("update", resources, func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, nil
|
||||
})
|
||||
},
|
||||
expectedError: false,
|
||||
},
|
||||
{
|
||||
nameFormat: "create %s error",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("create", resources, func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, errors.New("")
|
||||
})
|
||||
},
|
||||
expectedError: true,
|
||||
},
|
||||
{
|
||||
nameFormat: "%s exists, mutate returns error",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("create", resources, func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, apierrors.NewAlreadyExists(schema.GroupResource{}, "name")
|
||||
})
|
||||
client.PrependReactor("get", resources, func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, empty, nil
|
||||
})
|
||||
},
|
||||
mutator: func(T) error { return errors.New("") },
|
||||
expectedError: true,
|
||||
},
|
||||
{
|
||||
nameFormat: "%s exists, get returns error",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("create", resources, func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, apierrors.NewAlreadyExists(schema.GroupResource{}, "name")
|
||||
})
|
||||
client.PrependReactor("get", resources, func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, errors.New("")
|
||||
})
|
||||
},
|
||||
expectedError: true,
|
||||
},
|
||||
{
|
||||
nameFormat: "%s exists, mutate returns error",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("create", resources, func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, apierrors.NewAlreadyExists(schema.GroupResource{}, "name")
|
||||
})
|
||||
client.PrependReactor("get", resources, func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, empty, nil
|
||||
})
|
||||
client.PrependReactor("update", resources, func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, errors.New("")
|
||||
})
|
||||
},
|
||||
mutator: func(T) error { return nil },
|
||||
expectedError: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(fmt.Sprintf(tc.nameFormat, resource), func(t *testing.T) {
|
||||
client := clientsetfake.NewSimpleClientset()
|
||||
tc.setupClient(client)
|
||||
err := CreateOrUpdateConfigMap(client, &v1.ConfigMap{})
|
||||
err := CreateOrMutate[T](context.Background(), clientBuilder(client, empty), empty, tc.mutator)
|
||||
if (err != nil) != tc.expectedError {
|
||||
t.Fatalf("expected error: %v, got %v, error: %v", tc.expectedError, err != nil, err)
|
||||
}
|
||||
@ -119,84 +214,67 @@ func TestCreateOrUpdateConfigMap(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestCreateOrMutateConfigMap(t *testing.T) {
|
||||
testCreateOrMutate(t, "configmap", "configmaps", &v1.ConfigMap{},
|
||||
func(client kubernetes.Interface, obj *v1.ConfigMap) kubernetesInterface[*v1.ConfigMap] {
|
||||
return client.CoreV1().ConfigMaps(obj.ObjectMeta.Namespace)
|
||||
})
|
||||
}
|
||||
|
||||
func testCreateOrRetain[T kubernetesObject](t *testing.T, resource, resources string, empty T, clientBuilder func(kubernetes.Interface, T) kubernetesInterface[T]) {
|
||||
tests := []struct {
|
||||
name string
|
||||
nameFormat string
|
||||
setupClient func(*clientsetfake.Clientset)
|
||||
mutator func(*v1.ConfigMap) error
|
||||
expectedError bool
|
||||
}{
|
||||
{
|
||||
name: "create configmap",
|
||||
nameFormat: "%s exists",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("create", "configmaps", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, nil
|
||||
client.PrependReactor("get", resources, func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, empty, nil
|
||||
})
|
||||
client.PrependReactor("get", "configmaps", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, nil
|
||||
},
|
||||
expectedError: false,
|
||||
},
|
||||
{
|
||||
nameFormat: "%s get returns an error",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("get", resources, func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, errors.New("")
|
||||
})
|
||||
client.PrependReactor("update", "configmaps", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
},
|
||||
expectedError: true,
|
||||
},
|
||||
{
|
||||
nameFormat: "%s is not found, create it",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("get", resources, func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, apierrors.NewNotFound(schema.GroupResource{}, "name")
|
||||
})
|
||||
client.PrependReactor("create", resources, func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, nil
|
||||
})
|
||||
},
|
||||
expectedError: false,
|
||||
},
|
||||
{
|
||||
name: "create configmap error",
|
||||
nameFormat: "%s is not found, create returns an error",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("create", "configmaps", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
client.PrependReactor("get", resources, func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, apierrors.NewNotFound(schema.GroupResource{}, "name")
|
||||
})
|
||||
client.PrependReactor("create", resources, func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, errors.New("")
|
||||
})
|
||||
},
|
||||
expectedError: true,
|
||||
},
|
||||
{
|
||||
name: "configmap exists, mutate returns error",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("create", "configmaps", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, apierrors.NewAlreadyExists(schema.GroupResource{}, "name")
|
||||
})
|
||||
client.PrependReactor("get", "configmaps", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, &v1.ConfigMap{}, nil
|
||||
})
|
||||
},
|
||||
mutator: func(*v1.ConfigMap) error { return errors.New("") },
|
||||
expectedError: true,
|
||||
},
|
||||
{
|
||||
name: "configmap exists, get returns error",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("create", "configmaps", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, apierrors.NewAlreadyExists(schema.GroupResource{}, "name")
|
||||
})
|
||||
client.PrependReactor("get", "configmaps", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, errors.New("")
|
||||
})
|
||||
},
|
||||
expectedError: true,
|
||||
},
|
||||
{
|
||||
name: "configmap exists, mutate returns error",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("create", "configmaps", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, apierrors.NewAlreadyExists(schema.GroupResource{}, "name")
|
||||
})
|
||||
client.PrependReactor("get", "configmaps", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, &v1.ConfigMap{}, nil
|
||||
})
|
||||
client.PrependReactor("update", "configmaps", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, errors.New("")
|
||||
})
|
||||
},
|
||||
mutator: func(*v1.ConfigMap) error { return nil },
|
||||
expectedError: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
t.Run(fmt.Sprintf(tc.nameFormat, resource), func(t *testing.T) {
|
||||
client := clientsetfake.NewSimpleClientset()
|
||||
tc.setupClient(client)
|
||||
err := CreateOrMutateConfigMap(client, &v1.ConfigMap{}, tc.mutator)
|
||||
err := CreateOrRetain[T](context.Background(), clientBuilder(client, empty), empty)
|
||||
if (err != nil) != tc.expectedError {
|
||||
t.Fatalf("expected error: %v, got %v, error: %v", tc.expectedError, err != nil, err)
|
||||
}
|
||||
@ -205,623 +283,73 @@ func TestCreateOrMutateConfigMap(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestCreateOrRetainConfigMap(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
setupClient func(*clientsetfake.Clientset)
|
||||
expectedError bool
|
||||
}{
|
||||
{
|
||||
name: "configmap exists",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("get", "configmaps", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, &v1.ConfigMap{}, nil
|
||||
})
|
||||
},
|
||||
expectedError: false,
|
||||
},
|
||||
{
|
||||
name: "configmap get returns an error",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("get", "configmaps", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, errors.New("")
|
||||
})
|
||||
},
|
||||
expectedError: true,
|
||||
},
|
||||
{
|
||||
name: "configmap is not found, create it",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("get", "configmaps", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, apierrors.NewNotFound(schema.GroupResource{}, "name")
|
||||
})
|
||||
client.PrependReactor("create", "configmaps", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, nil
|
||||
})
|
||||
},
|
||||
expectedError: false,
|
||||
},
|
||||
{
|
||||
name: "configmap is not found, create returns an error",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("get", "configmaps", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, apierrors.NewNotFound(schema.GroupResource{}, "name")
|
||||
})
|
||||
client.PrependReactor("create", "configmaps", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, errors.New("")
|
||||
})
|
||||
},
|
||||
expectedError: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
client := clientsetfake.NewSimpleClientset()
|
||||
tc.setupClient(client)
|
||||
err := CreateOrRetainConfigMap(client, &v1.ConfigMap{}, "some-cm")
|
||||
if (err != nil) != tc.expectedError {
|
||||
t.Fatalf("expected error: %v, got %v, error: %v", tc.expectedError, err != nil, err)
|
||||
}
|
||||
testCreateOrRetain(t, "configmap", "configmaps", &v1.ConfigMap{},
|
||||
func(client kubernetes.Interface, obj *v1.ConfigMap) kubernetesInterface[*v1.ConfigMap] {
|
||||
return client.CoreV1().ConfigMaps(obj.ObjectMeta.Namespace)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateOrUpdateSecret(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
setupClient func(*clientsetfake.Clientset)
|
||||
expectedError bool
|
||||
}{
|
||||
{
|
||||
name: "create secret success",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("create", "secrets", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, nil
|
||||
})
|
||||
},
|
||||
expectedError: false,
|
||||
},
|
||||
{
|
||||
name: "create secret returns error",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("create", "secrets", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, errors.New("unknown error")
|
||||
})
|
||||
},
|
||||
expectedError: true,
|
||||
},
|
||||
{
|
||||
name: "secret exists, update it",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("create", "secrets", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, apierrors.NewAlreadyExists(schema.GroupResource{}, "name")
|
||||
})
|
||||
client.PrependReactor("update", "secrets", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, nil
|
||||
})
|
||||
},
|
||||
expectedError: false,
|
||||
},
|
||||
{
|
||||
name: "secret exists, update error",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("create", "secrets", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, apierrors.NewAlreadyExists(schema.GroupResource{}, "name")
|
||||
})
|
||||
client.PrependReactor("update", "secrets", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, errors.New("")
|
||||
})
|
||||
},
|
||||
expectedError: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
client := clientsetfake.NewSimpleClientset()
|
||||
tc.setupClient(client)
|
||||
err := CreateOrUpdateSecret(client, &v1.Secret{})
|
||||
if (err != nil) != tc.expectedError {
|
||||
t.Fatalf("expected error: %v, got %v, error: %v", tc.expectedError, err != nil, err)
|
||||
}
|
||||
testCreateOrUpdate(t, "secret", "secrets", &v1.Secret{},
|
||||
func(client kubernetes.Interface, obj *v1.Secret) kubernetesInterface[*v1.Secret] {
|
||||
return client.CoreV1().Secrets(obj.ObjectMeta.Namespace)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateOrUpdateServiceAccount(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
setupClient func(*clientsetfake.Clientset)
|
||||
expectedError bool
|
||||
}{
|
||||
{
|
||||
name: "create serviceaccount success",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("create", "serviceaccounts", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, nil
|
||||
})
|
||||
},
|
||||
expectedError: false,
|
||||
},
|
||||
{
|
||||
name: "create serviceaccount returns error",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("create", "serviceaccounts", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, errors.New("unknown error")
|
||||
})
|
||||
},
|
||||
expectedError: true,
|
||||
},
|
||||
{
|
||||
name: "serviceaccount exists, update it",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("create", "serviceaccounts", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, apierrors.NewAlreadyExists(schema.GroupResource{}, "name")
|
||||
})
|
||||
client.PrependReactor("update", "serviceaccounts", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, nil
|
||||
})
|
||||
},
|
||||
expectedError: false,
|
||||
},
|
||||
{
|
||||
name: "serviceaccount exists, update error",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("create", "serviceaccounts", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, apierrors.NewAlreadyExists(schema.GroupResource{}, "name")
|
||||
})
|
||||
client.PrependReactor("update", "serviceaccounts", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, errors.New("")
|
||||
})
|
||||
},
|
||||
expectedError: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
client := clientsetfake.NewSimpleClientset()
|
||||
tc.setupClient(client)
|
||||
err := CreateOrUpdateServiceAccount(client, &v1.ServiceAccount{})
|
||||
if (err != nil) != tc.expectedError {
|
||||
t.Fatalf("expected error: %v, got %v, error: %v", tc.expectedError, err != nil, err)
|
||||
}
|
||||
testCreateOrUpdate(t, "serviceaccount", "serviceaccounts", &v1.ServiceAccount{},
|
||||
func(client kubernetes.Interface, obj *v1.ServiceAccount) kubernetesInterface[*v1.ServiceAccount] {
|
||||
return client.CoreV1().ServiceAccounts(obj.ObjectMeta.Namespace)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateOrUpdateDeployment(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
setupClient func(*clientsetfake.Clientset)
|
||||
expectedError bool
|
||||
}{
|
||||
{
|
||||
name: "create deployment success",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("create", "deployments", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, nil
|
||||
})
|
||||
},
|
||||
expectedError: false,
|
||||
},
|
||||
{
|
||||
name: "create deployment returns error",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("create", "deployments", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, errors.New("unknown error")
|
||||
})
|
||||
},
|
||||
expectedError: true,
|
||||
},
|
||||
{
|
||||
name: "deployment exists, update it",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("create", "deployments", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, apierrors.NewAlreadyExists(schema.GroupResource{}, "name")
|
||||
})
|
||||
client.PrependReactor("update", "deployments", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, nil
|
||||
})
|
||||
},
|
||||
expectedError: false,
|
||||
},
|
||||
{
|
||||
name: "deployment exists, update error",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("create", "deployments", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, apierrors.NewAlreadyExists(schema.GroupResource{}, "name")
|
||||
})
|
||||
client.PrependReactor("update", "deployments", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, errors.New("")
|
||||
})
|
||||
},
|
||||
expectedError: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
client := clientsetfake.NewSimpleClientset()
|
||||
tc.setupClient(client)
|
||||
err := CreateOrUpdateDeployment(client, &apps.Deployment{})
|
||||
if (err != nil) != tc.expectedError {
|
||||
t.Fatalf("expected error: %v, got %v, error: %v", tc.expectedError, err != nil, err)
|
||||
}
|
||||
testCreateOrUpdate(t, "deployment", "deployments", &apps.Deployment{},
|
||||
func(client kubernetes.Interface, obj *apps.Deployment) kubernetesInterface[*apps.Deployment] {
|
||||
return client.AppsV1().Deployments(obj.ObjectMeta.Namespace)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateOrRetainDeployment(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
setupClient func(*clientsetfake.Clientset)
|
||||
expectedError bool
|
||||
}{
|
||||
{
|
||||
name: "deployment exists",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("get", "deployments", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, &apps.Deployment{}, nil
|
||||
})
|
||||
},
|
||||
expectedError: false,
|
||||
},
|
||||
{
|
||||
name: "deployment get returns an error",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("get", "deployments", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, errors.New("")
|
||||
})
|
||||
},
|
||||
expectedError: true,
|
||||
},
|
||||
{
|
||||
name: "deployment is not found, create it",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("get", "deployments", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, apierrors.NewNotFound(schema.GroupResource{}, "name")
|
||||
})
|
||||
client.PrependReactor("create", "deployments", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, nil
|
||||
})
|
||||
},
|
||||
expectedError: false,
|
||||
},
|
||||
{
|
||||
name: "deployment is not found, create returns an error",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("get", "deployments", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, apierrors.NewNotFound(schema.GroupResource{}, "name")
|
||||
})
|
||||
client.PrependReactor("create", "deployments", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, errors.New("")
|
||||
})
|
||||
},
|
||||
expectedError: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
client := clientsetfake.NewSimpleClientset()
|
||||
tc.setupClient(client)
|
||||
err := CreateOrRetainDeployment(client, &apps.Deployment{}, "some-deployment")
|
||||
if (err != nil) != tc.expectedError {
|
||||
t.Fatalf("expected error: %v, got %v, error: %v", tc.expectedError, err != nil, err)
|
||||
}
|
||||
testCreateOrRetain(t, "deployment", "deployments", &apps.Deployment{},
|
||||
func(client kubernetes.Interface, obj *apps.Deployment) kubernetesInterface[*apps.Deployment] {
|
||||
return client.AppsV1().Deployments(obj.ObjectMeta.Namespace)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateOrUpdateDaemonSet(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
setupClient func(*clientsetfake.Clientset)
|
||||
expectedError bool
|
||||
}{
|
||||
{
|
||||
name: "create daemonset success",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("create", "daemonsets", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, nil
|
||||
})
|
||||
},
|
||||
expectedError: false,
|
||||
},
|
||||
{
|
||||
name: "create daemonset returns error",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("create", "daemonsets", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, errors.New("unknown error")
|
||||
})
|
||||
},
|
||||
expectedError: true,
|
||||
},
|
||||
{
|
||||
name: "daemonset exists, update it",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("create", "daemonsets", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, apierrors.NewAlreadyExists(schema.GroupResource{}, "name")
|
||||
})
|
||||
client.PrependReactor("update", "daemonsets", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, nil
|
||||
})
|
||||
},
|
||||
expectedError: false,
|
||||
},
|
||||
{
|
||||
name: "daemonset exists, update error",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("create", "daemonsets", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, apierrors.NewAlreadyExists(schema.GroupResource{}, "name")
|
||||
})
|
||||
client.PrependReactor("update", "daemonsets", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, errors.New("")
|
||||
})
|
||||
},
|
||||
expectedError: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
client := clientsetfake.NewSimpleClientset()
|
||||
tc.setupClient(client)
|
||||
err := CreateOrUpdateDaemonSet(client, &apps.DaemonSet{})
|
||||
if (err != nil) != tc.expectedError {
|
||||
t.Fatalf("expected error: %v, got %v, error: %v", tc.expectedError, err != nil, err)
|
||||
}
|
||||
testCreateOrUpdate(t, "daemonset", "daemonsets", &apps.DaemonSet{},
|
||||
func(client kubernetes.Interface, obj *apps.DaemonSet) kubernetesInterface[*apps.DaemonSet] {
|
||||
return client.AppsV1().DaemonSets(obj.ObjectMeta.Namespace)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateOrUpdateRole(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
setupClient func(*clientsetfake.Clientset)
|
||||
expectedError bool
|
||||
}{
|
||||
{
|
||||
name: "create role success",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("create", "roles", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, nil
|
||||
})
|
||||
},
|
||||
expectedError: false,
|
||||
},
|
||||
{
|
||||
name: "create role returns error",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("create", "roles", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, errors.New("unknown error")
|
||||
})
|
||||
},
|
||||
expectedError: true,
|
||||
},
|
||||
{
|
||||
name: "role exists, update it",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("create", "roles", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, apierrors.NewAlreadyExists(schema.GroupResource{}, "name")
|
||||
})
|
||||
client.PrependReactor("update", "roles", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, nil
|
||||
})
|
||||
},
|
||||
expectedError: false,
|
||||
},
|
||||
{
|
||||
name: "role exists, update error",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("create", "roles", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, apierrors.NewAlreadyExists(schema.GroupResource{}, "name")
|
||||
})
|
||||
client.PrependReactor("update", "roles", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, errors.New("")
|
||||
})
|
||||
},
|
||||
expectedError: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
client := clientsetfake.NewSimpleClientset()
|
||||
tc.setupClient(client)
|
||||
err := CreateOrUpdateRole(client, &rbac.Role{})
|
||||
if (err != nil) != tc.expectedError {
|
||||
t.Fatalf("expected error: %v, got %v, error: %v", tc.expectedError, err != nil, err)
|
||||
}
|
||||
testCreateOrUpdate(t, "role", "roles", &rbac.Role{},
|
||||
func(client kubernetes.Interface, obj *rbac.Role) kubernetesInterface[*rbac.Role] {
|
||||
return client.RbacV1().Roles(obj.ObjectMeta.Namespace)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateOrUpdateRoleBindings(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
setupClient func(*clientsetfake.Clientset)
|
||||
expectedError bool
|
||||
}{
|
||||
{
|
||||
name: "create rolebinding success",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("create", "rolebindings", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, nil
|
||||
})
|
||||
},
|
||||
expectedError: false,
|
||||
},
|
||||
{
|
||||
name: "create rolebinding returns error",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("create", "rolebindings", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, errors.New("unknown error")
|
||||
})
|
||||
},
|
||||
expectedError: true,
|
||||
},
|
||||
{
|
||||
name: "rolebinding exists, update it",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("create", "rolebindings", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, apierrors.NewAlreadyExists(schema.GroupResource{}, "name")
|
||||
})
|
||||
client.PrependReactor("update", "rolebindings", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, nil
|
||||
})
|
||||
},
|
||||
expectedError: false,
|
||||
},
|
||||
{
|
||||
name: "rolebinding exists, update error",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("create", "rolebindings", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, apierrors.NewAlreadyExists(schema.GroupResource{}, "name")
|
||||
})
|
||||
client.PrependReactor("update", "rolebindings", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, errors.New("")
|
||||
})
|
||||
},
|
||||
expectedError: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
client := clientsetfake.NewSimpleClientset()
|
||||
tc.setupClient(client)
|
||||
err := CreateOrUpdateRoleBinding(client, &rbac.RoleBinding{})
|
||||
if (err != nil) != tc.expectedError {
|
||||
t.Fatalf("expected error: %v, got %v, error: %v", tc.expectedError, err != nil, err)
|
||||
}
|
||||
testCreateOrUpdate(t, "rolebinding", "rolebindings", &rbac.RoleBinding{},
|
||||
func(client kubernetes.Interface, obj *rbac.RoleBinding) kubernetesInterface[*rbac.RoleBinding] {
|
||||
return client.RbacV1().RoleBindings(obj.ObjectMeta.Namespace)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateOrUpdateClusterRole(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
setupClient func(*clientsetfake.Clientset)
|
||||
expectedError bool
|
||||
}{
|
||||
{
|
||||
name: "create clusterrole success",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("create", "clusterroles", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, nil
|
||||
})
|
||||
},
|
||||
expectedError: false,
|
||||
},
|
||||
{
|
||||
name: "create clusterrole returns error",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("create", "clusterroles", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, errors.New("unknown error")
|
||||
})
|
||||
},
|
||||
expectedError: true,
|
||||
},
|
||||
{
|
||||
name: "clusterrole exists, update it",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("create", "clusterroles", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, apierrors.NewAlreadyExists(schema.GroupResource{}, "name")
|
||||
})
|
||||
client.PrependReactor("update", "clusterroles", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, nil
|
||||
})
|
||||
},
|
||||
expectedError: false,
|
||||
},
|
||||
{
|
||||
name: "clusterrole exists, update error",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("create", "clusterroles", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, apierrors.NewAlreadyExists(schema.GroupResource{}, "name")
|
||||
})
|
||||
client.PrependReactor("update", "clusterroles", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, errors.New("")
|
||||
})
|
||||
},
|
||||
expectedError: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
client := clientsetfake.NewSimpleClientset()
|
||||
tc.setupClient(client)
|
||||
err := CreateOrUpdateClusterRole(client, &rbac.ClusterRole{})
|
||||
if (err != nil) != tc.expectedError {
|
||||
t.Fatalf("expected error: %v, got %v, error: %v", tc.expectedError, err != nil, err)
|
||||
}
|
||||
testCreateOrUpdate(t, "clusterrole", "clusterroles", &rbac.ClusterRole{},
|
||||
func(client kubernetes.Interface, obj *rbac.ClusterRole) kubernetesInterface[*rbac.ClusterRole] {
|
||||
return client.RbacV1().ClusterRoles()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateOrUpdateClusterRoleBindings(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
setupClient func(*clientsetfake.Clientset)
|
||||
expectedError bool
|
||||
}{
|
||||
{
|
||||
name: "create clusterrolebinding success",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("create", "clusterrolebindings", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, nil
|
||||
})
|
||||
},
|
||||
expectedError: false,
|
||||
},
|
||||
{
|
||||
name: "create clusterrolebinding returns error",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("create", "clusterrolebindings", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, errors.New("unknown error")
|
||||
})
|
||||
},
|
||||
expectedError: true,
|
||||
},
|
||||
{
|
||||
name: "clusterrolebinding exists, update it",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("create", "clusterrolebindings", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, apierrors.NewAlreadyExists(schema.GroupResource{}, "name")
|
||||
})
|
||||
client.PrependReactor("update", "clusterrolebindings", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, nil
|
||||
})
|
||||
},
|
||||
expectedError: false,
|
||||
},
|
||||
{
|
||||
name: "clusterrolebinding exists, update error",
|
||||
setupClient: func(client *clientsetfake.Clientset) {
|
||||
client.PrependReactor("create", "clusterrolebindings", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, apierrors.NewAlreadyExists(schema.GroupResource{}, "name")
|
||||
})
|
||||
client.PrependReactor("update", "clusterrolebindings", func(clientgotesting.Action) (bool, runtime.Object, error) {
|
||||
return true, nil, errors.New("")
|
||||
})
|
||||
},
|
||||
expectedError: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range tests {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
client := clientsetfake.NewSimpleClientset()
|
||||
tc.setupClient(client)
|
||||
err := CreateOrUpdateClusterRoleBinding(client, &rbac.ClusterRoleBinding{})
|
||||
if (err != nil) != tc.expectedError {
|
||||
t.Fatalf("expected error: %v, got %v, error: %v", tc.expectedError, err != nil, err)
|
||||
}
|
||||
testCreateOrUpdate(t, "clusterrolebinding", "clusterrolebindings", &rbac.ClusterRoleBinding{},
|
||||
func(client kubernetes.Interface, obj *rbac.ClusterRoleBinding) kubernetesInterface[*rbac.ClusterRoleBinding] {
|
||||
return client.RbacV1().ClusterRoleBindings()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestPatchNodeOnce(t *testing.T) {
|
||||
|
Loading…
Reference in New Issue
Block a user