diff --git a/cmd/kubeadm/app/discovery/token/token_test.go b/cmd/kubeadm/app/discovery/token/token_test.go index 2ff433c65c4..908c5716610 100644 --- a/cmd/kubeadm/app/discovery/token/token_test.go +++ b/cmd/kubeadm/app/discovery/token/token_test.go @@ -303,7 +303,7 @@ type fakeConfigMap struct { } func (c *fakeConfigMap) createOrUpdate(client clientset.Interface) error { - return apiclient.CreateOrUpdateConfigMap(client, &v1.ConfigMap{ + return apiclient.CreateOrUpdate(client.CoreV1().ConfigMaps(metav1.NamespacePublic), &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: c.name, Namespace: metav1.NamespacePublic, diff --git a/cmd/kubeadm/app/phases/addons/dns/dns.go b/cmd/kubeadm/app/phases/addons/dns/dns.go index f41cf51002b..c84348fa578 100644 --- a/cmd/kubeadm/app/phases/addons/dns/dns.go +++ b/cmd/kubeadm/app/phases/addons/dns/dns.go @@ -189,9 +189,11 @@ func createCoreDNSAddon(deploymentBytes, serviceBytes, configBytes []byte, clien // Assume that migration is always possible, rely on migrateCoreDNSCorefile() to fail if not. canMigrateCorefile := true + configMapClient := client.CoreV1().ConfigMaps(coreDNSConfigMap.GetNamespace()) + if corefile == "" || migration.Default("", corefile) { // If the Corefile is empty or default, the latest default Corefile will be applied - if err := apiclient.CreateOrUpdateConfigMap(client, coreDNSConfigMap); err != nil { + if err := apiclient.CreateOrUpdate(configMapClient, coreDNSConfigMap); err != nil { return err } } else if corefileMigrationRequired { @@ -201,13 +203,13 @@ func createCoreDNSAddon(deploymentBytes, serviceBytes, configBytes []byte, clien // to ignore preflight check errors. canMigrateCorefile = false klog.Warningf("the CoreDNS Configuration was not migrated: %v. The existing CoreDNS Corefile configuration has been retained.", err) - if err := apiclient.CreateOrRetainConfigMap(client, coreDNSConfigMap, kubeadmconstants.CoreDNSConfigMap); err != nil { + if err := apiclient.CreateOrRetain(configMapClient, coreDNSConfigMap, kubeadmconstants.CoreDNSConfigMap); err != nil { return err } } } else { // If the Corefile is modified and doesn't require any migration, it'll be retained for the benefit of the user - if err := apiclient.CreateOrRetainConfigMap(client, coreDNSConfigMap, kubeadmconstants.CoreDNSConfigMap); err != nil { + if err := apiclient.CreateOrRetain(configMapClient, coreDNSConfigMap, kubeadmconstants.CoreDNSConfigMap); err != nil { return err } } @@ -218,7 +220,7 @@ func createCoreDNSAddon(deploymentBytes, serviceBytes, configBytes []byte, clien } // Create the Clusterroles for CoreDNS or update it in case it already exists - if err := apiclient.CreateOrUpdateClusterRole(client, coreDNSClusterRoles); err != nil { + if err := apiclient.CreateOrUpdate(client.RbacV1().ClusterRoles(), coreDNSClusterRoles); err != nil { return err } @@ -228,7 +230,7 @@ func createCoreDNSAddon(deploymentBytes, serviceBytes, configBytes []byte, clien } // Create the Clusterrolebindings for CoreDNS or update it in case it already exists - if err := apiclient.CreateOrUpdateClusterRoleBinding(client, coreDNSClusterRolesBinding); err != nil { + if err := apiclient.CreateOrUpdate(client.RbacV1().ClusterRoleBindings(), coreDNSClusterRolesBinding); err != nil { return err } @@ -238,7 +240,7 @@ func createCoreDNSAddon(deploymentBytes, serviceBytes, configBytes []byte, clien } // Create the ConfigMap for CoreDNS or update it in case it already exists - if err := apiclient.CreateOrUpdateServiceAccount(client, coreDNSServiceAccount); err != nil { + if err := apiclient.CreateOrUpdate(client.CoreV1().ServiceAccounts(coreDNSServiceAccount.GetNamespace()), coreDNSServiceAccount); err != nil { return err } @@ -248,13 +250,14 @@ func createCoreDNSAddon(deploymentBytes, serviceBytes, configBytes []byte, clien } // Create the deployment for CoreDNS or retain it in case the CoreDNS migration has failed during upgrade + deploymentsClient := client.AppsV1().Deployments(coreDNSDeployment.GetNamespace()) if !canMigrateCorefile { - if err := apiclient.CreateOrRetainDeployment(client, coreDNSDeployment, kubeadmconstants.CoreDNSDeploymentName); err != nil { + if err := apiclient.CreateOrRetain(deploymentsClient, coreDNSDeployment, kubeadmconstants.CoreDNSDeploymentName); err != nil { return err } } else { // Create the Deployment for CoreDNS or update it in case it already exists - if err := apiclient.CreateOrUpdateDeployment(client, coreDNSDeployment); err != nil { + if err := apiclient.CreateOrUpdate(deploymentsClient, coreDNSDeployment); err != nil { return err } } diff --git a/cmd/kubeadm/app/phases/addons/proxy/proxy.go b/cmd/kubeadm/app/phases/addons/proxy/proxy.go index 11aa9e5c1b5..ed50f0167cb 100644 --- a/cmd/kubeadm/app/phases/addons/proxy/proxy.go +++ b/cmd/kubeadm/app/phases/addons/proxy/proxy.go @@ -133,19 +133,19 @@ func printOrCreateKubeProxyObjects(cmByte []byte, dsByte []byte, client clientse // Create the objects if printManifest is false if !printManifest { - if err := apiclient.CreateOrUpdateServiceAccount(client, sa); err != nil { + if err := apiclient.CreateOrUpdate(client.CoreV1().ServiceAccounts(sa.GetNamespace()), sa); err != nil { return errors.Wrap(err, "error when creating kube-proxy service account") } - if err := apiclient.CreateOrUpdateClusterRoleBinding(client, crb); err != nil { + if err := apiclient.CreateOrUpdate(client.RbacV1().ClusterRoleBindings(), crb); err != nil { return err } - if err := apiclient.CreateOrUpdateRole(client, role); err != nil { + if err := apiclient.CreateOrUpdate(client.RbacV1().Roles(role.GetNamespace()), role); err != nil { return err } - if err := apiclient.CreateOrUpdateRoleBinding(client, rb); err != nil { + if err := apiclient.CreateOrUpdate(client.RbacV1().RoleBindings(rb.GetNamespace()), rb); err != nil { return err } @@ -243,7 +243,7 @@ func createKubeProxyConfigMap(cfg *kubeadmapi.ClusterConfiguration, localEndpoin } // Create the ConfigMap for kube-proxy or update it in case it already exists - return []byte(""), apiclient.CreateOrUpdateConfigMap(client, kubeproxyConfigMap) + return []byte(""), apiclient.CreateOrUpdate(client.CoreV1().ConfigMaps(kubeproxyConfigMap.GetNamespace()), kubeproxyConfigMap) } func createKubeProxyAddon(cfg *kubeadmapi.ClusterConfiguration, client clientset.Interface, printManifest bool) ([]byte, error) { @@ -269,5 +269,5 @@ func createKubeProxyAddon(cfg *kubeadmapi.ClusterConfiguration, client clientset *env = append(*env, kubeadmutil.MergeKubeadmEnvVars(kubeadmutil.GetProxyEnvVars(nil))...) // Create the DaemonSet for kube-proxy or update it in case it already exists - return []byte(""), apiclient.CreateOrUpdateDaemonSet(client, kubeproxyDaemonSet) + return []byte(""), apiclient.CreateOrUpdate(client.AppsV1().DaemonSets(kubeproxyDaemonSet.GetNamespace()), kubeproxyDaemonSet) } diff --git a/cmd/kubeadm/app/phases/bootstraptoken/clusterinfo/clusterinfo.go b/cmd/kubeadm/app/phases/bootstraptoken/clusterinfo/clusterinfo.go index fd1097dae7f..143f3dc6ae8 100644 --- a/cmd/kubeadm/app/phases/bootstraptoken/clusterinfo/clusterinfo.go +++ b/cmd/kubeadm/app/phases/bootstraptoken/clusterinfo/clusterinfo.go @@ -69,7 +69,7 @@ func CreateBootstrapConfigMapIfNotExists(client clientset.Interface, kubeconfig // Create or update the ConfigMap in the kube-public namespace klog.V(1).Infoln("[bootstrap-token] creating/updating ConfigMap in kube-public namespace") - return apiclient.CreateOrUpdateConfigMap(client, &v1.ConfigMap{ + return apiclient.CreateOrUpdate(client.CoreV1().ConfigMaps(metav1.NamespacePublic), &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: bootstrapapi.ConfigMapClusterInfo, Namespace: metav1.NamespacePublic, @@ -83,7 +83,7 @@ func CreateBootstrapConfigMapIfNotExists(client clientset.Interface, kubeconfig // CreateClusterInfoRBACRules creates the RBAC rules for exposing the cluster-info ConfigMap in the kube-public namespace to unauthenticated users func CreateClusterInfoRBACRules(client clientset.Interface) error { klog.V(1).Infoln("creating the RBAC rules for exposing the cluster-info ConfigMap in the kube-public namespace") - err := apiclient.CreateOrUpdateRole(client, &rbac.Role{ + err := apiclient.CreateOrUpdate(client.RbacV1().Roles(metav1.NamespacePublic), &rbac.Role{ ObjectMeta: metav1.ObjectMeta{ Name: BootstrapSignerClusterRoleName, Namespace: metav1.NamespacePublic, @@ -101,7 +101,7 @@ func CreateClusterInfoRBACRules(client clientset.Interface) error { return err } - return apiclient.CreateOrUpdateRoleBinding(client, &rbac.RoleBinding{ + return apiclient.CreateOrUpdate(client.RbacV1().RoleBindings(metav1.NamespacePublic), &rbac.RoleBinding{ ObjectMeta: metav1.ObjectMeta{ Name: BootstrapSignerClusterRoleName, Namespace: metav1.NamespacePublic, diff --git a/cmd/kubeadm/app/phases/bootstraptoken/node/tlsbootstrap.go b/cmd/kubeadm/app/phases/bootstraptoken/node/tlsbootstrap.go index 19a3eb63c94..72154c9ecde 100644 --- a/cmd/kubeadm/app/phases/bootstraptoken/node/tlsbootstrap.go +++ b/cmd/kubeadm/app/phases/bootstraptoken/node/tlsbootstrap.go @@ -31,7 +31,7 @@ import ( func AllowBootstrapTokensToPostCSRs(client clientset.Interface) error { fmt.Println("[bootstrap-token] Configured RBAC rules to allow Node Bootstrap tokens to post CSRs in order for nodes to get long term certificate credentials") - return apiclient.CreateOrUpdateClusterRoleBinding(client, &rbac.ClusterRoleBinding{ + return apiclient.CreateOrUpdate(client.RbacV1().ClusterRoleBindings(), &rbac.ClusterRoleBinding{ ObjectMeta: metav1.ObjectMeta{ Name: constants.NodeKubeletBootstrap, }, @@ -53,7 +53,7 @@ func AllowBootstrapTokensToPostCSRs(client clientset.Interface) error { func AllowBootstrapTokensToGetNodes(client clientset.Interface) error { fmt.Println("[bootstrap-token] Configured RBAC rules to allow Node Bootstrap tokens to get nodes") - if err := apiclient.CreateOrUpdateClusterRole(client, &rbac.ClusterRole{ + if err := apiclient.CreateOrUpdate(client.RbacV1().ClusterRoles(), &rbac.ClusterRole{ ObjectMeta: metav1.ObjectMeta{ Name: constants.GetNodesClusterRoleName, }, @@ -68,7 +68,7 @@ func AllowBootstrapTokensToGetNodes(client clientset.Interface) error { return err } - return apiclient.CreateOrUpdateClusterRoleBinding(client, &rbac.ClusterRoleBinding{ + return apiclient.CreateOrUpdate(client.RbacV1().ClusterRoleBindings(), &rbac.ClusterRoleBinding{ ObjectMeta: metav1.ObjectMeta{ Name: constants.GetNodesClusterRoleName, }, @@ -91,7 +91,7 @@ func AutoApproveNodeBootstrapTokens(client clientset.Interface) error { fmt.Println("[bootstrap-token] Configured RBAC rules to allow the csrapprover controller automatically approve CSRs from a Node Bootstrap Token") // Always create this kubeadm-specific binding though - return apiclient.CreateOrUpdateClusterRoleBinding(client, &rbac.ClusterRoleBinding{ + return apiclient.CreateOrUpdate(client.RbacV1().ClusterRoleBindings(), &rbac.ClusterRoleBinding{ ObjectMeta: metav1.ObjectMeta{ Name: constants.NodeAutoApproveBootstrapClusterRoleBinding, }, @@ -113,7 +113,7 @@ func AutoApproveNodeBootstrapTokens(client clientset.Interface) error { func AutoApproveNodeCertificateRotation(client clientset.Interface) error { fmt.Println("[bootstrap-token] Configured RBAC rules to allow certificate rotation for all node client certificates in the cluster") - return apiclient.CreateOrUpdateClusterRoleBinding(client, &rbac.ClusterRoleBinding{ + return apiclient.CreateOrUpdate(client.RbacV1().ClusterRoleBindings(), &rbac.ClusterRoleBinding{ ObjectMeta: metav1.ObjectMeta{ Name: constants.NodeAutoApproveCertificateRotationClusterRoleBinding, }, diff --git a/cmd/kubeadm/app/phases/bootstraptoken/node/token.go b/cmd/kubeadm/app/phases/bootstraptoken/node/token.go index ea3d77e085e..66484c1184e 100644 --- a/cmd/kubeadm/app/phases/bootstraptoken/node/token.go +++ b/cmd/kubeadm/app/phases/bootstraptoken/node/token.go @@ -40,10 +40,12 @@ func CreateNewTokens(client clientset.Interface, tokens []bootstraptokenv1.Boots // UpdateOrCreateTokens attempts to update a token with the given ID, or create if it does not already exist. func UpdateOrCreateTokens(client clientset.Interface, failIfExists bool, tokens []bootstraptokenv1.BootstrapToken) error { + secretsClient := client.CoreV1().Secrets(metav1.NamespaceSystem) + for _, token := range tokens { secretName := bootstraputil.BootstrapTokenSecretName(token.Token.ID) - secret, err := client.CoreV1().Secrets(metav1.NamespaceSystem).Get(context.TODO(), secretName, metav1.GetOptions{}) + secret, err := secretsClient.Get(context.Background(), secretName, metav1.GetOptions{}) if secret != nil && err == nil && failIfExists { return errors.Errorf("a token with id %q already exists", token.Token.ID) } @@ -56,7 +58,7 @@ func UpdateOrCreateTokens(client clientset.Interface, failIfExists bool, tokens kubeadmconstants.KubernetesAPICallRetryInterval, kubeadmapi.GetActiveTimeouts().KubernetesAPICall.Duration, true, func(_ context.Context) (bool, error) { - if err := apiclient.CreateOrUpdateSecret(client, updatedOrNewSecret); err != nil { + if err := apiclient.CreateOrUpdate(secretsClient, updatedOrNewSecret); err != nil { lastError = errors.Wrapf(err, "failed to create or update bootstrap token with name %s", secretName) return false, nil } diff --git a/cmd/kubeadm/app/phases/copycerts/copycerts.go b/cmd/kubeadm/app/phases/copycerts/copycerts.go index 866677c06e1..a62404df589 100644 --- a/cmd/kubeadm/app/phases/copycerts/copycerts.go +++ b/cmd/kubeadm/app/phases/copycerts/copycerts.go @@ -106,7 +106,7 @@ func UploadCerts(client clientset.Interface, cfg *kubeadmapi.InitConfiguration, return err } - err = apiclient.CreateOrUpdateSecret(client, &v1.Secret{ + err = apiclient.CreateOrUpdate(client.CoreV1().Secrets(metav1.NamespaceSystem), &v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: kubeadmconstants.KubeadmCertsSecret, Namespace: metav1.NamespaceSystem, @@ -122,7 +122,7 @@ func UploadCerts(client clientset.Interface, cfg *kubeadmapi.InitConfiguration, } func createRBAC(client clientset.Interface) error { - err := apiclient.CreateOrUpdateRole(client, &rbac.Role{ + err := apiclient.CreateOrUpdate(client.RbacV1().Roles(metav1.NamespaceSystem), &rbac.Role{ ObjectMeta: metav1.ObjectMeta{ Name: kubeadmconstants.KubeadmCertsClusterRoleName, Namespace: metav1.NamespaceSystem, @@ -140,7 +140,7 @@ func createRBAC(client clientset.Interface) error { return err } - return apiclient.CreateOrUpdateRoleBinding(client, &rbac.RoleBinding{ + return apiclient.CreateOrUpdate(client.RbacV1().RoleBindings(metav1.NamespaceSystem), &rbac.RoleBinding{ ObjectMeta: metav1.ObjectMeta{ Name: kubeadmconstants.KubeadmCertsClusterRoleName, Namespace: metav1.NamespaceSystem, diff --git a/cmd/kubeadm/app/phases/kubelet/config.go b/cmd/kubeadm/app/phases/kubelet/config.go index 865acafcda4..5005d443bbf 100644 --- a/cmd/kubeadm/app/phases/kubelet/config.go +++ b/cmd/kubeadm/app/phases/kubelet/config.go @@ -151,7 +151,7 @@ func CreateConfigMap(cfg *kubeadmapi.ClusterConfiguration, client clientset.Inte componentconfigs.SignConfigMap(configMap) } - if err := apiclient.CreateOrUpdateConfigMap(client, configMap); err != nil { + if err := apiclient.CreateOrUpdate(client.CoreV1().ConfigMaps(configMap.GetNamespace()), configMap); err != nil { return err } @@ -163,7 +163,7 @@ func CreateConfigMap(cfg *kubeadmapi.ClusterConfiguration, client clientset.Inte // createConfigMapRBACRules creates the RBAC rules for exposing the base kubelet ConfigMap in the kube-system namespace to unauthenticated users func createConfigMapRBACRules(client clientset.Interface) error { - if err := apiclient.CreateOrUpdateRole(client, &rbac.Role{ + if err := apiclient.CreateOrUpdate(client.RbacV1().Roles(metav1.NamespaceSystem), &rbac.Role{ ObjectMeta: metav1.ObjectMeta{ Name: kubeadmconstants.KubeletBaseConfigMapRole, Namespace: metav1.NamespaceSystem, @@ -180,7 +180,7 @@ func createConfigMapRBACRules(client clientset.Interface) error { return err } - return apiclient.CreateOrUpdateRoleBinding(client, &rbac.RoleBinding{ + return apiclient.CreateOrUpdate(client.RbacV1().RoleBindings(metav1.NamespaceSystem), &rbac.RoleBinding{ ObjectMeta: metav1.ObjectMeta{ Name: kubeadmconstants.KubeletBaseConfigMapRole, Namespace: metav1.NamespaceSystem, diff --git a/cmd/kubeadm/app/phases/uploadconfig/uploadconfig.go b/cmd/kubeadm/app/phases/uploadconfig/uploadconfig.go index 9a430753388..25e4f22017b 100644 --- a/cmd/kubeadm/app/phases/uploadconfig/uploadconfig.go +++ b/cmd/kubeadm/app/phases/uploadconfig/uploadconfig.go @@ -59,7 +59,7 @@ func UploadConfiguration(cfg *kubeadmapi.InitConfiguration, client clientset.Int return err } - err = apiclient.CreateOrMutateConfigMap(client, &v1.ConfigMap{ + err = apiclient.CreateOrMutate(client.CoreV1().ConfigMaps(metav1.NamespaceSystem), &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: kubeadmconstants.KubeadmConfigConfigMap, Namespace: metav1.NamespaceSystem, @@ -78,7 +78,7 @@ func UploadConfiguration(cfg *kubeadmapi.InitConfiguration, client clientset.Int } // Ensure that the NodesKubeadmConfigClusterRoleName exists - err = apiclient.CreateOrUpdateRole(client, &rbac.Role{ + err = apiclient.CreateOrUpdate(client.RbacV1().Roles(metav1.NamespaceSystem), &rbac.Role{ ObjectMeta: metav1.ObjectMeta{ Name: NodesKubeadmConfigClusterRoleName, Namespace: metav1.NamespaceSystem, @@ -99,7 +99,7 @@ func UploadConfiguration(cfg *kubeadmapi.InitConfiguration, client clientset.Int // Binds the NodesKubeadmConfigClusterRoleName to all the bootstrap tokens // that are members of the system:bootstrappers:kubeadm:default-node-token group // and to all nodes - return apiclient.CreateOrUpdateRoleBinding(client, &rbac.RoleBinding{ + return apiclient.CreateOrUpdate(client.RbacV1().RoleBindings(metav1.NamespaceSystem), &rbac.RoleBinding{ ObjectMeta: metav1.ObjectMeta{ Name: NodesKubeadmConfigClusterRoleName, Namespace: metav1.NamespaceSystem, diff --git a/cmd/kubeadm/app/util/apiclient/idempotency.go b/cmd/kubeadm/app/util/apiclient/idempotency.go index cf4d218239d..e524e47c416 100644 --- a/cmd/kubeadm/app/util/apiclient/idempotency.go +++ b/cmd/kubeadm/app/util/apiclient/idempotency.go @@ -23,9 +23,7 @@ import ( "github.com/pkg/errors" - apps "k8s.io/api/apps/v1" v1 "k8s.io/api/core/v1" - 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" @@ -57,9 +55,9 @@ type kubernetesObject interface { // 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 { +func CreateOrUpdate[T kubernetesObject](client kubernetesInterface[T], obj T) error { var lastError error - err := wait.PollUntilContextTimeout(ctx, + err := wait.PollUntilContextTimeout(context.Background(), 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 @@ -83,21 +81,13 @@ func CreateOrUpdate[T kubernetesObject](ctx context.Context, client kubernetesIn return lastError } -// 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 { +func CreateOrMutate[T kubernetesObject](client kubernetesInterface[T], obj T, mutator objectMutator[T]) error { var lastError error - err := wait.PollUntilContextTimeout(ctx, + err := wait.PollUntilContextTimeout(context.Background(), 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 @@ -119,16 +109,6 @@ func CreateOrMutate[T kubernetesObject](ctx context.Context, client kubernetesIn 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). -// -// 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 @@ -147,15 +127,15 @@ func mutate[T kubernetesObject](ctx context.Context, client kubernetesInterface[ // 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 { +func CreateOrRetain[T kubernetesObject](client kubernetesInterface[T], obj T, name string) error { var lastError error - err := wait.PollUntilContextTimeout(ctx, + err := wait.PollUntilContextTimeout(context.Background(), 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 _, err := client.Get(ctx, name, metav1.GetOptions{}); err != nil { if !apierrors.IsNotFound(err) { lastError = errors.Wrapf(err, "unable to get %T", obj) return false, nil @@ -173,86 +153,6 @@ func CreateOrRetain[T kubernetesObject](ctx context.Context, client kubernetesIn 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 { - 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. -// -// Deprecated: use CreateOrUpdate() instead. -func CreateOrUpdateSecret(client clientset.Interface, secret *v1.Secret) error { - 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. -// -// Deprecated: use CreateOrUpdate() instead. -func CreateOrUpdateServiceAccount(client clientset.Interface, sa *v1.ServiceAccount) error { - 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. -// -// Deprecated: use CreateOrUpdate() instead. -func CreateOrUpdateDeployment(client clientset.Interface, deploy *apps.Deployment) error { - 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. -// -// Deprecated: use CreateOrRetain() instead. -func CreateOrRetainDeployment(client clientset.Interface, deploy *apps.Deployment, deployName string) error { - 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. -// -// Deprecated: use CreateOrUpdate() instead. -func CreateOrUpdateDaemonSet(client clientset.Interface, ds *apps.DaemonSet) error { - 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. -// -// Deprecated: use CreateOrUpdate() instead. -func CreateOrUpdateRole(client clientset.Interface, role *rbac.Role) error { - 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. -// -// Deprecated: use CreateOrUpdate() instead. -func CreateOrUpdateRoleBinding(client clientset.Interface, roleBinding *rbac.RoleBinding) error { - 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. -// -// Deprecated: use CreateOrUpdate() instead. -func CreateOrUpdateClusterRole(client clientset.Interface, clusterRole *rbac.ClusterRole) error { - 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. -// -// Deprecated: use CreateOrUpdate() instead. -func CreateOrUpdateClusterRoleBinding(client clientset.Interface, clusterRoleBinding *rbac.ClusterRoleBinding) error { - return CreateOrUpdate(context.Background(), client.RbacV1().ClusterRoleBindings(), clusterRoleBinding) -} - // PatchNodeOnce executes patchFn on the node object found by the node name. func PatchNodeOnce(client clientset.Interface, nodeName string, patchFn func(*v1.Node), lastError *error) func(context.Context) (bool, error) { return func(_ context.Context) (bool, error) { diff --git a/cmd/kubeadm/app/util/apiclient/idempotency_test.go b/cmd/kubeadm/app/util/apiclient/idempotency_test.go index c2e7c0d94a3..ec0caf78465 100644 --- a/cmd/kubeadm/app/util/apiclient/idempotency_test.go +++ b/cmd/kubeadm/app/util/apiclient/idempotency_test.go @@ -112,7 +112,7 @@ func testCreateOrUpdate[T kubernetesObject](t *testing.T, resource, resources st 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) + err := CreateOrUpdate(clientBuilder(client, empty), empty) if (err != nil) != tc.expectedError { t.Fatalf("expected error: %v, got %v, error: %v", tc.expectedError, err != nil, err) } @@ -205,7 +205,7 @@ func testCreateOrMutate[T kubernetesObject](t *testing.T, resource, resources st t.Run(fmt.Sprintf(tc.nameFormat, resource), func(t *testing.T) { client := clientsetfake.NewSimpleClientset() tc.setupClient(client) - err := CreateOrMutate[T](context.Background(), clientBuilder(client, empty), empty, tc.mutator) + err := CreateOrMutate[T](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) } @@ -274,7 +274,7 @@ func testCreateOrRetain[T kubernetesObject](t *testing.T, resource, resources st t.Run(fmt.Sprintf(tc.nameFormat, resource), func(t *testing.T) { client := clientsetfake.NewSimpleClientset() tc.setupClient(client) - err := CreateOrRetain[T](context.Background(), clientBuilder(client, empty), empty) + err := CreateOrRetain[T](clientBuilder(client, empty), empty, resource) if (err != nil) != tc.expectedError { t.Fatalf("expected error: %v, got %v, error: %v", tc.expectedError, err != nil, err) } diff --git a/cmd/kubeadm/test/resources/configmap.go b/cmd/kubeadm/test/resources/configmap.go index 00799cb32f0..33a2b6e9cf4 100644 --- a/cmd/kubeadm/test/resources/configmap.go +++ b/cmd/kubeadm/test/resources/configmap.go @@ -32,7 +32,7 @@ type FakeConfigMap struct { // Create creates a fake configmap using the provided client func (c *FakeConfigMap) Create(client clientset.Interface) error { - return apiclient.CreateOrUpdateConfigMap(client, &v1.ConfigMap{ + return apiclient.CreateOrUpdate(client.CoreV1().ConfigMaps(metav1.NamespaceSystem), &v1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ Name: c.Name, Namespace: metav1.NamespaceSystem,