Skip to content

Commit

Permalink
Merge pull request #271 from 3scale-ops/improve-redis-instance-status
Browse files Browse the repository at this point in the history
Add useful information to the Sentinel status
  • Loading branch information
3scale-robot authored Oct 11, 2023
2 parents 7592d08 + 441fff5 commit 049461b
Show file tree
Hide file tree
Showing 10 changed files with 88 additions and 13 deletions.
3 changes: 3 additions & 0 deletions api/v1alpha1/sentinel_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,9 @@ type RedisServerDetails struct {
// +operator-sdk:csv:customresourcedefinitions:type=status
// +optional
Config map[string]string `json:"config,omitempty"`
// +operator-sdk:csv:customresourcedefinitions:type=status
// +optional
Info map[string]string `json:"info,omitempty"`
}

// +kubebuilder:object:root=true
Expand Down
7 changes: 7 additions & 0 deletions api/v1alpha1/zz_generated.deepcopy.go

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

4 changes: 3 additions & 1 deletion controllers/sentinel_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,8 @@ func (r *SentinelReconciler) reconcileStatus(ctx context.Context, instance *saas
}

// redis shards info to the status
merr := cluster.SentinelDiscover(ctx, sharded.SlaveReadOnlyDiscoveryOpt, sharded.SaveConfigDiscoveryOpt)
merr := cluster.SentinelDiscover(ctx, sharded.SlaveReadOnlyDiscoveryOpt,
sharded.SaveConfigDiscoveryOpt, sharded.SlavePriorityDiscoveryOpt, sharded.ReplicationInfoDiscoveryOpt)
// if the failure occurred calling sentinel discard the result and return error
// otherwise keep going on and use the information that was returned, even if there were some
// other errors
Expand Down Expand Up @@ -194,6 +195,7 @@ func (r *SentinelReconciler) reconcileStatus(ctx context.Context, instance *saas
Role: srv.Role,
Address: srv.ID(),
Config: srv.Config,
Info: srv.Info,
}
}
}
Expand Down
5 changes: 5 additions & 0 deletions pkg/redis/client/fake_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,11 @@ func (fc *FakeClient) RedisSet(ctx context.Context, key string, value interface{
return rsp.InjectError()
}

func (fc *FakeClient) RedisInfo(ctx context.Context, section string) (string, error) {
rsp := fc.pop()
return rsp.InjectResponse().(string), rsp.InjectError()
}

func (fc *FakeClient) pop() (fakeRsp FakeResponse) {
fakeRsp, fc.Responses = fc.Responses[0], fc.Responses[1:]
return fakeRsp
Expand Down
5 changes: 5 additions & 0 deletions pkg/redis/client/goredis_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -165,3 +165,8 @@ func (c *GoRedisClient) RedisSet(ctx context.Context, key string, value interfac
_, err := c.redis.Set(ctx, key, value, 0).Result()
return err
}

func (c *GoRedisClient) RedisInfo(ctx context.Context, section string) (string, error) {
val, err := c.redis.Info(ctx, section).Result()
return val, err
}
1 change: 1 addition & 0 deletions pkg/redis/client/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ type TestableInterface interface {
RedisBGSave(context.Context) error
RedisLastSave(context.Context) (int64, error)
RedisSet(context.Context, string, interface{}) error
RedisInfo(ctx context.Context, section string) (string, error)
Close() error
}

Expand Down
8 changes: 8 additions & 0 deletions pkg/redis/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,14 @@ func (srv *Server) RedisSet(ctx context.Context, key string, value interface{})
return srv.client.RedisSet(ctx, key, value)
}

func (srv *Server) RedisInfo(ctx context.Context, section string) (map[string]string, error) {
val, err := srv.client.RedisInfo(ctx, section)
if err != nil {
return nil, err
}
return InfoStringToMap(val), nil
}

// This is a horrible function to parse the horrible structs that the go-redis
// client returns for administrative commands. I swear it's not my fault ...
func sliceCmdToStruct(in interface{}, out interface{}) error {
Expand Down
35 changes: 35 additions & 0 deletions pkg/redis/sharded/discover.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ const (
SlaveReadOnlyDiscoveryOpt DiscoveryOption = iota
SaveConfigDiscoveryOpt
OnlyMasterDiscoveryOpt
SlavePriorityDiscoveryOpt
ReplicationInfoDiscoveryOpt
)

func (set DiscoveryOptionSet) Has(opt DiscoveryOption) bool {
Expand Down Expand Up @@ -64,6 +66,39 @@ func (srv *RedisServer) Discover(ctx context.Context, opts ...DiscoveryOption) e
srv.Config["slave-read-only"] = slaveReadOnly
}

if DiscoveryOptionSet(opts).Has(SlavePriorityDiscoveryOpt) {
slavePriority, err := srv.RedisConfigGet(ctx, "slave-priority")
if err != nil {
logger.Error(err, fmt.Sprintf("unable to get %s|%s|%s 'slave-priority' option", srv.GetAlias(), srv.Role, srv.ID()))
return err
}
srv.Config["slave-priority"] = slavePriority
}

if DiscoveryOptionSet(opts).Has(ReplicationInfoDiscoveryOpt) && role != client.Master {
repinfo, err := srv.RedisInfo(ctx, "replication")
if err != nil {
logger.Error(err, fmt.Sprintf("unable to get %s|%s|%s replication info", srv.GetAlias(), srv.Role, srv.ID()))
return err
}

var syncInProgress string
switch flag := repinfo["master_sync_in_progress"]; flag {
case "0":
syncInProgress = "no"
case "1":
syncInProgress = "yes"
default:
logger.Error(err, fmt.Sprintf("unexpected value '%s' for 'master_sync_in_progress' %s|%s|%s", flag, srv.GetAlias(), srv.Role, srv.ID()))
syncInProgress = ""
}

if srv.Info == nil {
srv.Info = map[string]string{}
}
srv.Info["replication"] = fmt.Sprintf("master-link: %s, sync-in-progress: %s", repinfo["master_link_status"], syncInProgress)
}

return nil
}

Expand Down
1 change: 1 addition & 0 deletions pkg/redis/sharded/redis_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ type RedisServer struct {
*redis.Server
Role client.Role
Config map[string]string
Info map[string]string
}

func NewRedisServerFromPool(connectionString string, alias *string, pool *redis.ServerPool) (*RedisServer, error) {
Expand Down
32 changes: 20 additions & 12 deletions test/e2e/sentinel_suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -164,17 +164,19 @@ var _ = Describe("sentinel e2e suite", func() {
shards[0].Status.ShardNodes.GetHostPortByPodIndex(0): {
Address: shards[0].Status.ShardNodes.GetHostPortByPodIndex(0),
Role: redisclient.Master,
Config: map[string]string{"save": ""},
Config: map[string]string{"save": "", "slave-priority": "100"},
},
shards[0].Status.ShardNodes.GetHostPortByPodIndex(1): {
Address: shards[0].Status.ShardNodes.GetHostPortByPodIndex(1),
Role: redisclient.Slave,
Config: map[string]string{"save": "", "slave-read-only": "yes"},
Config: map[string]string{"save": "", "slave-read-only": "yes", "slave-priority": "100"},
Info: map[string]string{"replication": "master-link: up, sync-in-progress: no"},
},
shards[0].Status.ShardNodes.GetHostPortByPodIndex(2): {
Address: shards[0].Status.ShardNodes.GetHostPortByPodIndex(2),
Role: redisclient.Slave,
Config: map[string]string{"save": "", "slave-read-only": "yes"},
Config: map[string]string{"save": "", "slave-read-only": "yes", "slave-priority": "100"},
Info: map[string]string{"replication": "master-link: up, sync-in-progress: no"},
},
},
},
Expand All @@ -184,17 +186,19 @@ var _ = Describe("sentinel e2e suite", func() {
shards[1].Status.ShardNodes.GetHostPortByPodIndex(0): {
Address: shards[1].Status.ShardNodes.GetHostPortByPodIndex(0),
Role: redisclient.Slave,
Config: map[string]string{"save": "", "slave-read-only": "yes"},
Config: map[string]string{"save": "", "slave-read-only": "yes", "slave-priority": "100"},
Info: map[string]string{"replication": "master-link: up, sync-in-progress: no"},
},
shards[1].Status.ShardNodes.GetHostPortByPodIndex(1): {
Address: shards[1].Status.ShardNodes.GetHostPortByPodIndex(1),
Role: redisclient.Slave,
Config: map[string]string{"save": "", "slave-read-only": "yes"},
Config: map[string]string{"save": "", "slave-read-only": "yes", "slave-priority": "100"},
Info: map[string]string{"replication": "master-link: up, sync-in-progress: no"},
},
shards[1].Status.ShardNodes.GetHostPortByPodIndex(2): {
Address: shards[1].Status.ShardNodes.GetHostPortByPodIndex(2),
Role: redisclient.Master,
Config: map[string]string{"save": ""},
Config: map[string]string{"save": "", "slave-priority": "100"},
},
},
},
Expand Down Expand Up @@ -289,17 +293,19 @@ var _ = Describe("sentinel e2e suite", func() {
shards[0].Status.ShardNodes.GetHostPortByPodIndex(0): {
Address: shards[0].Status.ShardNodes.GetHostPortByPodIndex(0),
Role: redisclient.Slave,
Config: map[string]string{"save": "", "slave-read-only": "yes"},
Config: map[string]string{"save": "", "slave-read-only": "yes", "slave-priority": "100"},
Info: map[string]string{"replication": "master-link: up, sync-in-progress: no"},
},
shards[0].Status.ShardNodes.GetHostPortByPodIndex(1): {
Address: shards[0].Status.ShardNodes.GetHostPortByPodIndex(1),
Role: redisclient.Master,
Config: map[string]string{"save": ""},
Config: map[string]string{"save": "", "slave-priority": "100"},
},
shards[0].Status.ShardNodes.GetHostPortByPodIndex(2): {
Address: shards[0].Status.ShardNodes.GetHostPortByPodIndex(2),
Role: redisclient.Slave,
Config: map[string]string{"save": "", "slave-read-only": "yes"},
Config: map[string]string{"save": "", "slave-read-only": "yes", "slave-priority": "0"},
Info: map[string]string{"replication": "master-link: up, sync-in-progress: no"},
},
},
},
Expand All @@ -309,17 +315,19 @@ var _ = Describe("sentinel e2e suite", func() {
shards[1].Status.ShardNodes.GetHostPortByPodIndex(0): {
Address: shards[1].Status.ShardNodes.GetHostPortByPodIndex(0),
Role: redisclient.Slave,
Config: map[string]string{"save": "", "slave-read-only": "yes"},
Config: map[string]string{"save": "", "slave-read-only": "yes", "slave-priority": "100"},
Info: map[string]string{"replication": "master-link: up, sync-in-progress: no"},
},
shards[1].Status.ShardNodes.GetHostPortByPodIndex(1): {
Address: shards[1].Status.ShardNodes.GetHostPortByPodIndex(1),
Role: redisclient.Slave,
Config: map[string]string{"save": "", "slave-read-only": "yes"},
Config: map[string]string{"save": "", "slave-read-only": "yes", "slave-priority": "100"},
Info: map[string]string{"replication": "master-link: up, sync-in-progress: no"},
},
shards[1].Status.ShardNodes.GetHostPortByPodIndex(2): {
Address: shards[1].Status.ShardNodes.GetHostPortByPodIndex(2),
Role: redisclient.Master,
Config: map[string]string{"save": ""},
Config: map[string]string{"save": "", "slave-priority": "100"},
},
},
},
Expand Down

0 comments on commit 049461b

Please sign in to comment.