diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index e195254..e70f175 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -21,10 +21,10 @@ jobs: go-version-file: go.mod - name: golangci-lint - uses: golangci/golangci-lint-action@v6 + uses: golangci/golangci-lint-action@v8 with: args: --timeout=5m - version: v1.64 + version: v2.3.0 validate: runs-on: ubuntu-latest diff --git a/.golangci.yml b/.golangci.yml index 4590817..2da35ec 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,13 +1,6 @@ +version: "2" + linters: enable: - # default linters - - errcheck - - gosimple - - govet - - ineffassign - - staticcheck - - unused - - # extra - - misspell - - wsl + - misspell + - wsl_v5 diff --git a/Makefile b/Makefile index dde544a..f8fb083 100644 --- a/Makefile +++ b/Makefile @@ -4,14 +4,14 @@ VERSION ?= $(shell git describe --tags --always --dirty --match="v[0-9]*") ## Dependencies -GOLANGCI_LINT_VERSION := v1.64.8 +GOLANGCI_LINT_VERSION := v2.3.0 GINKGO_VERSION ?= v2.21.0 GINKGO_FLAGS ?= -v -r --coverprofile=cover.out --coverpkg=./... ENVTEST_VERSION ?= v0.0.0-20250505003155-b6c5897febe5 ENVTEST_K8S_VERSION := 1.31.0 CRD_REF_DOCS_VER ?= v0.1.0 -GOLANGCI_LINT ?= go run github.com/golangci/golangci-lint/cmd/golangci-lint@$(GOLANGCI_LINT_VERSION) +GOLANGCI_LINT ?= go run github.com/golangci/golangci-lint/v2/cmd/golangci-lint@$(GOLANGCI_LINT_VERSION) GINKGO ?= go run github.com/onsi/ginkgo/v2/ginkgo@$(GINKGO_VERSION) CRD_REF_DOCS := go run github.com/elastic/crd-ref-docs@$(CRD_REF_DOCS_VER) diff --git a/cli/cmds/cluster_create.go b/cli/cmds/cluster_create.go index e7f5aad..b98c5b9 100644 --- a/cli/cmds/cluster_create.go +++ b/cli/cmds/cluster_create.go @@ -23,7 +23,6 @@ import ( "k8s.io/client-go/util/retry" "k8s.io/utils/ptr" "sigs.k8s.io/controller-runtime/pkg/client" - ctrl "sigs.k8s.io/controller-runtime/pkg/client" ) type CreateConfig struct { @@ -90,7 +89,7 @@ func createAction(appCtx *AppContext, config *CreateConfig) cli.ActionFunc { if strings.Contains(config.version, "+") { orig := config.version - config.version = strings.Replace(config.version, "+", "-", -1) + config.version = strings.ReplaceAll(config.version, "+", "-") logrus.Warnf("Invalid K3s docker reference version: '%s'. Using '%s' instead", orig, config.version) } @@ -256,13 +255,13 @@ func env(envSlice []string) []v1.EnvVar { return envVars } -func waitForCluster(ctx context.Context, client client.Client, cluster *v1alpha1.Cluster) error { +func waitForCluster(ctx context.Context, k8sClient client.Client, cluster *v1alpha1.Cluster) error { interval := 5 * time.Second timeout := 2 * time.Minute return wait.PollUntilContextTimeout(ctx, interval, timeout, true, func(ctx context.Context) (bool, error) { - key := ctrl.ObjectKeyFromObject(cluster) - if err := client.Get(ctx, key, cluster); err != nil { + key := client.ObjectKeyFromObject(cluster) + if err := k8sClient.Get(ctx, key, cluster); err != nil { return false, fmt.Errorf("failed to get resource: %w", err) } @@ -281,7 +280,7 @@ func waitForCluster(ctx context.Context, client client.Client, cluster *v1alpha1 }) } -func CreateCustomCertsSecrets(ctx context.Context, name, namespace, customCertsPath string, client client.Client) error { +func CreateCustomCertsSecrets(ctx context.Context, name, namespace, customCertsPath string, k8sclient client.Client) error { customCAsMap := map[string]string{ "etcd-peer-ca": "/etcd/peer-ca", "etcd-server-ca": "/etcd/server-ca", @@ -316,8 +315,8 @@ func CreateCustomCertsSecrets(ctx context.Context, name, namespace, customCertsP certSecret := caCertSecret(certName, name, namespace, cert, key) - if err := client.Create(ctx, certSecret); err != nil { - return ctrl.IgnoreAlreadyExists(err) + if err := k8sclient.Create(ctx, certSecret); err != nil { + return client.IgnoreAlreadyExists(err) } } diff --git a/k3k-kubelet/controller/configmap.go b/k3k-kubelet/controller/configmap.go index b3167e0..78ff500 100644 --- a/k3k-kubelet/controller/configmap.go +++ b/k3k-kubelet/controller/configmap.go @@ -125,6 +125,7 @@ func (c *ConfigMapSyncer) AddResource(ctx context.Context, namespace, name strin // lock in write mode since we are now adding the key c.mutex.Lock() + if c.objs == nil { c.objs = sets.Set[types.NamespacedName]{} } @@ -135,7 +136,6 @@ func (c *ConfigMapSyncer) AddResource(ctx context.Context, namespace, name strin _, err := c.Reconcile(ctx, reconcile.Request{ NamespacedName: objKey, }) - if err != nil { return fmt.Errorf("unable to reconcile new object %s/%s: %w", objKey.Namespace, objKey.Name, err) } @@ -164,6 +164,7 @@ func (c *ConfigMapSyncer) RemoveResource(ctx context.Context, namespace, name st } c.mutex.Lock() + if c.objs == nil { c.objs = sets.Set[types.NamespacedName]{} } diff --git a/k3k-kubelet/controller/handler.go b/k3k-kubelet/controller/handler.go index 6adb776..4a9c3a2 100644 --- a/k3k-kubelet/controller/handler.go +++ b/k3k-kubelet/controller/handler.go @@ -51,6 +51,7 @@ func (c *ControllerHandler) AddResource(ctx context.Context, obj client.Object) if controllers != nil { if r, ok := c.controllers[obj.GetObjectKind().GroupVersionKind()]; ok { err := r.AddResource(ctx, obj.GetNamespace(), obj.GetName()) + c.RUnlock() return err @@ -103,12 +104,12 @@ func (c *ControllerHandler) AddResource(ctx context.Context, obj client.Object) Named(r.Name()). For(&v1.ConfigMap{}). Complete(r) - if err != nil { return fmt.Errorf("unable to start configmap controller: %w", err) } c.Lock() + if c.controllers == nil { c.controllers = map[schema.GroupVersionKind]updateableReconciler{} } diff --git a/k3k-kubelet/controller/priority_class_test.go b/k3k-kubelet/controller/priority_class_test.go index 40f7668..461567d 100644 --- a/k3k-kubelet/controller/priority_class_test.go +++ b/k3k-kubelet/controller/priority_class_test.go @@ -90,7 +90,7 @@ var PriorityClassTests = func() { Expect(hostPriorityClass.Value).To(Equal(priorityClass.Value)) Expect(hostPriorityClass.Labels).To(ContainElement("bar")) - fmt.Fprintf(GinkgoWriter, "labels: %v\n", hostPriorityClass.Labels) + GinkgoWriter.Printf("labels: %v\n", hostPriorityClass.Labels) }) It("updates a priorityClass on the host cluster", func() { diff --git a/k3k-kubelet/controller/secret.go b/k3k-kubelet/controller/secret.go index e3a4c9f..52ccccc 100644 --- a/k3k-kubelet/controller/secret.go +++ b/k3k-kubelet/controller/secret.go @@ -117,12 +117,15 @@ func (s *SecretSyncer) AddResource(ctx context.Context, namespace, name string) Namespace: namespace, Name: name, } + // if we already sync this object, no need to writelock/add it if s.isWatching(objKey) { return nil } + // lock in write mode since we are now adding the key s.mutex.Lock() + if s.objs == nil { s.objs = sets.Set[types.NamespacedName]{} } @@ -133,7 +136,6 @@ func (s *SecretSyncer) AddResource(ctx context.Context, namespace, name string) _, err := s.Reconcile(ctx, reconcile.Request{ NamespacedName: objKey, }) - if err != nil { return fmt.Errorf("unable to reconcile new object %s/%s: %w", objKey.Namespace, objKey.Name, err) } @@ -162,6 +164,7 @@ func (s *SecretSyncer) RemoveResource(ctx context.Context, namespace, name strin } s.mutex.Lock() + if s.objs == nil { s.objs = sets.Set[types.NamespacedName]{} } @@ -174,11 +177,11 @@ func (s *SecretSyncer) RemoveResource(ctx context.Context, namespace, name strin func (s *SecretSyncer) removeHostSecret(ctx context.Context, virtualNamespace, virtualName string) error { var vSecret corev1.Secret + err := s.VirtualClient.Get(ctx, types.NamespacedName{ Namespace: virtualNamespace, Name: virtualName, }, &vSecret) - if err != nil { return fmt.Errorf("unable to get virtual secret %s/%s: %w", virtualNamespace, virtualName, err) } diff --git a/k3k-kubelet/kubelet.go b/k3k-kubelet/kubelet.go index 05830db..8b6a53f 100644 --- a/k3k-kubelet/kubelet.go +++ b/k3k-kubelet/kubelet.go @@ -144,7 +144,6 @@ func newKubelet(ctx context.Context, c *config, logger *k3klog.Logger) (*kubelet BindAddress: virtualMetricsBindAddress, }, }) - if err != nil { return nil, errors.New("unable to create controller-runtime mgr for virtual cluster: " + err.Error()) } @@ -351,7 +350,6 @@ func virtRestConfig(ctx context.Context, virtualConfigPath string, hostClient ct b.ClientCA.Content, b.ClientCAKey.Content, ) - if err != nil { return nil, err } diff --git a/k3k-kubelet/provider/collectors/kubelet_resource_metrics.go b/k3k-kubelet/provider/collectors/kubelet_resource_metrics.go index e4ef960..2ac5fba 100644 --- a/k3k-kubelet/provider/collectors/kubelet_resource_metrics.go +++ b/k3k-kubelet/provider/collectors/kubelet_resource_metrics.go @@ -91,14 +91,20 @@ var _ compbasemetrics.StableCollector = &resourceMetricsCollector{} // DescribeWithStability implements compbasemetrics.StableCollector func (rc *resourceMetricsCollector) DescribeWithStability(ch chan<- *compbasemetrics.Desc) { - ch <- nodeCPUUsageDesc - ch <- nodeMemoryUsageDesc - ch <- containerStartTimeDesc - ch <- containerCPUUsageDesc - ch <- containerMemoryUsageDesc - ch <- podCPUUsageDesc - ch <- podMemoryUsageDesc - ch <- resourceScrapeResultDesc + descs := []*compbasemetrics.Desc{ + nodeCPUUsageDesc, + nodeMemoryUsageDesc, + containerStartTimeDesc, + containerCPUUsageDesc, + containerMemoryUsageDesc, + podCPUUsageDesc, + podMemoryUsageDesc, + resourceScrapeResultDesc, + } + + for _, desc := range descs { + ch <- desc + } } // CollectWithStability implements compbasemetrics.StableCollector diff --git a/k3k-kubelet/provider/configure.go b/k3k-kubelet/provider/configure.go index c12121c..cad5f4d 100644 --- a/k3k-kubelet/provider/configure.go +++ b/k3k-kubelet/provider/configure.go @@ -7,7 +7,6 @@ import ( "github.com/rancher/k3k/pkg/apis/k3k.io/v1alpha1" k3klog "github.com/rancher/k3k/pkg/log" corev1 "k8s.io/api/core/v1" - v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/apimachinery/pkg/types" @@ -15,7 +14,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" ) -func ConfigureNode(logger *k3klog.Logger, node *v1.Node, hostname string, servicePort int, ip string, coreClient typedv1.CoreV1Interface, virtualClient client.Client, virtualCluster v1alpha1.Cluster, version string, mirrorHostNodes bool) { +func ConfigureNode(logger *k3klog.Logger, node *corev1.Node, hostname string, servicePort int, ip string, coreClient typedv1.CoreV1Interface, virtualClient client.Client, virtualCluster v1alpha1.Cluster, version string, mirrorHostNodes bool) { ctx := context.Background() if mirrorHostNodes { hostNode, err := coreClient.Nodes().Get(ctx, node.Name, metav1.GetOptions{}) @@ -32,13 +31,13 @@ func ConfigureNode(logger *k3klog.Logger, node *v1.Node, hostname string, servic } else { node.Status.Conditions = nodeConditions() node.Status.DaemonEndpoints.KubeletEndpoint.Port = int32(servicePort) - node.Status.Addresses = []v1.NodeAddress{ + node.Status.Addresses = []corev1.NodeAddress{ { - Type: v1.NodeHostName, + Type: corev1.NodeHostName, Address: hostname, }, { - Type: v1.NodeInternalIP, + Type: corev1.NodeInternalIP, Address: ip, }, } @@ -63,11 +62,11 @@ func ConfigureNode(logger *k3klog.Logger, node *v1.Node, hostname string, servic } // nodeConditions returns the basic conditions which mark the node as ready -func nodeConditions() []v1.NodeCondition { - return []v1.NodeCondition{ +func nodeConditions() []corev1.NodeCondition { + return []corev1.NodeCondition{ { Type: "Ready", - Status: v1.ConditionTrue, + Status: corev1.ConditionTrue, LastHeartbeatTime: metav1.Now(), LastTransitionTime: metav1.Now(), Reason: "KubeletReady", @@ -75,7 +74,7 @@ func nodeConditions() []v1.NodeCondition { }, { Type: "OutOfDisk", - Status: v1.ConditionFalse, + Status: corev1.ConditionFalse, LastHeartbeatTime: metav1.Now(), LastTransitionTime: metav1.Now(), Reason: "KubeletHasSufficientDisk", @@ -83,7 +82,7 @@ func nodeConditions() []v1.NodeCondition { }, { Type: "MemoryPressure", - Status: v1.ConditionFalse, + Status: corev1.ConditionFalse, LastHeartbeatTime: metav1.Now(), LastTransitionTime: metav1.Now(), Reason: "KubeletHasSufficientMemory", @@ -91,7 +90,7 @@ func nodeConditions() []v1.NodeCondition { }, { Type: "DiskPressure", - Status: v1.ConditionFalse, + Status: corev1.ConditionFalse, LastHeartbeatTime: metav1.Now(), LastTransitionTime: metav1.Now(), Reason: "KubeletHasNoDiskPressure", @@ -99,7 +98,7 @@ func nodeConditions() []v1.NodeCondition { }, { Type: "NetworkUnavailable", - Status: v1.ConditionFalse, + Status: corev1.ConditionFalse, LastHeartbeatTime: metav1.Now(), LastTransitionTime: metav1.Now(), Reason: "RouteCreated", @@ -129,7 +128,7 @@ func updateNodeCapacity(ctx context.Context, coreClient typedv1.CoreV1Interface, // getResourcesFromNodes will return a sum of all the resource capacity of the host nodes, and the allocatable resources. // If some node labels are specified only the matching nodes will be considered. -func getResourcesFromNodes(ctx context.Context, coreClient typedv1.CoreV1Interface, nodeLabels map[string]string) (v1.ResourceList, v1.ResourceList, error) { +func getResourcesFromNodes(ctx context.Context, coreClient typedv1.CoreV1Interface, nodeLabels map[string]string) (corev1.ResourceList, corev1.ResourceList, error) { listOpts := metav1.ListOptions{} if nodeLabels != nil { diff --git a/k3k-kubelet/provider/provider.go b/k3k-kubelet/provider/provider.go index 3fe68c8..186adce 100644 --- a/k3k-kubelet/provider/provider.go +++ b/k3k-kubelet/provider/provider.go @@ -23,7 +23,6 @@ import ( "github.com/virtual-kubelet/virtual-kubelet/node/api" "github.com/virtual-kubelet/virtual-kubelet/node/nodeutil" corev1 "k8s.io/api/core/v1" - v1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" @@ -213,7 +212,7 @@ func (p *Provider) AttachToContainer(ctx context.Context, namespace, podName, co func (p *Provider) GetStatsSummary(ctx context.Context) (*stats.Summary, error) { p.logger.Debug("GetStatsSummary") - nodeList := &v1.NodeList{} + nodeList := &corev1.NodeList{} if err := p.CoreClient.RESTClient().Get().Resource("nodes").Do(ctx).Into(nodeList); err != nil { return nil, fmt.Errorf("unable to get nodes of cluster %s in namespace %s: %w", p.ClusterName, p.ClusterNamespace, err) } @@ -256,7 +255,7 @@ func (p *Provider) GetStatsSummary(ctx context.Context) (*stats.Summary, error) return nil, err } - podsNameMap := make(map[string]*v1.Pod) + podsNameMap := make(map[string]*corev1.Pod) for _, pod := range pods { hostPodName := p.Translator.TranslateName(pod.Namespace, pod.Name) @@ -329,7 +328,6 @@ func (p *Provider) PortForward(ctx context.Context, namespace, pod string, port // should send a value on stopChannel so that the PortForward is stopped. However, we only have a ReadWriteCloser // so more work is needed to detect a close and handle that appropriately. fw, err := portforward.New(dialer, []string{portAsString}, stopChannel, readyChannel, stream, stream) - if err != nil { return err } @@ -419,7 +417,7 @@ func (p *Provider) createPod(ctx context.Context, pod *corev1.Pod) error { } // withRetry retries passed function with interval and timeout -func (p *Provider) withRetry(ctx context.Context, f func(context.Context, *v1.Pod) error, pod *v1.Pod) error { +func (p *Provider) withRetry(ctx context.Context, f func(context.Context, *corev1.Pod) error, pod *corev1.Pod) error { const ( interval = 2 * time.Second timeout = 10 * time.Second @@ -577,7 +575,7 @@ func (p *Provider) UpdatePod(ctx context.Context, pod *corev1.Pod) error { return p.withRetry(ctx, p.updatePod, pod) } -func (p *Provider) updatePod(ctx context.Context, pod *v1.Pod) error { +func (p *Provider) updatePod(ctx context.Context, pod *corev1.Pod) error { p.logger.Debugw("got a request for update pod") // Once scheduled a Pod cannot update other fields than the image of the containers, initcontainers and a few others @@ -585,7 +583,7 @@ func (p *Provider) updatePod(ctx context.Context, pod *v1.Pod) error { // Update Pod in the virtual cluster - var currentVirtualPod v1.Pod + var currentVirtualPod corev1.Pod if err := p.VirtualClient.Get(ctx, client.ObjectKeyFromObject(pod), ¤tVirtualPod); err != nil { return fmt.Errorf("unable to get pod to update from virtual cluster: %w", err) } @@ -649,7 +647,7 @@ func (p *Provider) updatePod(ctx context.Context, pod *v1.Pod) error { } // updateContainerImages will update the images of the original container images with the same name -func updateContainerImages(original, updated []v1.Container) []v1.Container { +func updateContainerImages(original, updated []corev1.Container) []corev1.Container { newImages := make(map[string]string) for _, c := range updated { @@ -811,8 +809,8 @@ func (p *Provider) GetPods(ctx context.Context) ([]*corev1.Pod, error) { selector = selector.Add(*requirement) var podList corev1.PodList - err = p.HostClient.List(ctx, &podList, &client.ListOptions{LabelSelector: selector}) + err = p.HostClient.List(ctx, &podList, &client.ListOptions{LabelSelector: selector}) if err != nil { return nil, fmt.Errorf("unable to list pods: %w", err) } @@ -855,7 +853,7 @@ func configureNetworking(pod *corev1.Pod, podName, podNamespace, serverIP, dnsIP "svc.cluster.local", "cluster.local", }, - Options: []v1.PodDNSConfigOption{ + Options: []corev1.PodDNSConfigOption{ { Name: "ndots", Value: ptr.To("5"), @@ -938,7 +936,7 @@ func getSecretsAndConfigmaps(pod *corev1.Pod) ([]string, []string) { // configureFieldPathEnv will retrieve all annotations created by the pod mutator webhook // to assign env fieldpaths to pods, it will also make sure to change the metadata.name and metadata.namespace to the // assigned annotations -func (p *Provider) configureFieldPathEnv(pod, tPod *v1.Pod) error { +func (p *Provider) configureFieldPathEnv(pod, tPod *corev1.Pod) error { for _, container := range pod.Spec.EphemeralContainers { addFieldPathAnnotationToEnv(container.Env) } @@ -958,10 +956,10 @@ func (p *Provider) configureFieldPathEnv(pod, tPod *v1.Pod) error { return err } // re-adding these envs to the pod - tPod.Spec.Containers[containerIndex].Env = append(tPod.Spec.Containers[containerIndex].Env, v1.EnvVar{ + tPod.Spec.Containers[containerIndex].Env = append(tPod.Spec.Containers[containerIndex].Env, corev1.EnvVar{ Name: envName, - ValueFrom: &v1.EnvVarSource{ - FieldRef: &v1.ObjectFieldSelector{ + ValueFrom: &corev1.EnvVarSource{ + FieldRef: &corev1.ObjectFieldSelector{ FieldPath: value, }, }, @@ -974,7 +972,7 @@ func (p *Provider) configureFieldPathEnv(pod, tPod *v1.Pod) error { return nil } -func addFieldPathAnnotationToEnv(envVars []v1.EnvVar) { +func addFieldPathAnnotationToEnv(envVars []corev1.EnvVar) { for j, envVar := range envVars { if envVar.ValueFrom == nil || envVar.ValueFrom.FieldRef == nil { continue diff --git a/k3k-kubelet/provider/provider_test.go b/k3k-kubelet/provider/provider_test.go index 051b64a..f7f03dc 100644 --- a/k3k-kubelet/provider/provider_test.go +++ b/k3k-kubelet/provider/provider_test.go @@ -5,7 +5,6 @@ import ( "testing" corev1 "k8s.io/api/core/v1" - v1 "k8s.io/api/core/v1" ) func Test_overrideEnvVars(t *testing.T) { @@ -22,42 +21,42 @@ func Test_overrideEnvVars(t *testing.T) { { name: "orig and new are empty", args: args{ - orig: []v1.EnvVar{}, - new: []v1.EnvVar{}, + orig: []corev1.EnvVar{}, + new: []corev1.EnvVar{}, }, - want: []v1.EnvVar{}, + want: []corev1.EnvVar{}, }, { name: "only orig is empty", args: args{ - orig: []v1.EnvVar{}, - new: []v1.EnvVar{{Name: "FOO", Value: "new_val"}}, + orig: []corev1.EnvVar{}, + new: []corev1.EnvVar{{Name: "FOO", Value: "new_val"}}, }, - want: []v1.EnvVar{}, + want: []corev1.EnvVar{}, }, { name: "orig has a matching element", args: args{ - orig: []v1.EnvVar{{Name: "FOO", Value: "old_val"}}, - new: []v1.EnvVar{{Name: "FOO", Value: "new_val"}}, + orig: []corev1.EnvVar{{Name: "FOO", Value: "old_val"}}, + new: []corev1.EnvVar{{Name: "FOO", Value: "new_val"}}, }, - want: []v1.EnvVar{{Name: "FOO", Value: "new_val"}}, + want: []corev1.EnvVar{{Name: "FOO", Value: "new_val"}}, }, { name: "orig have multiple elements", args: args{ - orig: []v1.EnvVar{{Name: "FOO_0", Value: "old_val_0"}, {Name: "FOO_1", Value: "old_val_1"}}, - new: []v1.EnvVar{{Name: "FOO_1", Value: "new_val_1"}}, + orig: []corev1.EnvVar{{Name: "FOO_0", Value: "old_val_0"}, {Name: "FOO_1", Value: "old_val_1"}}, + new: []corev1.EnvVar{{Name: "FOO_1", Value: "new_val_1"}}, }, - want: []v1.EnvVar{{Name: "FOO_0", Value: "old_val_0"}, {Name: "FOO_1", Value: "new_val_1"}}, + want: []corev1.EnvVar{{Name: "FOO_0", Value: "old_val_0"}, {Name: "FOO_1", Value: "new_val_1"}}, }, { name: "orig and new have multiple elements and some not matching", args: args{ - orig: []v1.EnvVar{{Name: "FOO_0", Value: "old_val_0"}, {Name: "FOO_1", Value: "old_val_1"}}, - new: []v1.EnvVar{{Name: "FOO_1", Value: "new_val_1"}, {Name: "FOO_2", Value: "val_1"}}, + orig: []corev1.EnvVar{{Name: "FOO_0", Value: "old_val_0"}, {Name: "FOO_1", Value: "old_val_1"}}, + new: []corev1.EnvVar{{Name: "FOO_1", Value: "new_val_1"}, {Name: "FOO_2", Value: "val_1"}}, }, - want: []v1.EnvVar{{Name: "FOO_0", Value: "old_val_0"}, {Name: "FOO_1", Value: "new_val_1"}}, + want: []corev1.EnvVar{{Name: "FOO_0", Value: "old_val_0"}, {Name: "FOO_1", Value: "new_val_1"}}, }, } diff --git a/k3k-kubelet/provider/token.go b/k3k-kubelet/provider/token.go index c5ba6db..9988a32 100644 --- a/k3k-kubelet/provider/token.go +++ b/k3k-kubelet/provider/token.go @@ -145,6 +145,7 @@ func removeKubeAccessVolume(pod *corev1.Pod) { func addKubeAccessVolume(pod *corev1.Pod, hostSecretName string) { var tokenVolumeName = k3kcontroller.SafeConcatNameWithPrefix(kubeAPIAccessPrefix) + pod.Spec.Volumes = append(pod.Spec.Volumes, corev1.Volume{ Name: tokenVolumeName, VolumeSource: corev1.VolumeSource{ diff --git a/main.go b/main.go index e711eca..0a81bf9 100644 --- a/main.go +++ b/main.go @@ -146,7 +146,6 @@ func run(clx *cli.Context) error { mgr, err := ctrl.NewManager(restConfig, manager.Options{ Scheme: scheme, }) - if err != nil { return fmt.Errorf("failed to create new controller runtime manager: %v", err) } diff --git a/pkg/controller/cluster/agent/ports.go b/pkg/controller/cluster/agent/ports.go index d043561..649b688 100644 --- a/pkg/controller/cluster/agent/ports.go +++ b/pkg/controller/cluster/agent/ports.go @@ -76,7 +76,7 @@ func (a *PortAllocator) getOrCreate(ctx context.Context, configmap *v1.ConfigMap Namespace: configmap.Namespace, } - if err := a.Client.Get(ctx, nn, configmap); err != nil { + if err := a.Get(ctx, nn, configmap); err != nil { if !apierrors.IsNotFound(err) { return err } @@ -90,7 +90,7 @@ func (a *PortAllocator) getOrCreate(ctx context.Context, configmap *v1.ConfigMap snapshotDataKey: []byte(""), } - if err := a.Client.Create(ctx, configmap); err != nil { + if err := a.Create(ctx, configmap); err != nil { return fmt.Errorf("failed to create port range configmap: %w", err) } } @@ -158,7 +158,7 @@ func (a *PortAllocator) allocatePort(ctx context.Context, clusterName, clusterNa return 0, err } - if err := a.Client.Update(ctx, configMap); err != nil { + if err := a.Update(ctx, configMap); err != nil { return 0, err } @@ -209,7 +209,7 @@ func (a *PortAllocator) deallocatePort(ctx context.Context, clusterName, cluster } } - return a.Client.Update(ctx, configMap) + return a.Update(ctx, configMap) } // parsePortMap will convert ConfigMap Data to a portMap of string keys and values of ints diff --git a/pkg/controller/cluster/cluster.go b/pkg/controller/cluster/cluster.go index 06e2196..b71debc 100644 --- a/pkg/controller/cluster/cluster.go +++ b/pkg/controller/cluster/cluster.go @@ -12,7 +12,6 @@ import ( "github.com/rancher/k3k/pkg/apis/k3k.io/v1alpha1" "github.com/rancher/k3k/pkg/controller" - k3kcontroller "github.com/rancher/k3k/pkg/controller" "github.com/rancher/k3k/pkg/controller/cluster/agent" "github.com/rancher/k3k/pkg/controller/cluster/server" "github.com/rancher/k3k/pkg/controller/cluster/server/bootstrap" @@ -35,7 +34,6 @@ import ( "k8s.io/client-go/util/workqueue" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/client" - ctrlruntimeclient "sigs.k8s.io/controller-runtime/pkg/client" ctrlcontroller "sigs.k8s.io/controller-runtime/pkg/controller" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "sigs.k8s.io/controller-runtime/pkg/event" @@ -65,7 +63,7 @@ var ( type ClusterReconciler struct { DiscoveryClient *discovery.DiscoveryClient - Client ctrlruntimeclient.Client + Client client.Client Scheme *runtime.Scheme record.EventRecorder SharedAgentImage string @@ -155,7 +153,7 @@ func (c *ClusterReconciler) Reconcile(ctx context.Context, req reconcile.Request var cluster v1alpha1.Cluster if err := c.Client.Get(ctx, req.NamespacedName, &cluster); err != nil { - return reconcile.Result{}, ctrlruntimeclient.IgnoreNotFound(err) + return reconcile.Result{}, client.IgnoreNotFound(err) } // if DeletionTimestamp is not Zero -> finalize the object @@ -285,7 +283,6 @@ func (c *ClusterReconciler) reconcile(ctx context.Context, cluster *v1alpha1.Clu log.Info("looking up Service CIDR for shared mode") cluster.Status.ServiceCIDR, err = c.lookupServiceCIDR(ctx) - if err != nil { log.Error(err, "error while looking up Cluster Service CIDR") @@ -450,7 +447,7 @@ func (c *ClusterReconciler) ensureNetworkPolicy(ctx context.Context, cluster *v1 log := ctrl.LoggerFrom(ctx) log.Info("ensuring network policy") - networkPolicyName := k3kcontroller.SafeConcatNameWithPrefix(cluster.Name) + networkPolicyName := controller.SafeConcatNameWithPrefix(cluster.Name) // network policies are managed by the Policy -> delete the one created as a standalone cluster if cluster.Status.PolicyName != "" { @@ -461,12 +458,12 @@ func (c *ClusterReconciler) ensureNetworkPolicy(ctx context.Context, cluster *v1 }, } - return ctrlruntimeclient.IgnoreNotFound(c.Client.Delete(ctx, netpol)) + return client.IgnoreNotFound(c.Client.Delete(ctx, netpol)) } expectedNetworkPolicy := &networkingv1.NetworkPolicy{ ObjectMeta: metav1.ObjectMeta{ - Name: k3kcontroller.SafeConcatNameWithPrefix(cluster.Name), + Name: controller.SafeConcatNameWithPrefix(cluster.Name), Namespace: cluster.Namespace, }, TypeMeta: metav1.TypeMeta{ @@ -516,6 +513,7 @@ func (c *ClusterReconciler) ensureNetworkPolicy(ctx context.Context, cluster *v1 } currentNetworkPolicy := expectedNetworkPolicy.DeepCopy() + result, err := controllerutil.CreateOrUpdate(ctx, c.Client, currentNetworkPolicy, func() error { if err := controllerutil.SetControllerReference(cluster, currentNetworkPolicy, c.Scheme); err != nil { return err @@ -525,7 +523,6 @@ func (c *ClusterReconciler) ensureNetworkPolicy(ctx context.Context, cluster *v1 return nil }) - if err != nil { return err } @@ -579,6 +576,7 @@ func (c *ClusterReconciler) ensureIngress(ctx context.Context, cluster *v1alpha1 } currentServerIngress := expectedServerIngress.DeepCopy() + result, err := controllerutil.CreateOrUpdate(ctx, c.Client, currentServerIngress, func() error { if err := controllerutil.SetControllerReference(cluster, currentServerIngress, c.Scheme); err != nil { return err @@ -589,7 +587,6 @@ func (c *ClusterReconciler) ensureIngress(ctx context.Context, cluster *v1alpha1 return nil }) - if err != nil { return err } @@ -761,11 +758,11 @@ func (c *ClusterReconciler) lookupServiceCIDR(ctx context.Context) (string, erro log.Info("looking up serviceCIDR from kube-apiserver pod") - matchingLabels := ctrlruntimeclient.MatchingLabels(map[string]string{ + matchingLabels := client.MatchingLabels(map[string]string{ "component": "kube-apiserver", "tier": "control-plane", }) - listOpts := &ctrlruntimeclient.ListOptions{Namespace: "kube-system"} + listOpts := &client.ListOptions{Namespace: "kube-system"} matchingLabels.ApplyToList(listOpts) var podList v1.PodList diff --git a/pkg/controller/cluster/cluster_suite_test.go b/pkg/controller/cluster/cluster_suite_test.go index 162a1e2..010d208 100644 --- a/pkg/controller/cluster/cluster_suite_test.go +++ b/pkg/controller/cluster/cluster_suite_test.go @@ -46,7 +46,7 @@ var _ = BeforeSuite(func() { } // setting controller namespace env to activate port range allocator - os.Setenv("CONTROLLER_NAMESPACE", "default") + _ = os.Setenv("CONTROLLER_NAMESPACE", "default") cfg, err := testEnv.Start() Expect(err).NotTo(HaveOccurred()) diff --git a/pkg/controller/cluster/cluster_test.go b/pkg/controller/cluster/cluster_test.go index 9b17f60..5f1b284 100644 --- a/pkg/controller/cluster/cluster_test.go +++ b/pkg/controller/cluster/cluster_test.go @@ -11,7 +11,6 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" corev1 "k8s.io/api/core/v1" - v1 "k8s.io/api/core/v1" networkingv1 "k8s.io/api/networking/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/utils/ptr" @@ -61,7 +60,7 @@ var _ = Describe("Cluster Controller", Label("controller"), Label("Cluster"), fu Expect(cluster.Status.Phase).To(Equal(v1alpha1.ClusterUnknown)) - serverVersion, err := k8s.DiscoveryClient.ServerVersion() + serverVersion, err := k8s.ServerVersion() Expect(err).To(Not(HaveOccurred())) expectedHostVersion := fmt.Sprintf("%s-k3s1", serverVersion.GitVersion) @@ -110,9 +109,9 @@ var _ = Describe("Cluster Controller", Label("controller"), Label("Cluster"), fu Expect(k8sClient.Create(ctx, cluster)).To(Succeed()) - var service v1.Service + var service corev1.Service - Eventually(func() v1.ServiceType { + Eventually(func() corev1.ServiceType { serviceKey := client.ObjectKey{ Name: server.ServiceName(cluster.Name), Namespace: cluster.Namespace, @@ -124,7 +123,7 @@ var _ = Describe("Cluster Controller", Label("controller"), Label("Cluster"), fu }). WithTimeout(time.Second * 30). WithPolling(time.Second). - Should(Equal(v1.ServiceTypeNodePort)) + Should(Equal(corev1.ServiceTypeNodePort)) }) It("will have the specified ports exposed when specified", func() { @@ -145,9 +144,9 @@ var _ = Describe("Cluster Controller", Label("controller"), Label("Cluster"), fu Expect(k8sClient.Create(ctx, cluster)).To(Succeed()) - var service v1.Service + var service corev1.Service - Eventually(func() v1.ServiceType { + Eventually(func() corev1.ServiceType { serviceKey := client.ObjectKey{ Name: server.ServiceName(cluster.Name), Namespace: cluster.Namespace, @@ -159,7 +158,7 @@ var _ = Describe("Cluster Controller", Label("controller"), Label("Cluster"), fu }). WithTimeout(time.Second * 30). WithPolling(time.Second). - Should(Equal(v1.ServiceTypeNodePort)) + Should(Equal(corev1.ServiceTypeNodePort)) servicePorts := service.Spec.Ports Expect(servicePorts).NotTo(BeEmpty()) @@ -193,9 +192,9 @@ var _ = Describe("Cluster Controller", Label("controller"), Label("Cluster"), fu Expect(k8sClient.Create(ctx, cluster)).To(Succeed()) - var service v1.Service + var service corev1.Service - Eventually(func() v1.ServiceType { + Eventually(func() corev1.ServiceType { serviceKey := client.ObjectKey{ Name: server.ServiceName(cluster.Name), Namespace: cluster.Namespace, @@ -207,7 +206,7 @@ var _ = Describe("Cluster Controller", Label("controller"), Label("Cluster"), fu }). WithTimeout(time.Second * 30). WithPolling(time.Second). - Should(Equal(v1.ServiceTypeNodePort)) + Should(Equal(corev1.ServiceTypeNodePort)) servicePorts := service.Spec.Ports Expect(servicePorts).NotTo(BeEmpty()) @@ -237,7 +236,7 @@ var _ = Describe("Cluster Controller", Label("controller"), Label("Cluster"), fu Expect(k8sClient.Create(ctx, cluster)).To(Succeed()) - var service v1.Service + var service corev1.Service Eventually(func() error { serviceKey := client.ObjectKey{ @@ -251,7 +250,7 @@ var _ = Describe("Cluster Controller", Label("controller"), Label("Cluster"), fu WithPolling(time.Second). Should(Succeed()) - Expect(service.Spec.Type).To(Equal(v1.ServiceTypeLoadBalancer)) + Expect(service.Spec.Type).To(Equal(corev1.ServiceTypeLoadBalancer)) servicePorts := service.Spec.Ports Expect(servicePorts).NotTo(BeEmpty()) diff --git a/pkg/controller/cluster/pod.go b/pkg/controller/cluster/pod.go index d7462aa..db8cb4a 100644 --- a/pkg/controller/cluster/pod.go +++ b/pkg/controller/cluster/pod.go @@ -237,8 +237,8 @@ func removePeer(ctx context.Context, client *clientv3.Client, name, address stri if u.Hostname() == address { log.Info("removing member from etcd", "name", member.Name, "id", member.ID, "address", address) - _, err := client.MemberRemove(ctx, member.ID) + _, err := client.MemberRemove(ctx, member.ID) if errors.Is(err, rpctypes.ErrGRPCMemberNotFound) { return nil } diff --git a/pkg/controller/cluster/server/bootstrap/bootstrap.go b/pkg/controller/cluster/server/bootstrap/bootstrap.go index cbc2c14..f49b69c 100644 --- a/pkg/controller/cluster/server/bootstrap/bootstrap.go +++ b/pkg/controller/cluster/server/bootstrap/bootstrap.go @@ -77,7 +77,10 @@ func requestBootstrap(token, serverIP string) (*ControlRuntimeBootstrap, error) return nil, err } - defer resp.Body.Close() + + defer func() { + _ = resp.Body.Close() + }() var runtimeBootstrap ControlRuntimeBootstrap if err := json.NewDecoder(resp.Body).Decode(&runtimeBootstrap); err != nil { @@ -174,6 +177,7 @@ func GetFromSecret(ctx context.Context, client client.Client, cluster *v1alpha1. } var bootstrap ControlRuntimeBootstrap + err := json.Unmarshal(bootstrapData, &bootstrap) return &bootstrap, err diff --git a/pkg/controller/policy/policy_test.go b/pkg/controller/policy/policy_test.go index d82b991..38f75a0 100644 --- a/pkg/controller/policy/policy_test.go +++ b/pkg/controller/policy/policy_test.go @@ -2,7 +2,6 @@ package policy_test import ( "context" - "fmt" "reflect" "time" @@ -532,8 +531,6 @@ var _ = Describe("VirtualClusterPolicy Controller", Label("controller"), Label(" WithPolling(time.Second). Should(BeNil()) - fmt.Printf("%+v\n", resourceQuota) - delete(namespace.Labels, policy.PolicyNameLabelKey) err := k8sClient.Update(ctx, namespace) Expect(err).To(Not(HaveOccurred())) diff --git a/tests/cluster_test.go b/tests/cluster_test.go index c207c1d..12967d1 100644 --- a/tests/cluster_test.go +++ b/tests/cluster_test.go @@ -4,7 +4,6 @@ import ( "context" "crypto/x509" "errors" - "fmt" "os" "strings" "time" @@ -62,7 +61,7 @@ var _ = When("a ephemeral cluster is installed", Label("e2e"), func() { It("regenerates the bootstrap secret after a restart", func() { ctx := context.Background() - _, err := virtualCluster.Client.DiscoveryClient.ServerVersion() + _, err := virtualCluster.Client.ServerVersion() Expect(err).To(Not(HaveOccurred())) labelSelector := "cluster=" + virtualCluster.Cluster.Name + ",role=server" @@ -72,7 +71,8 @@ var _ = When("a ephemeral cluster is installed", Label("e2e"), func() { Expect(len(serverPods.Items)).To(Equal(1)) serverPod := serverPods.Items[0] - fmt.Fprintf(GinkgoWriter, "deleting pod %s/%s\n", serverPod.Namespace, serverPod.Name) + GinkgoWriter.Printf("deleting pod %s/%s\n", serverPod.Namespace, serverPod.Name) + err = k8s.CoreV1().Pods(virtualCluster.Cluster.Namespace).Delete(ctx, serverPod.Name, v1.DeleteOptions{}) Expect(err).To(Not(HaveOccurred())) @@ -144,7 +144,7 @@ var _ = When("a dynamic cluster is installed", func() { It("use the same bootstrap secret after a restart", func() { ctx := context.Background() - _, err := virtualCluster.Client.DiscoveryClient.ServerVersion() + _, err := virtualCluster.Client.ServerVersion() Expect(err).To(Not(HaveOccurred())) labelSelector := "cluster=" + virtualCluster.Cluster.Name + ",role=server" @@ -154,7 +154,8 @@ var _ = When("a dynamic cluster is installed", func() { Expect(len(serverPods.Items)).To(Equal(1)) serverPod := serverPods.Items[0] - fmt.Fprintf(GinkgoWriter, "deleting pod %s/%s\n", serverPod.Namespace, serverPod.Name) + GinkgoWriter.Printf("deleting pod %s/%s\n", serverPod.Namespace, serverPod.Name) + err = k8s.CoreV1().Pods(virtualCluster.Cluster.Namespace).Delete(ctx, serverPod.Name, v1.DeleteOptions{}) Expect(err).To(Not(HaveOccurred())) diff --git a/tests/common_test.go b/tests/common_test.go index e0fbea9..919c5fc 100644 --- a/tests/common_test.go +++ b/tests/common_test.go @@ -249,7 +249,7 @@ func (c *VirtualCluster) NewNginxPod(namespace string) (*corev1.Pod, string) { if resourceName == nginxPod.Name && resourceNamespace == nginxPod.Namespace { podIP = pod.Status.PodIP - fmt.Fprintf(GinkgoWriter, + GinkgoWriter.Printf( "pod=%s resource=%s/%s status=%s podIP=%s\n", pod.Name, resourceNamespace, resourceName, pod.Status.Phase, podIP, ) diff --git a/tests/tests_suite_test.go b/tests/tests_suite_test.go index cd44296..1bf10ea 100644 --- a/tests/tests_suite_test.go +++ b/tests/tests_suite_test.go @@ -21,7 +21,6 @@ import ( "helm.sh/helm/v3/pkg/action" "helm.sh/helm/v3/pkg/chart/loader" corev1 "k8s.io/api/core/v1" - v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/client-go/kubernetes" @@ -54,7 +53,8 @@ var _ = BeforeSuite(func() { hostIP, err = k3sContainer.ContainerIP(ctx) Expect(err).To(Not(HaveOccurred())) - fmt.Fprintln(GinkgoWriter, "K3s containerIP: "+hostIP) + + GinkgoWriter.Println("K3s containerIP: " + hostIP) kubeconfig, err := k3sContainer.GetKubeConfig(context.Background()) Expect(err).To(Not(HaveOccurred())) @@ -65,6 +65,7 @@ var _ = BeforeSuite(func() { func initKubernetesClient(kubeconfig []byte) { var err error + restcfg, err = clientcmd.RESTConfigFromKubeConfig(kubeconfig) Expect(err).To(Not(HaveOccurred())) @@ -96,7 +97,7 @@ func installK3kChart(kubeconfig []byte) { releaseNamespace := "k3k-system" err = actionConfig.Init(restClientGetter, releaseNamespace, os.Getenv("HELM_DRIVER"), func(format string, v ...interface{}) { - fmt.Fprintf(GinkgoWriter, "helm debug: "+format+"\n", v...) + GinkgoWriter.Printf("helm debug: "+format+"\n", v...) }) Expect(err).To(Not(HaveOccurred())) @@ -127,7 +128,7 @@ func installK3kChart(kubeconfig []byte) { release, err := iCli.Run(k3kChart, k3kChart.Values) Expect(err).To(Not(HaveOccurred())) - fmt.Fprintf(GinkgoWriter, "Release %s installed in %s namespace\n", release.Name, release.Namespace) + GinkgoWriter.Printf("Release %s installed in %s namespace\n", release.Name, release.Namespace) } var _ = AfterSuite(func() { @@ -142,7 +143,7 @@ var _ = AfterSuite(func() { err = os.WriteFile(logfile, logs, 0644) Expect(err).To(Not(HaveOccurred())) - fmt.Fprintln(GinkgoWriter, "k3s logs written to: "+logfile) + GinkgoWriter.Println("k3s logs written to: " + logfile) // dump k3k controller logs readCloser, err = k3sContainer.Logs(context.Background()) @@ -169,7 +170,7 @@ func buildScheme() *runtime.Scheme { func writeK3kLogs() { var ( err error - podList v1.PodList + podList corev1.PodList ) ctx := context.Background() @@ -184,8 +185,6 @@ func writeK3kLogs() { } func writeLogs(filename string, logs io.ReadCloser) { - defer logs.Close() - logsStr, err := io.ReadAll(logs) Expect(err).To(Not(HaveOccurred())) @@ -193,7 +192,9 @@ func writeLogs(filename string, logs io.ReadCloser) { err = os.WriteFile(tempfile, []byte(logsStr), 0644) Expect(err).To(Not(HaveOccurred())) - fmt.Fprintln(GinkgoWriter, "logs written to: "+filename) + GinkgoWriter.Println("logs written to: " + filename) + + _ = logs.Close() } func readFileWithinPod(ctx context.Context, client *kubernetes.Clientset, config *rest.Config, name, namespace, path string) ([]byte, error) { @@ -217,13 +218,13 @@ func exec(ctx context.Context, clientset *kubernetes.Clientset, config *rest.Con SubResource("exec") scheme := runtime.NewScheme() - if err := v1.AddToScheme(scheme); err != nil { + if err := corev1.AddToScheme(scheme); err != nil { return nil, fmt.Errorf("error adding to scheme: %v", err) } parameterCodec := runtime.NewParameterCodec(scheme) - req.VersionedParams(&v1.PodExecOptions{ + req.VersionedParams(&corev1.PodExecOptions{ Command: command, Stdin: stdin != nil, Stdout: stdout != nil, @@ -244,7 +245,6 @@ func exec(ctx context.Context, clientset *kubernetes.Clientset, config *rest.Con Stderr: &stderr, Tty: false, }) - if err != nil { return nil, fmt.Errorf("error in Stream: %v", err) } @@ -252,8 +252,8 @@ func exec(ctx context.Context, clientset *kubernetes.Clientset, config *rest.Con return stderr.Bytes(), nil } -func caCertSecret(name, namespace string, crt, key []byte) *v1.Secret { - return &v1.Secret{ +func caCertSecret(name, namespace string, crt, key []byte) *corev1.Secret { + return &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: name, Namespace: namespace,