diff --git a/.github/workflows/operator-ci.yaml b/.github/workflows/operator-ci.yaml index 46caf204c..72cd7db61 100644 --- a/.github/workflows/operator-ci.yaml +++ b/.github/workflows/operator-ci.yaml @@ -7,6 +7,9 @@ on: branches: - master +permissions: + contents: read + env: GOLANG_VERSION: 1.21 APPLICATION_NAME: redis-operator @@ -44,15 +47,7 @@ jobs: uses: actions/setup-go@v4 with: go-version: ${{ env.GOLANG_VERSION }} - - - name: Download Go modules - run: go mod download - - - name: Check disk space - run: df -h - - - name: List Go module cache - run: ls -la $(go env GOPATH)/pkg/mod + cache: false - name: Run GolangCI-Lint uses: golangci/golangci-lint-action@v3 diff --git a/.golangci.yml b/.golangci.yml index a72eb7d4d..1f6276d5a 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -2,50 +2,59 @@ linters-settings: govet: check-shadowing: true golint: - min-confidence: 0.8 + min-confidence: 0.8 gofmt: simplify: true linters: - disable: - - errcheck - - tagliatelle + enable: + - asasalint + - asciicheck + - bidichk + - bodyclose + - containedctx + - decorder + - dogsled + - durationcheck + - errcheck + - errname + - exportloopref + - gci + - gochecknoinits + - gofmt + - gofumpt + - goprintffuncname + - gosec + - gosimple + - govet + - grouper + - importas - ineffassign + - makezero + - misspell + - noctx + - nolintlint + - nosprintfhostport - staticcheck - -# Exclude the files that are causing the errors -issues: - exclude-rules: - - path: _test\.go # Ignore test files for linting - linters: - - gocyclo - - errcheck - - dupl - - gosec -run: - timeout: 5m - go-version: "1.21" - output: - format: colored-line-number - sort-results: true + - tenv + - thelper + - tparallel + - typecheck + - unconvert + - unused + - wastedassign + - whitespace - test: false - # Exclude third-party packages and go.mod from the lint checks - exclude: | - '(^vendor/.*|.*_test\.go|go\.mod|.*validatingwebhookconfiguration\.go|.*mutatingwebhookconfiguration\.go)' +run: + timeout: 15m + go: "1.21" + tests: true + show-stats: true skip-files: - - '^.*validatingwebhookconfiguration\.go$' - - controllers/suite_test.go - skip-dirs: - - k8s.io/client-go - - github.com/banzaicloud/k8s-objectmatcher - - github.com/go-logr/logr - - github.com/redis/go-redis - - github.com/onsi/ginkgo - - github.com/onsi/gomega - - github.com/pkg/errors - - k8s.io/api - - k8s.io/apimachinery - - sigs.k8s.io/controller-runtime - - golang.org/x/sys - - vendor$, third_party$, testdata$, examples$, Godeps$, builtin$ \ No newline at end of file + - ".+\\.generated.go" + +output: + format: colored-line-number + sort-results: true + print-linter-name: true + print-issued-lines: true \ No newline at end of file diff --git a/api/v1beta1/redis_types.go b/api/v1beta1/redis_types.go index 6a38be57a..8f30e2d10 100644 --- a/api/v1beta1/redis_types.go +++ b/api/v1beta1/redis_types.go @@ -45,8 +45,7 @@ type RedisSpec struct { } // RedisStatus defines the observed state of Redis -type RedisStatus struct { -} +type RedisStatus struct{} // +kubebuilder:object:root=true // +kubebuilder:subresource:status @@ -69,6 +68,7 @@ type RedisList struct { Items []Redis `json:"items"` } +// //nolint:gochecknoinits func init() { SchemeBuilder.Register(&Redis{}, &RedisList{}) } diff --git a/api/v1beta1/rediscluster_types.go b/api/v1beta1/rediscluster_types.go index 4076e71c0..21df7fde0 100644 --- a/api/v1beta1/rediscluster_types.go +++ b/api/v1beta1/rediscluster_types.go @@ -64,8 +64,7 @@ type RedisFollower struct { } // RedisClusterStatus defines the observed state of RedisCluster -type RedisClusterStatus struct { -} +type RedisClusterStatus struct{} // +kubebuilder:object:root=true // +kubebuilder:subresource:status @@ -91,6 +90,7 @@ type RedisClusterList struct { Items []RedisCluster `json:"items"` } +//nolint:gochecknoinits func init() { SchemeBuilder.Register(&RedisCluster{}, &RedisClusterList{}) } diff --git a/api/v1beta1/redisreplication_types.go b/api/v1beta1/redisreplication_types.go index df9ea159c..4cca92403 100644 --- a/api/v1beta1/redisreplication_types.go +++ b/api/v1beta1/redisreplication_types.go @@ -31,8 +31,7 @@ func (cr *RedisReplicationSpec) GetReplicationCounts(t string) int32 { } // RedisStatus defines the observed state of Redis -type RedisReplicationStatus struct { -} +type RedisReplicationStatus struct{} // +kubebuilder:object:root=true // +kubebuilder:subresource:status @@ -55,6 +54,7 @@ type RedisReplicationList struct { Items []RedisReplication `json:"items"` } +//nolint:gochecknoinits func init() { SchemeBuilder.Register(&RedisReplication{}, &RedisReplicationList{}) } diff --git a/api/v1beta1/redissentinel_types.go b/api/v1beta1/redissentinel_types.go index 43103f2d5..54536b231 100644 --- a/api/v1beta1/redissentinel_types.go +++ b/api/v1beta1/redissentinel_types.go @@ -37,8 +37,7 @@ type RedisSentinelConfig struct { common.RedisSentinelConfig `json:",inline"` } -type RedisSentinelStatus struct { -} +type RedisSentinelStatus struct{} // +kubebuilder:object:root=true // +kubebuilder:subresource:status @@ -61,6 +60,7 @@ type RedisSentinelList struct { Items []RedisSentinel `json:"items"` } +//nolint:gochecknoinits func init() { SchemeBuilder.Register(&RedisSentinel{}, &RedisSentinelList{}) } diff --git a/api/v1beta2/redis_types.go b/api/v1beta2/redis_types.go index 091cb19ea..d6e56c775 100644 --- a/api/v1beta2/redis_types.go +++ b/api/v1beta2/redis_types.go @@ -50,8 +50,7 @@ type RedisSpec struct { } // RedisStatus defines the observed state of Redis -type RedisStatus struct { -} +type RedisStatus struct{} // +kubebuilder:object:root=true // +kubebuilder:subresource:status @@ -75,6 +74,7 @@ type RedisList struct { Items []Redis `json:"items"` } +//nolint:gochecknoinits func init() { SchemeBuilder.Register(&Redis{}, &RedisList{}) } diff --git a/api/v1beta2/rediscluster_types.go b/api/v1beta2/rediscluster_types.go index b9e629f7a..31c188494 100644 --- a/api/v1beta2/rediscluster_types.go +++ b/api/v1beta2/rediscluster_types.go @@ -113,6 +113,7 @@ type RedisClusterList struct { Items []RedisCluster `json:"items"` } +//nolint:gochecknoinits func init() { SchemeBuilder.Register(&RedisCluster{}, &RedisClusterList{}) } diff --git a/api/v1beta2/redisreplication_types.go b/api/v1beta2/redisreplication_types.go index cb04c169d..59248fb55 100644 --- a/api/v1beta2/redisreplication_types.go +++ b/api/v1beta2/redisreplication_types.go @@ -36,8 +36,7 @@ func (cr *RedisReplicationSpec) GetReplicationCounts(t string) int32 { } // RedisStatus defines the observed state of Redis -type RedisReplicationStatus struct { -} +type RedisReplicationStatus struct{} // +kubebuilder:object:root=true // +kubebuilder:subresource:status @@ -61,6 +60,7 @@ type RedisReplicationList struct { Items []RedisReplication `json:"items"` } +//nolint:gochecknoinits func init() { SchemeBuilder.Register(&RedisReplication{}, &RedisReplicationList{}) } diff --git a/api/v1beta2/redissentinel_types.go b/api/v1beta2/redissentinel_types.go index b40ee6e10..8787ee96c 100644 --- a/api/v1beta2/redissentinel_types.go +++ b/api/v1beta2/redissentinel_types.go @@ -41,8 +41,7 @@ type RedisSentinelConfig struct { common.RedisSentinelConfig `json:",inline"` } -type RedisSentinelStatus struct { -} +type RedisSentinelStatus struct{} // +kubebuilder:object:root=true // +kubebuilder:subresource:status @@ -66,6 +65,7 @@ type RedisSentinelList struct { Items []RedisSentinel `json:"items"` } +//nolint:gochecknoinits func init() { SchemeBuilder.Register(&RedisSentinel{}, &RedisSentinelList{}) } diff --git a/controllers/redis_controller_test.go b/controllers/redis_controller_test.go index 17830fd1f..ea04c705d 100644 --- a/controllers/redis_controller_test.go +++ b/controllers/redis_controller_test.go @@ -4,13 +4,11 @@ import ( "context" "fmt" - appsv1 "k8s.io/api/apps/v1" - redisv1beta2 "github.com/OT-CONTAINER-KIT/redis-operator/api/v1beta2" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" + appsv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" - "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" diff --git a/controllers/rediscluster_controller.go b/controllers/rediscluster_controller.go index 76b57d305..3cc478f93 100644 --- a/controllers/rediscluster_controller.go +++ b/controllers/rediscluster_controller.go @@ -141,7 +141,6 @@ func (r *RedisClusterReconciler) Reconcile(ctx context.Context, req ctrl.Request } if redisLeaderInfo.Status.ReadyReplicas == leaderReplicas { - // Mark the cluster status as initializing if there are no follower nodes if instance.Status.ReadyLeaderReplicas == 0 && instance.Status.ReadyFollowerReplicas == 0 { err = k8sutils.UpdateRedisClusterStatus(instance, status.RedisClusterInitializing, status.InitializingClusterFollowerReason, leaderReplicas, 0, r.Dk8sClient) diff --git a/controllers/rediscluster_controller_test.go b/controllers/rediscluster_controller_test.go index 6ae21cbd9..a28cbedf0 100644 --- a/controllers/rediscluster_controller_test.go +++ b/controllers/rediscluster_controller_test.go @@ -4,13 +4,11 @@ import ( "context" "fmt" - appsv1 "k8s.io/api/apps/v1" - corev1 "k8s.io/api/core/v1" - redisv1beta2 "github.com/OT-CONTAINER-KIT/redis-operator/api/v1beta2" . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" - + appsv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" diff --git a/controllers/redisreplication_controller.go b/controllers/redisreplication_controller.go index 9929e332c..d6f9b85cb 100644 --- a/controllers/redisreplication_controller.go +++ b/controllers/redisreplication_controller.go @@ -26,7 +26,6 @@ type RedisReplicationReconciler struct { } func (r *RedisReplicationReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) { - reqLogger := r.Log.WithValues("Request.Namespace", req.Namespace, "Request.Name", req.Name) reqLogger.Info("Reconciling opstree redis replication controller") instance := &redisv1beta2.RedisReplication{} @@ -73,7 +72,7 @@ func (r *RedisReplicationReconciler) Reconcile(ctx context.Context, req ctrl.Req } // Check that the Leader and Follower are ready in redis replication - if int32(redisReplicationInfo.Status.ReadyReplicas) != totalReplicas { + if redisReplicationInfo.Status.ReadyReplicas != totalReplicas { reqLogger.Info("Redis replication nodes are not ready yet", "Ready.Replicas", strconv.Itoa(int(redisReplicationInfo.Status.ReadyReplicas)), "Expected.Replicas", totalReplicas) return ctrl.Result{RequeueAfter: time.Second * 60}, nil } @@ -86,12 +85,9 @@ func (r *RedisReplicationReconciler) Reconcile(ctx context.Context, req ctrl.Req if err != nil { return ctrl.Result{RequeueAfter: time.Second * 60}, err } - } - reqLogger.Info("Will reconcile redis operator in again 10 seconds") return ctrl.Result{RequeueAfter: time.Second * 10}, nil - } // SetupWithManager sets up the controller with the Manager. diff --git a/controllers/redisreplication_controller_test.go b/controllers/redisreplication_controller_test.go index 3d12c07ee..ff833a5b1 100644 --- a/controllers/redisreplication_controller_test.go +++ b/controllers/redisreplication_controller_test.go @@ -49,7 +49,6 @@ var _ = Describe("Redis replication test", func() { Context("When creating a redis replication CR", func() { It("should create a statefulset, service", func() { - svc := &corev1.Service{} sts := &appsv1.StatefulSet{} @@ -101,7 +100,6 @@ var _ = Describe("Redis replication test", func() { "redis_setup_type": "replication", "role": "replication", })) - }) Context("then deleting the redis replication CR", func() { diff --git a/controllers/suite_test.go b/controllers/suite_test.go index 0ab8268ff..970eaf24d 100644 --- a/controllers/suite_test.go +++ b/controllers/suite_test.go @@ -23,7 +23,6 @@ import ( // redisv1beta1 "github.com/OT-CONTAINER-KIT/redis-operator/api/v1beta1" redisv1beta2 "github.com/OT-CONTAINER-KIT/redis-operator/api/v1beta2" - . "github.com/onsi/ginkgo/v2" . "github.com/onsi/gomega" "github.com/onsi/gomega/gexec" @@ -31,16 +30,16 @@ import ( "k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes/scheme" ctrl "sigs.k8s.io/controller-runtime" - "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/envtest" logf "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/controller-runtime/pkg/log/zap" - // +kubebuilder:scaffold:imports ) -var k8sClient client.Client -var testEnv *envtest.Environment +var ( + k8sClient client.Client + testEnv *envtest.Environment +) const ( ns = "default" @@ -136,5 +135,4 @@ var _ = BeforeSuite(func() { err := testEnv.Stop() Expect(err).ToNot(HaveOccurred()) }() - }) diff --git a/k8sutils/client_test.go b/k8sutils/client_test.go index 13618dc70..4a9904e1c 100644 --- a/k8sutils/client_test.go +++ b/k8sutils/client_test.go @@ -11,6 +11,7 @@ import ( func mockK8sConfigProvider() (*rest.Config, error) { return &rest.Config{}, nil } + func mockInvalidK8sConfigProvider() (*rest.Config, error) { return nil, errors.New("invalid configuration") } diff --git a/k8sutils/cluster-scaling.go b/k8sutils/cluster-scaling.go index 957b74b28..6e9303bc3 100644 --- a/k8sutils/cluster-scaling.go +++ b/k8sutils/cluster-scaling.go @@ -94,7 +94,6 @@ func getRedisClusterSlots(ctx context.Context, client kubernetes.Interface, logg // Split the Redis cluster info into lines lines := strings.Split(redisClusterInfo, "\n") - // Iterate through all lines for _, line := range lines { if strings.Contains(line, "master") && strings.Contains(line, "connected") { // Check if this line is a master node @@ -114,9 +113,7 @@ func getRedisClusterSlots(ctx context.Context, client kubernetes.Interface, logg } } } - logger.V(1).Info("Total cluster slots to be transferred from", "node", nodeID, "is", totalSlots) - return strconv.Itoa(totalSlots) } @@ -290,7 +287,6 @@ func getAttachedFollowerNodeIDs(ctx context.Context, client kubernetes.Interface slaveIDs = append(slaveIDs, parts[0]) } } - } logger.V(1).Info("Slaves Nodes attached to", "node", masterNodeID, "are", slaveIDs) @@ -334,7 +330,6 @@ func RemoveRedisFollowerNodesFromCluster(ctx context.Context, client kubernetes. } for _, followerNodeID := range followerNodeIDs { - cmd = append(cmd, followerNodeID) logger.V(1).Info("Redis cluster follower remove command is", "Command", cmd) executeCommand(client, logger, cr, cmd, cr.ObjectMeta.Name+"-leader-0") @@ -345,7 +340,7 @@ func RemoveRedisFollowerNodesFromCluster(ctx context.Context, client kubernetes. // Remove redis cluster node would remove last node to the existing redis cluster using redis-cli func RemoveRedisNodeFromCluster(ctx context.Context, client kubernetes.Interface, logger logr.Logger, cr *redisv1beta2.RedisCluster, removePod RedisDetails) { var cmd []string - //currentRedisCount := CheckRedisNodeCount(ctx, client, logger, cr, "leader") + // currentRedisCount := CheckRedisNodeCount(ctx, client, logger, cr, "leader") existingPod := RedisDetails{ PodName: cr.ObjectMeta.Name + "-leader-0", @@ -398,7 +393,7 @@ func VerifyLeaderPod(ctx context.Context, client kubernetes.Interface, logger lo } lines := strings.Split(info, "\r\n") - role := "" + var role string for _, line := range lines { if strings.HasPrefix(line, "role:") { role = strings.TrimPrefix(line, "role:") diff --git a/k8sutils/finalizer.go b/k8sutils/finalizer.go index 526fac516..b9a08d27c 100644 --- a/k8sutils/finalizer.go +++ b/k8sutils/finalizer.go @@ -3,13 +3,13 @@ package k8sutils import ( "context" "fmt" - "k8s.io/utils/env" redisv1beta2 "github.com/OT-CONTAINER-KIT/redis-operator/api/v1beta2" "github.com/go-logr/logr" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" + "k8s.io/utils/env" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" ) @@ -172,7 +172,6 @@ func finalizeRedisClusterPVC(client kubernetes.Interface, logger logr.Logger, cr } } } - } return nil } @@ -192,6 +191,5 @@ func finalizeRedisReplicationPVC(client kubernetes.Interface, logger logr.Logger } func finalizeRedisSentinelPVC(cr *redisv1beta2.RedisSentinel) error { - return nil } diff --git a/k8sutils/finalizers_test.go b/k8sutils/finalizers_test.go index f99a021df..a20ab6362 100644 --- a/k8sutils/finalizers_test.go +++ b/k8sutils/finalizers_test.go @@ -5,8 +5,6 @@ import ( "fmt" "testing" - // "time" - "github.com/OT-CONTAINER-KIT/redis-operator/api/v1beta2" "github.com/go-logr/logr/testr" "github.com/stretchr/testify/assert" @@ -14,12 +12,10 @@ import ( k8serrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" - // "k8s.io/apimachinery/pkg/types" // utilruntime "k8s.io/apimachinery/pkg/util/runtime" k8sClientFake "k8s.io/client-go/kubernetes/fake" "k8s.io/utils/pointer" - // ctrlClientFake "sigs.k8s.io/controller-runtime/pkg/client/fake" ) // func TestHandleRedisFinalizer(t *testing.T) { diff --git a/k8sutils/labels.go b/k8sutils/labels.go index 4d0d4518d..da3960870 100644 --- a/k8sutils/labels.go +++ b/k8sutils/labels.go @@ -39,7 +39,7 @@ func AddOwnerRefToObject(obj metav1.Object, ownerRef metav1.OwnerReference) { obj.SetOwnerReferences(append(obj.GetOwnerReferences(), ownerRef)) } -// redisAsOwner generates and returns object refernece +// redisAsOwner generates and returns object reference func redisAsOwner(cr *redisv1beta2.Redis) metav1.OwnerReference { trueVar := true return metav1.OwnerReference{ @@ -51,7 +51,7 @@ func redisAsOwner(cr *redisv1beta2.Redis) metav1.OwnerReference { } } -// redisClusterAsOwner generates and returns object refernece +// redisClusterAsOwner generates and returns object reference func redisClusterAsOwner(cr *redisv1beta2.RedisCluster) metav1.OwnerReference { trueVar := true return metav1.OwnerReference{ @@ -63,7 +63,7 @@ func redisClusterAsOwner(cr *redisv1beta2.RedisCluster) metav1.OwnerReference { } } -// redisReplicationAsOwner generates and returns object refernece +// redisReplicationAsOwner generates and returns object reference func redisReplicationAsOwner(cr *redisv1beta2.RedisReplication) metav1.OwnerReference { trueVar := true return metav1.OwnerReference{ @@ -75,7 +75,7 @@ func redisReplicationAsOwner(cr *redisv1beta2.RedisReplication) metav1.OwnerRefe } } -// RedisSentinelAsOwner generates and returns object refernece +// RedisSentinelAsOwner generates and returns object reference func redisSentinelAsOwner(cr *redisv1beta2.RedisSentinel) metav1.OwnerReference { trueVar := true return metav1.OwnerReference{ diff --git a/k8sutils/labels_test.go b/k8sutils/labels_test.go index 274f9c1a0..3331a1784 100644 --- a/k8sutils/labels_test.go +++ b/k8sutils/labels_test.go @@ -48,7 +48,8 @@ func Test_generateObjectMetaInformation(t *testing.T) { name: "test", namespace: "default", labels: map[string]string{"test": "test"}, - annotations: map[string]string{"test": "test"}}, + annotations: map[string]string{"test": "test"}, + }, want: metav1.ObjectMeta{ Name: "test", Namespace: "default", diff --git a/k8sutils/poddisruption.go b/k8sutils/poddisruption.go index 77412673f..4561b8cc9 100644 --- a/k8sutils/poddisruption.go +++ b/k8sutils/poddisruption.go @@ -76,14 +76,14 @@ func generatePodDisruptionBudgetDef(cr *redisv1beta2.RedisCluster, role string, }, } if pdbParams.MinAvailable != nil { - pdbTemplate.Spec.MinAvailable = &intstr.IntOrString{Type: intstr.Int, IntVal: int32(*pdbParams.MinAvailable)} + pdbTemplate.Spec.MinAvailable = &intstr.IntOrString{Type: intstr.Int, IntVal: (*pdbParams.MinAvailable)} } if pdbParams.MaxUnavailable != nil { - pdbTemplate.Spec.MaxUnavailable = &intstr.IntOrString{Type: intstr.Int, IntVal: int32(*pdbParams.MaxUnavailable)} + pdbTemplate.Spec.MaxUnavailable = &intstr.IntOrString{Type: intstr.Int, IntVal: *pdbParams.MaxUnavailable} } // If we don't have a value for either, assume quorum: (N/2)+1 if pdbTemplate.Spec.MaxUnavailable == nil && pdbTemplate.Spec.MinAvailable == nil { - pdbTemplate.Spec.MinAvailable = &intstr.IntOrString{Type: intstr.Int, IntVal: int32((*cr.Spec.Size / 2) + 1)} + pdbTemplate.Spec.MinAvailable = &intstr.IntOrString{Type: intstr.Int, IntVal: (*cr.Spec.Size / 2) + 1} } AddOwnerRefToObject(pdbTemplate, redisClusterAsOwner(cr)) return pdbTemplate @@ -103,14 +103,14 @@ func generateSentinelPodDisruptionBudgetDef(cr *redisv1beta2.RedisSentinel, role }, } if pdbParams.MinAvailable != nil { - pdbTemplate.Spec.MinAvailable = &intstr.IntOrString{Type: intstr.Int, IntVal: int32(*pdbParams.MinAvailable)} + pdbTemplate.Spec.MinAvailable = &intstr.IntOrString{Type: intstr.Int, IntVal: *pdbParams.MinAvailable} } if pdbParams.MaxUnavailable != nil { - pdbTemplate.Spec.MaxUnavailable = &intstr.IntOrString{Type: intstr.Int, IntVal: int32(*pdbParams.MaxUnavailable)} + pdbTemplate.Spec.MaxUnavailable = &intstr.IntOrString{Type: intstr.Int, IntVal: *pdbParams.MaxUnavailable} } // If we don't have a value for either, assume quorum: (N/2)+1 if pdbTemplate.Spec.MaxUnavailable == nil && pdbTemplate.Spec.MinAvailable == nil { - pdbTemplate.Spec.MinAvailable = &intstr.IntOrString{Type: intstr.Int, IntVal: int32((*cr.Spec.Size / 2) + 1)} + pdbTemplate.Spec.MinAvailable = &intstr.IntOrString{Type: intstr.Int, IntVal: (*cr.Spec.Size / 2) + 1} } AddOwnerRefToObject(pdbTemplate, redisSentinelAsOwner(cr)) return pdbTemplate diff --git a/k8sutils/redis-cluster.go b/k8sutils/redis-cluster.go index ae6a26247..273158be5 100644 --- a/k8sutils/redis-cluster.go +++ b/k8sutils/redis-cluster.go @@ -5,13 +5,12 @@ import ( "strconv" "strings" - "k8s.io/apimachinery/pkg/util/intstr" - "k8s.io/client-go/kubernetes" - commonapi "github.com/OT-CONTAINER-KIT/redis-operator/api" redisv1beta2 "github.com/OT-CONTAINER-KIT/redis-operator/api/v1beta2" "github.com/OT-CONTAINER-KIT/redis-operator/pkg/util" corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/util/intstr" + "k8s.io/client-go/kubernetes" "k8s.io/utils/pointer" ) @@ -96,7 +95,6 @@ func generateRedisClusterInitContainerParams(cr *redisv1beta2.RedisCluster) init if cr.Spec.Storage != nil { initcontainerProp.PersistenceEnabled = &trueProperty } - } return initcontainerProp diff --git a/k8sutils/redis-cluster_test.go b/k8sutils/redis-cluster_test.go index bdaac7a61..3774a0889 100644 --- a/k8sutils/redis-cluster_test.go +++ b/k8sutils/redis-cluster_test.go @@ -5,14 +5,13 @@ import ( "path/filepath" "testing" - "k8s.io/client-go/kubernetes/fake" - common "github.com/OT-CONTAINER-KIT/redis-operator/api" redisv1beta2 "github.com/OT-CONTAINER-KIT/redis-operator/api/v1beta2" "github.com/stretchr/testify/assert" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/util/yaml" + "k8s.io/client-go/kubernetes/fake" "k8s.io/utils/pointer" ) diff --git a/k8sutils/redis-replication.go b/k8sutils/redis-replication.go index 81803b10a..5fa84f53e 100644 --- a/k8sutils/redis-replication.go +++ b/k8sutils/redis-replication.go @@ -143,11 +143,9 @@ func generateRedisReplicationContainerParams(cr *redisv1beta2.RedisReplication) if cr.Spec.RedisExporter.Resources != nil { containerProp.RedisExporterResources = cr.Spec.RedisExporter.Resources } - if cr.Spec.RedisExporter.EnvVars != nil { containerProp.RedisExporterEnv = cr.Spec.RedisExporter.EnvVars } - } if cr.Spec.ReadinessProbe != nil { containerProp.ReadinessProbe = &cr.Spec.ReadinessProbe.Probe @@ -193,8 +191,6 @@ func generateRedisReplicationInitContainerParams(cr *redisv1beta2.RedisReplicati if cr.Spec.Storage != nil { initcontainerProp.PersistenceEnabled = &trueProperty } - } - return initcontainerProp } diff --git a/k8sutils/redis-replication_test.go b/k8sutils/redis-replication_test.go index 509f863e7..57765acba 100644 --- a/k8sutils/redis-replication_test.go +++ b/k8sutils/redis-replication_test.go @@ -21,7 +21,8 @@ func Test_generateRedisReplicationParams(t *testing.T) { ClusterMode: false, NodeConfVolume: false, NodeSelector: map[string]string{ - "node-role.kubernetes.io/infra": "worker"}, + "node-role.kubernetes.io/infra": "worker", + }, PodSecurityContext: &corev1.PodSecurityContext{ RunAsUser: pointer.Int64(1000), FSGroup: pointer.Int64(1000), diff --git a/k8sutils/redis-sentinel.go b/k8sutils/redis-sentinel.go index 698a19980..ad0c754b6 100644 --- a/k8sutils/redis-sentinel.go +++ b/k8sutils/redis-sentinel.go @@ -5,17 +5,16 @@ import ( "encoding/json" "errors" - "github.com/OT-CONTAINER-KIT/redis-operator/pkg/util" - "k8s.io/utils/pointer" - commonapi "github.com/OT-CONTAINER-KIT/redis-operator/api" redisv1beta2 "github.com/OT-CONTAINER-KIT/redis-operator/api/v1beta2" + "github.com/OT-CONTAINER-KIT/redis-operator/pkg/util" "github.com/go-logr/logr" corev1 "k8s.io/api/core/v1" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/client-go/dynamic" "k8s.io/client-go/kubernetes" + "k8s.io/utils/pointer" ) // RedisSentinelSTS is a interface to call Redis Statefulset function @@ -52,12 +51,10 @@ func CreateRedisSentinel(ctx context.Context, client kubernetes.Interface, logge } return prop.CreateRedisSentinelSetup(ctx, client, logger, cr, cl, dcl) - } // Create RedisSentinel Service func CreateRedisSentinelService(cr *redisv1beta2.RedisSentinel, cl kubernetes.Interface) error { - prop := RedisSentinelService{ RedisServiceRole: "sentinel", } @@ -80,7 +77,6 @@ func (service RedisSentinelSTS) CreateRedisSentinelSetup(ctx context.Context, cl cr.Spec.Sidecars, cl, ) - if err != nil { logger.Error(err, "Cannot create Sentinel statefulset for Redis") return err @@ -90,7 +86,6 @@ func (service RedisSentinelSTS) CreateRedisSentinelSetup(ctx context.Context, cl // Create Redis Sentile Params for the statefulset func generateRedisSentinelParams(cr *redisv1beta2.RedisSentinel, replicas int32, externalConfig *string, affinity *corev1.Affinity) statefulSetParameters { - res := statefulSetParameters{ Replicas: &replicas, ClusterMode: false, @@ -123,7 +118,6 @@ func generateRedisSentinelParams(cr *redisv1beta2.RedisSentinel, replicas int32, // generateRedisSentinelInitContainerParams generates Redis sentinel initcontainer information func generateRedisSentinelInitContainerParams(cr *redisv1beta2.RedisSentinel) initContainerParameters { - initcontainerProp := initContainerParameters{} if cr.Spec.InitContainer != nil { @@ -139,9 +133,7 @@ func generateRedisSentinelInitContainerParams(cr *redisv1beta2.RedisSentinel) in Command: initContainer.Command, Arguments: initContainer.Args, } - } - return initcontainerProp } @@ -190,7 +182,6 @@ func generateRedisSentinelContainerParams(ctx context.Context, client kubernetes } return containerProp - } // Get the Count of the Sentinel @@ -243,7 +234,6 @@ func (service RedisSentinelService) CreateRedisSentinelService(cr *redisv1beta2. return err } return nil - } func getSentinelEnvVariable(ctx context.Context, client kubernetes.Interface, logger logr.Logger, cr *redisv1beta2.RedisSentinel, dcl dynamic.Interface) *[]corev1.EnvVar { @@ -289,7 +279,6 @@ func getSentinelEnvVariable(ctx context.Context, client kubernetes.Interface, lo }) } return envVar - } func getRedisReplicationMasterIP(ctx context.Context, client kubernetes.Interface, logger logr.Logger, cr *redisv1beta2.RedisSentinel, dcl dynamic.Interface) string { diff --git a/k8sutils/redis-sentinel_test.go b/k8sutils/redis-sentinel_test.go index 85260d5b1..98cee4ee9 100644 --- a/k8sutils/redis-sentinel_test.go +++ b/k8sutils/redis-sentinel_test.go @@ -7,9 +7,6 @@ import ( "reflect" "testing" - "k8s.io/client-go/dynamic/fake" - "k8s.io/client-go/kubernetes" - common "github.com/OT-CONTAINER-KIT/redis-operator/api" redisv1beta2 "github.com/OT-CONTAINER-KIT/redis-operator/api/v1beta2" "github.com/go-logr/logr" @@ -18,6 +15,8 @@ import ( "k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/yaml" + "k8s.io/client-go/dynamic/fake" + "k8s.io/client-go/kubernetes" "k8s.io/utils/pointer" ) @@ -28,7 +27,8 @@ func Test_generateRedisSentinelParams(t *testing.T) { ClusterMode: false, NodeConfVolume: false, NodeSelector: map[string]string{ - "node-role.kubernetes.io/infra": "worker"}, + "node-role.kubernetes.io/infra": "worker", + }, PodSecurityContext: &corev1.PodSecurityContext{ RunAsUser: pointer.Int64(1000), FSGroup: pointer.Int64(1000), @@ -254,7 +254,6 @@ func Test_generateRedisSentinelInitContainerParams(t *testing.T) { func Test_getSentinelEnvVariable(t *testing.T) { type args struct { - ctx context.Context client kubernetes.Interface logger logr.Logger cr *redisv1beta2.RedisSentinel @@ -267,7 +266,6 @@ func Test_getSentinelEnvVariable(t *testing.T) { { name: "When RedisSentinelConfig is nil", args: args{ - ctx: context.TODO(), client: nil, logger: logr.Logger{}, cr: &redisv1beta2.RedisSentinel{}, @@ -277,7 +275,6 @@ func Test_getSentinelEnvVariable(t *testing.T) { { name: "When RedisSentinelConfig is not nil", args: args{ - ctx: context.TODO(), client: nil, logger: logr.Logger{}, cr: &redisv1beta2.RedisSentinel{ @@ -329,7 +326,8 @@ func Test_getSentinelEnvVariable(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - if got := getSentinelEnvVariable(tt.args.ctx, tt.args.client, tt.args.logger, tt.args.cr, fake.NewSimpleDynamicClient(&runtime.Scheme{})); !reflect.DeepEqual(got, tt.want) { + ctx := context.TODO() + if got := getSentinelEnvVariable(ctx, tt.args.client, tt.args.logger, tt.args.cr, fake.NewSimpleDynamicClient(&runtime.Scheme{})); !reflect.DeepEqual(got, tt.want) { t.Errorf("getSentinelEnvVariable() = %v, want %v", got, tt.want) } }) diff --git a/k8sutils/redis-standalone.go b/k8sutils/redis-standalone.go index c47e6a934..a99a45b92 100644 --- a/k8sutils/redis-standalone.go +++ b/k8sutils/redis-standalone.go @@ -103,7 +103,6 @@ func generateRedisStandaloneParams(cr *redisv1beta2.Redis) statefulSetParameters } if cr.Spec.RedisExporter != nil { res.EnableMetrics = cr.Spec.RedisExporter.Enabled - } if cr.Spec.ServiceAccountName != nil { res.ServiceAccountName = cr.Spec.ServiceAccountName @@ -153,7 +152,6 @@ func generateRedisStandaloneContainerParams(cr *redisv1beta2.Redis) containerPar if cr.Spec.RedisExporter.EnvVars != nil { containerProp.RedisExporterEnv = cr.Spec.RedisExporter.EnvVars } - } if cr.Spec.ReadinessProbe != nil { containerProp.ReadinessProbe = &cr.Spec.ReadinessProbe.Probe @@ -199,8 +197,6 @@ func generateRedisStandaloneInitContainerParams(cr *redisv1beta2.Redis) initCont if cr.Spec.Storage != nil { initcontainerProp.PersistenceEnabled = &trueProperty } - } - return initcontainerProp } diff --git a/k8sutils/redis-standalone_test.go b/k8sutils/redis-standalone_test.go index 81d13e537..e7eebe882 100644 --- a/k8sutils/redis-standalone_test.go +++ b/k8sutils/redis-standalone_test.go @@ -29,7 +29,8 @@ func Test_generateRedisStandaloneParams(t *testing.T) { // "opstreelabs.in.redis": "true"}, // }, NodeSelector: map[string]string{ - "node-role.kubernetes.io/infra": "worker"}, + "node-role.kubernetes.io/infra": "worker", + }, PodSecurityContext: &corev1.PodSecurityContext{ RunAsUser: pointer.Int64(1000), FSGroup: pointer.Int64(1000), diff --git a/k8sutils/redis.go b/k8sutils/redis.go index 221917c13..ddca1b8ed 100644 --- a/k8sutils/redis.go +++ b/k8sutils/redis.go @@ -182,7 +182,7 @@ func ExecuteRedisReplicationCommand(ctx context.Context, client kubernetes.Inter Namespace: cr.Namespace, } leaderPod := RedisDetails{ - PodName: cr.ObjectMeta.Name + "-leader-" + strconv.Itoa(int(followerIdx)%int(leaderCounts)), + PodName: cr.ObjectMeta.Name + "-leader-" + strconv.Itoa((followerIdx)%int(leaderCounts)), Namespace: cr.Namespace, } podIP = getRedisServerIP(client, logger, followerPod) @@ -486,7 +486,6 @@ func GetRedisNodesByRole(ctx context.Context, cl kubernetes.Interface, logger lo replicas := cr.Spec.GetReplicationCounts("replication") for i := 0; i < int(replicas); i++ { - podName := statefulset.Name + "-" + strconv.Itoa(i) podRole := checkRedisServerRole(ctx, cl, logger, cr, podName) if podRole == redisRole { @@ -542,11 +541,8 @@ func checkAttachedSlave(ctx context.Context, client kubernetes.Interface, logger if nums > 0 { return podName } - } - return "" - } func CreateMasterSlaveReplication(ctx context.Context, client kubernetes.Interface, logger logr.Logger, cr *redisv1beta2.RedisReplication, masterPods []string, slavePods []string) error { @@ -568,7 +564,6 @@ func CreateMasterSlaveReplication(ctx context.Context, client kubernetes.Interfa for i := 0; i < len(masterPods); i++ { if masterPods[i] != realMasterPod { - redisClient := configureRedisReplicationClient(client, logger, cr, masterPods[i]) defer redisClient.Close() logger.V(1).Info("Setting the", "pod", masterPods[i], "to slave of", realMasterPod) diff --git a/k8sutils/redis_test.go b/k8sutils/redis_test.go index 8dacd2032..14c0b2717 100644 --- a/k8sutils/redis_test.go +++ b/k8sutils/redis_test.go @@ -24,7 +24,7 @@ func TestCheckRedisNodePresence(t *testing.T) { csvOutput.FieldsPerRecord = -1 nodes, _ := csvOutput.ReadAll() - var tests = []struct { + tests := []struct { nodes [][]string ip string want bool diff --git a/k8sutils/services.go b/k8sutils/services.go index 353e68f58..94e93c00c 100644 --- a/k8sutils/services.go +++ b/k8sutils/services.go @@ -19,9 +19,7 @@ const ( redisExporterPortName = "redis-exporter" ) -var ( - serviceType corev1.ServiceType -) +var serviceType corev1.ServiceType // exporterPortProvider return the exporter port if bool is true type exporterPortProvider func() (port int, enable bool) @@ -49,7 +47,7 @@ func generateServiceDef(serviceMeta metav1.ObjectMeta, epp exporterPortProvider, { Name: PortName, Port: int32(port), - TargetPort: intstr.FromInt(int(port)), + TargetPort: intstr.FromInt(port), Protocol: corev1.ProtocolTCP, }, }, diff --git a/k8sutils/statefulset.go b/k8sutils/statefulset.go index 67f394a6e..b732a3afc 100644 --- a/k8sutils/statefulset.go +++ b/k8sutils/statefulset.go @@ -8,13 +8,9 @@ import ( "strconv" "strings" - "github.com/OT-CONTAINER-KIT/redis-operator/pkg/util" - "k8s.io/client-go/kubernetes" - "k8s.io/utils/env" - "k8s.io/utils/pointer" - commonapi "github.com/OT-CONTAINER-KIT/redis-operator/api" redisv1beta2 "github.com/OT-CONTAINER-KIT/redis-operator/api/v1beta2" + "github.com/OT-CONTAINER-KIT/redis-operator/pkg/util" "github.com/banzaicloud/k8s-objectmatcher/patch" "github.com/go-logr/logr" "github.com/pkg/errors" @@ -24,6 +20,9 @@ import ( apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/kubernetes" + "k8s.io/utils/env" + "k8s.io/utils/pointer" ) const ( @@ -169,12 +168,13 @@ func patchStatefulSet(storedStateful *appsv1.StatefulSet, newStateful *appsv1.St } updateFailed := false realUpdate := false - for _, pvc := range pvcs.Items { + for i := range pvcs.Items { + pvc := &pvcs.Items[i] realCapacity := pvc.Spec.Resources.Requests.Storage().Value() if realCapacity != stateCapacity { realUpdate = true pvc.Spec.Resources.Requests = newStateful.Spec.VolumeClaimTemplates[0].Spec.Resources.Requests - _, err = cl.CoreV1().PersistentVolumeClaims(storedStateful.Namespace).Update(context.Background(), &pvc, metav1.UpdateOptions{}) + _, err = cl.CoreV1().PersistentVolumeClaims(storedStateful.Namespace).Update(context.Background(), pvc, metav1.UpdateOptions{}) if err != nil { if !updateFailed { updateFailed = true @@ -183,6 +183,7 @@ func patchStatefulSet(storedStateful *appsv1.StatefulSet, newStateful *appsv1.St } } } + if !updateFailed && len(pvcs.Items) != 0 { annotations["storageCapacity"] = fmt.Sprintf("%d", stateCapacity) storedStateful.Annotations = annotations @@ -612,7 +613,8 @@ func getProbeInfo(probe *commonapi.Probe) *corev1.Probe { // getEnvironmentVariables returns all the required Environment Variables func getEnvironmentVariables(role string, enabledPassword *bool, secretName *string, secretKey *string, persistenceEnabled *bool, tlsConfig *redisv1beta2.TLSConfig, - aclConfig *redisv1beta2.ACLConfig, envVar *[]corev1.EnvVar, port *int, clusterVersion *string) []corev1.EnvVar { + aclConfig *redisv1beta2.ACLConfig, envVar *[]corev1.EnvVar, port *int, clusterVersion *string, +) []corev1.EnvVar { envVars := []corev1.EnvVar{ {Name: "SERVER_MODE", Value: role}, {Name: "SETUP_MODE", Value: role}, diff --git a/main.go b/main.go index 5f552bb35..0111770e5 100644 --- a/main.go +++ b/main.go @@ -20,26 +20,20 @@ import ( "flag" "os" - // Import all Kubernetes client auth plugins (e.g. Azure, GCP, OIDC, etc.) - // to ensure that exec-entrypoint and run can make use of them. - _ "k8s.io/client-go/plugin/pkg/client/auth" - + redisv1beta1 "github.com/OT-CONTAINER-KIT/redis-operator/api/v1beta1" + redisv1beta2 "github.com/OT-CONTAINER-KIT/redis-operator/api/v1beta2" + "github.com/OT-CONTAINER-KIT/redis-operator/controllers" + "github.com/OT-CONTAINER-KIT/redis-operator/k8sutils" "k8s.io/apimachinery/pkg/runtime" utilruntime "k8s.io/apimachinery/pkg/util/runtime" clientgoscheme "k8s.io/client-go/kubernetes/scheme" + _ "k8s.io/client-go/plugin/pkg/client/auth" ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/cache" "sigs.k8s.io/controller-runtime/pkg/healthz" "sigs.k8s.io/controller-runtime/pkg/log/zap" "sigs.k8s.io/controller-runtime/pkg/metrics/server" "sigs.k8s.io/controller-runtime/pkg/webhook" - - redisv1beta2 "github.com/OT-CONTAINER-KIT/redis-operator/api/v1beta2" - "github.com/OT-CONTAINER-KIT/redis-operator/controllers" - "github.com/OT-CONTAINER-KIT/redis-operator/k8sutils" - - redisv1beta1 "github.com/OT-CONTAINER-KIT/redis-operator/api/v1beta1" - // +kubebuilder:scaffold:imports ) var ( @@ -47,6 +41,7 @@ var ( setupLog = ctrl.Log.WithName("setup") ) +//nolint:gochecknoinits func init() { utilruntime.Must(clientgoscheme.AddToScheme(scheme)) diff --git a/mocks/utils/utils.go b/mocks/utils/utils.go index 6f9c33b99..9c58952fc 100644 --- a/mocks/utils/utils.go +++ b/mocks/utils/utils.go @@ -66,7 +66,7 @@ func CreateFakeClientWithPodIPs(cr *redisv1beta2.RedisCluster) *fake.Clientset { func CreateFakeClientWithSecrets(cr *redisv1beta2.RedisCluster, secretName, secretKey, secretValue string) *fake.Clientset { leaderReplicas := cr.Spec.GetReplicaCounts("leader") followerReplicas := cr.Spec.GetReplicaCounts("follower") - pods := make([]runtime.Object, leaderReplicas+followerReplicas) + pods := make([]runtime.Object, 0) for i := 0; i < int(leaderReplicas); i++ { podName := cr.ObjectMeta.Name + "-leader-" + strconv.Itoa(i)