mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-10 20:42:26 +00:00
kubeadm: generalise CreateOrUpdate etc.
This uses generics to generalise the various CreateOrUpdate, CreateOrRetain etc. functions. Where appropriate, the context is added as an initial argument to the new functions. ConfigMapMutator isn't used anywhere else, so it's dropped in favour of the private objectMutator added in this commit. Signed-off-by: Stephen Kitt <skitt@redhat.com>
This commit is contained in:
parent
4a0b0365ef
commit
db4c509e71
@ -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