Skip to content

Commit

Permalink
feat: support exporter custom port (#728)
Browse files Browse the repository at this point in the history
* support exporter custom port

Signed-off-by: drivebyer <[email protected]>

* add e2e

Signed-off-by: drivebyer <[email protected]>

---------

Signed-off-by: drivebyer <[email protected]>
  • Loading branch information
drivebyer authored Dec 17, 2023
1 parent 692c4ac commit 62d79b8
Show file tree
Hide file tree
Showing 22 changed files with 298 additions and 86 deletions.
1 change: 1 addition & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ COPY main.go main.go
COPY api/ api/
COPY controllers/ controllers/
COPY k8sutils/ k8sutils/
COPY pkg/ pkg/
COPY mocks/ mocks/

# Build
Expand Down
4 changes: 3 additions & 1 deletion api/common_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ type ExistingPasswordSecret struct {
// RedisExporter interface will have the information for redis exporter related stuff
// +k8s:deepcopy-gen=true
type RedisExporter struct {
Enabled bool `json:"enabled,omitempty"`
Enabled bool `json:"enabled,omitempty"`
// +kubebuilder:default:=9121
Port *int `json:"port,omitempty"`
Image string `json:"image"`
Resources *corev1.ResourceRequirements `json:"resources,omitempty"`
ImagePullPolicy corev1.PullPolicy `json:"imagePullPolicy,omitempty"`
Expand Down
3 changes: 3 additions & 0 deletions api/v1beta2/rediscluster_default.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,7 @@ func (r *RedisCluster) SetDefault() {
if r.Spec.Port == nil {
r.Spec.Port = pointer.Int(6379)
}
if r.Spec.RedisExporter != nil && r.Spec.RedisExporter.Port == nil {
r.Spec.RedisExporter.Port = pointer.Int(9121)
}
}
5 changes: 5 additions & 0 deletions api/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions config/crd/bases/redis.redis.opstreelabs.in_redis.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1274,6 +1274,9 @@ spec:
description: PullPolicy describes a policy for if/when to pull
a container image
type: string
port:
default: 9121
type: integer
resources:
description: ResourceRequirements describes the compute resource
requirements.
Expand Down Expand Up @@ -5615,6 +5618,9 @@ spec:
description: PullPolicy describes a policy for if/when to pull
a container image
type: string
port:
default: 9121
type: integer
resources:
description: ResourceRequirements describes the compute resource
requirements.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,9 @@ spec:
description: PullPolicy describes a policy for if/when to pull
a container image
type: string
port:
default: 9121
type: integer
resources:
description: ResourceRequirements describes the compute resource
requirements.
Expand Down Expand Up @@ -5920,6 +5923,9 @@ spec:
description: PullPolicy describes a policy for if/when to pull
a container image
type: string
port:
default: 9121
type: integer
resources:
description: ResourceRequirements describes the compute resource
requirements.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1276,6 +1276,9 @@ spec:
description: PullPolicy describes a policy for if/when to pull
a container image
type: string
port:
default: 9121
type: integer
resources:
description: ResourceRequirements describes the compute resource
requirements.
Expand Down Expand Up @@ -5620,6 +5623,9 @@ spec:
description: PullPolicy describes a policy for if/when to pull
a container image
type: string
port:
default: 9121
type: integer
resources:
description: ResourceRequirements describes the compute resource
requirements.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3316,6 +3316,9 @@ spec:
description: PullPolicy describes a policy for if/when to pull
a container image
type: string
port:
default: 9121
type: integer
resources:
description: ResourceRequirements describes the compute resource
requirements.
Expand Down
7 changes: 6 additions & 1 deletion k8sutils/labels.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package k8sutils

import (
"strconv"

redisv1beta2 "github.com/OT-CONTAINER-KIT/redis-operator/api/v1beta2"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)
Expand Down Expand Up @@ -111,13 +113,16 @@ func filterAnnotations(anots map[string]string, ignoreAnnots ...string) map[stri
}

// generateServiceAnots generates and returns service annotations
func generateServiceAnots(stsMeta metav1.ObjectMeta, additionalSvcAnnotations map[string]string) map[string]string {
func generateServiceAnots(stsMeta metav1.ObjectMeta, additionalSvcAnnotations map[string]string, epp exporterPortProvider) map[string]string {
anots := map[string]string{
"redis.opstreelabs.in": "true",
"redis.opstreelabs.instance": stsMeta.GetName(),
"prometheus.io/scrape": "true",
"prometheus.io/port": "9121",
}
if exporterPort, ok := epp(); ok {
anots["prometheus.io/port"] = strconv.Itoa(exporterPort)
}
for k, v := range stsMeta.GetAnnotations() {
anots[k] = v
}
Expand Down
2 changes: 1 addition & 1 deletion k8sutils/labels_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ func TestGenerateServiceAnots(t *testing.T) {
"additional-annotation": "additional-value",
}

resultAnnotations := generateServiceAnots(stsMeta, additionalSvcAnnotations)
resultAnnotations := generateServiceAnots(stsMeta, additionalSvcAnnotations, defaultExporterPortProvider)

if !reflect.DeepEqual(resultAnnotations, expectedAnnotations) {
t.Errorf("Expected annotations to be %v but got %v", expectedAnnotations, resultAnnotations)
Expand Down
27 changes: 17 additions & 10 deletions k8sutils/redis-cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ package k8sutils
import (
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/utils/pointer"
)

// RedisClusterSTS is a interface to call Redis Statefulset function
Expand Down Expand Up @@ -124,11 +126,12 @@ func generateRedisClusterContainerParams(cr *redisv1beta2.RedisCluster, security
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.RedisExporter.Port != nil {
containerProp.RedisExporterPort = cr.Spec.RedisExporter.Port
}
}
if readinessProbeDef != nil {
containerProp.ReadinessProbe = readinessProbeDef
Expand Down Expand Up @@ -235,25 +238,29 @@ func (service RedisClusterService) CreateRedisClusterService(cr *redisv1beta2.Re
serviceName := cr.ObjectMeta.Name + "-" + service.RedisServiceRole
logger := serviceLogger(cr.Namespace, serviceName)
labels := getRedisLabels(serviceName, cluster, service.RedisServiceRole, cr.ObjectMeta.Labels)
annotations := generateServiceAnots(cr.ObjectMeta, nil)
if cr.Spec.RedisExporter != nil && cr.Spec.RedisExporter.Enabled {
enableMetrics = true
var epp exporterPortProvider
if cr.Spec.RedisExporter != nil {
epp = func() (port int, enable bool) {
defaultP := pointer.Int(redisExporterPort)
return *util.Coalesce(cr.Spec.RedisExporter.Port, defaultP), cr.Spec.RedisExporter.Enabled
}
} else {
enableMetrics = false
epp = disableMetrics
}
annotations := generateServiceAnots(cr.ObjectMeta, nil, epp)
additionalServiceAnnotations := map[string]string{}
if cr.Spec.KubernetesConfig.Service != nil {
additionalServiceAnnotations = cr.Spec.KubernetesConfig.Service.ServiceAnnotations
}
objectMetaInfo := generateObjectMetaInformation(serviceName, cr.Namespace, labels, annotations)
headlessObjectMetaInfo := generateObjectMetaInformation(serviceName+"-headless", cr.Namespace, labels, annotations)
additionalObjectMetaInfo := generateObjectMetaInformation(serviceName+"-additional", cr.Namespace, labels, generateServiceAnots(cr.ObjectMeta, additionalServiceAnnotations))
err := CreateOrUpdateService(cr.Namespace, headlessObjectMetaInfo, redisClusterAsOwner(cr), false, true, "ClusterIP", *cr.Spec.Port)
additionalObjectMetaInfo := generateObjectMetaInformation(serviceName+"-additional", cr.Namespace, labels, generateServiceAnots(cr.ObjectMeta, additionalServiceAnnotations, epp))
err := CreateOrUpdateService(cr.Namespace, headlessObjectMetaInfo, redisClusterAsOwner(cr), disableMetrics, true, "ClusterIP", *cr.Spec.Port)
if err != nil {
logger.Error(err, "Cannot create headless service for Redis", "Setup.Type", service.RedisServiceRole)
return err
}
err = CreateOrUpdateService(cr.Namespace, objectMetaInfo, redisClusterAsOwner(cr), enableMetrics, false, "ClusterIP", *cr.Spec.Port)
err = CreateOrUpdateService(cr.Namespace, objectMetaInfo, redisClusterAsOwner(cr), epp, false, "ClusterIP", *cr.Spec.Port)
if err != nil {
logger.Error(err, "Cannot create service for Redis", "Setup.Type", service.RedisServiceRole)
return err
Expand All @@ -262,7 +269,7 @@ func (service RedisClusterService) CreateRedisClusterService(cr *redisv1beta2.Re
if cr.Spec.KubernetesConfig.Service != nil {
additionalServiceType = cr.Spec.KubernetesConfig.Service.ServiceType
}
err = CreateOrUpdateService(cr.Namespace, additionalObjectMetaInfo, redisClusterAsOwner(cr), false, false, additionalServiceType, *cr.Spec.Port)
err = CreateOrUpdateService(cr.Namespace, additionalObjectMetaInfo, redisClusterAsOwner(cr), disableMetrics, false, additionalServiceType, *cr.Spec.Port)
if err != nil {
logger.Error(err, "Cannot create additional service for Redis", "Setup.Type", service.RedisServiceRole)
return err
Expand Down
26 changes: 17 additions & 9 deletions k8sutils/redis-replication.go
Original file line number Diff line number Diff line change
@@ -1,30 +1,38 @@
package k8sutils

import redisv1beta2 "github.com/OT-CONTAINER-KIT/redis-operator/api/v1beta2"
import (
redisv1beta2 "github.com/OT-CONTAINER-KIT/redis-operator/api/v1beta2"
"github.com/OT-CONTAINER-KIT/redis-operator/pkg/util"
"k8s.io/utils/pointer"
)

// CreateReplicationService method will create replication service for Redis
func CreateReplicationService(cr *redisv1beta2.RedisReplication) error {
logger := serviceLogger(cr.Namespace, cr.ObjectMeta.Name)
labels := getRedisLabels(cr.ObjectMeta.Name, replication, "replication", cr.ObjectMeta.Labels)
annotations := generateServiceAnots(cr.ObjectMeta, nil)
if cr.Spec.RedisExporter != nil && cr.Spec.RedisExporter.Enabled {
enableMetrics = true
var epp exporterPortProvider
if cr.Spec.RedisExporter != nil {
epp = func() (port int, enable bool) {
defaultP := pointer.Int(redisExporterPort)
return *util.Coalesce(cr.Spec.RedisExporter.Port, defaultP), cr.Spec.RedisExporter.Enabled
}
} else {
enableMetrics = false
epp = disableMetrics
}
annotations := generateServiceAnots(cr.ObjectMeta, nil, epp)
additionalServiceAnnotations := map[string]string{}
if cr.Spec.KubernetesConfig.Service != nil {
additionalServiceAnnotations = cr.Spec.KubernetesConfig.Service.ServiceAnnotations
}
objectMetaInfo := generateObjectMetaInformation(cr.ObjectMeta.Name, cr.Namespace, labels, annotations)
headlessObjectMetaInfo := generateObjectMetaInformation(cr.ObjectMeta.Name+"-headless", cr.Namespace, labels, annotations)
additionalObjectMetaInfo := generateObjectMetaInformation(cr.ObjectMeta.Name+"-additional", cr.Namespace, labels, generateServiceAnots(cr.ObjectMeta, additionalServiceAnnotations))
err := CreateOrUpdateService(cr.Namespace, headlessObjectMetaInfo, redisReplicationAsOwner(cr), false, true, "ClusterIP", redisPort)
additionalObjectMetaInfo := generateObjectMetaInformation(cr.ObjectMeta.Name+"-additional", cr.Namespace, labels, generateServiceAnots(cr.ObjectMeta, additionalServiceAnnotations, epp))
err := CreateOrUpdateService(cr.Namespace, headlessObjectMetaInfo, redisReplicationAsOwner(cr), disableMetrics, true, "ClusterIP", redisPort)
if err != nil {
logger.Error(err, "Cannot create replication headless service for Redis")
return err
}
err = CreateOrUpdateService(cr.Namespace, objectMetaInfo, redisReplicationAsOwner(cr), enableMetrics, false, "ClusterIP", redisPort)
err = CreateOrUpdateService(cr.Namespace, objectMetaInfo, redisReplicationAsOwner(cr), epp, false, "ClusterIP", redisPort)
if err != nil {
logger.Error(err, "Cannot create replication service for Redis")
return err
Expand All @@ -33,7 +41,7 @@ func CreateReplicationService(cr *redisv1beta2.RedisReplication) error {
if cr.Spec.KubernetesConfig.Service != nil {
additionalServiceType = cr.Spec.KubernetesConfig.Service.ServiceType
}
err = CreateOrUpdateService(cr.Namespace, additionalObjectMetaInfo, redisReplicationAsOwner(cr), false, false, additionalServiceType, redisPort)
err = CreateOrUpdateService(cr.Namespace, additionalObjectMetaInfo, redisReplicationAsOwner(cr), disableMetrics, false, additionalServiceType, redisPort)
if err != nil {
logger.Error(err, "Cannot create additional service for Redis Replication")
return err
Expand Down
24 changes: 14 additions & 10 deletions k8sutils/redis-sentinel.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"context"
"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"
Expand Down Expand Up @@ -198,29 +200,31 @@ func (service RedisSentinelService) CreateRedisSentinelService(cr *redisv1beta2.
serviceName := cr.ObjectMeta.Name + "-" + service.RedisServiceRole
logger := serviceLogger(cr.Namespace, serviceName)
labels := getRedisLabels(serviceName, sentinel, service.RedisServiceRole, cr.ObjectMeta.Labels)
annotations := generateServiceAnots(cr.ObjectMeta, nil)

if cr.Spec.RedisExporter != nil && cr.Spec.RedisExporter.Enabled {
enableMetrics = true
var epp exporterPortProvider
if cr.Spec.RedisExporter != nil {
epp = func() (port int, enable bool) {
defaultP := pointer.Int(redisExporterPort)
return *util.Coalesce(cr.Spec.RedisExporter.Port, defaultP), cr.Spec.RedisExporter.Enabled
}
} else {
enableMetrics = false
epp = disableMetrics
}

annotations := generateServiceAnots(cr.ObjectMeta, nil, epp)
additionalServiceAnnotations := map[string]string{}
if cr.Spec.KubernetesConfig.Service != nil {
additionalServiceAnnotations = cr.Spec.KubernetesConfig.Service.ServiceAnnotations
}

objectMetaInfo := generateObjectMetaInformation(serviceName, cr.Namespace, labels, annotations)
headlessObjectMetaInfo := generateObjectMetaInformation(serviceName+"-headless", cr.Namespace, labels, annotations)
additionalObjectMetaInfo := generateObjectMetaInformation(serviceName+"-additional", cr.Namespace, labels, generateServiceAnots(cr.ObjectMeta, additionalServiceAnnotations))
additionalObjectMetaInfo := generateObjectMetaInformation(serviceName+"-additional", cr.Namespace, labels, generateServiceAnots(cr.ObjectMeta, additionalServiceAnnotations, epp))

err := CreateOrUpdateService(cr.Namespace, headlessObjectMetaInfo, redisSentinelAsOwner(cr), false, true, "ClusterIP", sentinelPort)
err := CreateOrUpdateService(cr.Namespace, headlessObjectMetaInfo, redisSentinelAsOwner(cr), disableMetrics, true, "ClusterIP", sentinelPort)
if err != nil {
logger.Error(err, "Cannot create headless service for Redis", "Setup.Type", service.RedisServiceRole)
return err
}
err = CreateOrUpdateService(cr.Namespace, objectMetaInfo, redisSentinelAsOwner(cr), enableMetrics, false, "ClusterIP", sentinelPort)
err = CreateOrUpdateService(cr.Namespace, objectMetaInfo, redisSentinelAsOwner(cr), epp, false, "ClusterIP", sentinelPort)
if err != nil {
logger.Error(err, "Cannot create service for Redis", "Setup.Type", service.RedisServiceRole)
return err
Expand All @@ -230,7 +234,7 @@ func (service RedisSentinelService) CreateRedisSentinelService(cr *redisv1beta2.
if cr.Spec.KubernetesConfig.Service != nil {
additionalServiceType = cr.Spec.KubernetesConfig.Service.ServiceType
}
err = CreateOrUpdateService(cr.Namespace, additionalObjectMetaInfo, redisSentinelAsOwner(cr), false, false, additionalServiceType, sentinelPort)
err = CreateOrUpdateService(cr.Namespace, additionalObjectMetaInfo, redisSentinelAsOwner(cr), disableMetrics, false, additionalServiceType, sentinelPort)
if err != nil {
logger.Error(err, "Cannot create additional service for Redis", "Setup.Type", service.RedisServiceRole)
return err
Expand Down
32 changes: 20 additions & 12 deletions k8sutils/redis-standalone.go
Original file line number Diff line number Diff line change
@@ -1,34 +1,42 @@
package k8sutils

import redisv1beta2 "github.com/OT-CONTAINER-KIT/redis-operator/api/v1beta2"

var (
enableMetrics bool
import (
redisv1beta2 "github.com/OT-CONTAINER-KIT/redis-operator/api/v1beta2"
"github.com/OT-CONTAINER-KIT/redis-operator/pkg/util"
"k8s.io/utils/pointer"
)

//var (
// enableMetrics bool
//)

// CreateStandaloneService method will create standalone service for Redis
func CreateStandaloneService(cr *redisv1beta2.Redis) error {
logger := serviceLogger(cr.Namespace, cr.ObjectMeta.Name)
labels := getRedisLabels(cr.ObjectMeta.Name, standalone, "standalone", cr.ObjectMeta.Labels)
annotations := generateServiceAnots(cr.ObjectMeta, nil)
if cr.Spec.RedisExporter != nil && cr.Spec.RedisExporter.Enabled {
enableMetrics = true
var epp exporterPortProvider
if cr.Spec.RedisExporter != nil {
epp = func() (port int, enable bool) {
defaultP := pointer.Int(redisExporterPort)
return *util.Coalesce(cr.Spec.RedisExporter.Port, defaultP), cr.Spec.RedisExporter.Enabled
}
} else {
enableMetrics = false
epp = disableMetrics
}
annotations := generateServiceAnots(cr.ObjectMeta, nil, epp)
additionalServiceAnnotations := map[string]string{}
if cr.Spec.KubernetesConfig.Service != nil {
additionalServiceAnnotations = cr.Spec.KubernetesConfig.Service.ServiceAnnotations
}
objectMetaInfo := generateObjectMetaInformation(cr.ObjectMeta.Name, cr.Namespace, labels, annotations)
headlessObjectMetaInfo := generateObjectMetaInformation(cr.ObjectMeta.Name+"-headless", cr.Namespace, labels, annotations)
additionalObjectMetaInfo := generateObjectMetaInformation(cr.ObjectMeta.Name+"-additional", cr.Namespace, labels, generateServiceAnots(cr.ObjectMeta, additionalServiceAnnotations))
err := CreateOrUpdateService(cr.Namespace, headlessObjectMetaInfo, redisAsOwner(cr), false, true, "ClusterIP", redisPort)
additionalObjectMetaInfo := generateObjectMetaInformation(cr.ObjectMeta.Name+"-additional", cr.Namespace, labels, generateServiceAnots(cr.ObjectMeta, additionalServiceAnnotations, epp))
err := CreateOrUpdateService(cr.Namespace, headlessObjectMetaInfo, redisAsOwner(cr), disableMetrics, true, "ClusterIP", redisPort)
if err != nil {
logger.Error(err, "Cannot create standalone headless service for Redis")
return err
}
err = CreateOrUpdateService(cr.Namespace, objectMetaInfo, redisAsOwner(cr), enableMetrics, false, "ClusterIP", redisPort)
err = CreateOrUpdateService(cr.Namespace, objectMetaInfo, redisAsOwner(cr), epp, false, "ClusterIP", redisPort)
if err != nil {
logger.Error(err, "Cannot create standalone service for Redis")
return err
Expand All @@ -37,7 +45,7 @@ func CreateStandaloneService(cr *redisv1beta2.Redis) error {
if cr.Spec.KubernetesConfig.Service != nil {
additionalServiceType = cr.Spec.KubernetesConfig.Service.ServiceType
}
err = CreateOrUpdateService(cr.Namespace, additionalObjectMetaInfo, redisAsOwner(cr), false, false, additionalServiceType, redisPort)
err = CreateOrUpdateService(cr.Namespace, additionalObjectMetaInfo, redisAsOwner(cr), disableMetrics, false, additionalServiceType, redisPort)
if err != nil {
logger.Error(err, "Cannot create additional service for Redis")
return err
Expand Down
Loading

0 comments on commit 62d79b8

Please sign in to comment.