Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add useful information to the Sentinel status #271

Merged
merged 1 commit into from
Oct 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading