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

Enabling XDR dynamic config and export few functions #53

Merged
merged 9 commits into from
May 6, 2024
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
52 changes: 24 additions & 28 deletions asconfig/as_setconfig.go
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
package asconfig

import (
"container/list"
"fmt"
"strings"

aero "github.com/aerospike/aerospike-client-go/v7"
"github.com/aerospike/aerospike-management-lib/deployment"
"github.com/aerospike/aerospike-management-lib/info"
"github.com/go-logr/logr"
)

const (
cmdSetConfigNetwork = "set-config:context=network;" // ConfigNetwork
cmdSetConfigService = "set-config:context=service;" // ConfigService
cmdSetConfigNamespace = "set-config:context=namespace;id=" // ConfigNamespace
// cmdSetConfigXDR = "set-config:context=xdr" // ConfigXDR
cmdSetConfigSecurity = "set-config:context=security;" // ConfigSecurity
cmdSetLogging = "log-set:id=" // ConfigLogging
cmdSetConfigXDR = "set-config:context=xdr" // ConfigXDR
cmdSetConfigSecurity = "set-config:context=security;" // ConfigSecurity
cmdSetLogging = "log-set:id=" // ConfigLogging
)

// convertValueToString converts the value of a config to a string.
Expand Down Expand Up @@ -191,10 +193,14 @@ func createSetConfigNamespaceCmdList(tokens []string, operationValueMap map[Oper
cmd += strings.Trim(token, "{}")
}
} else {
if prevToken == "index-type" || prevToken == "sindex-type" {
switch prevToken {
case "index-type", "sindex-type":
cmd += fmt.Sprintf(";%s.%s", prevToken, token)
prevToken = ""
} else {
case "geo2dsphere-within":
cmd += fmt.Sprintf(";%s-%s", prevToken, token)
prevToken = ""
default:
prevToken = token
}
}
Expand Down Expand Up @@ -247,7 +253,6 @@ func createLogSetCmdList(tokens []string, operationValueMap map[Operation][]stri
return cmdList, nil
}

/*
// createSetConfigXDRCmdList creates set-config commands for XDR context.
func createSetConfigXDRCmdList(tokens []string, operationValueMap map[Operation][]string) []string {
cmdList := make([]string, 0, len(operationValueMap))
Expand Down Expand Up @@ -312,15 +317,15 @@ func createSetConfigXDRCmdList(tokens []string, operationValueMap map[Operation]

return cmdList
}
*/

// CreateSetConfigCmdList creates set-config commands for given config.
func CreateSetConfigCmdList(configMap DynamicConfigMap, conn deployment.ASConnInterface,
func CreateSetConfigCmdList(log logr.Logger, configMap DynamicConfigMap, conn deployment.ASConnInterface,
aerospikePolicy *aero.ClientPolicy,
) ([]string, error) {
cmdList := make([]string, 0, len(configMap))

for c := range configMap {
orderedConfList := rearrangeConfigMap(log, configMap)
for _, c := range orderedConfList {
tokens := strings.Split(c, sep)
context := tokens[0]

Expand All @@ -339,11 +344,8 @@ func CreateSetConfigCmdList(configMap DynamicConfigMap, conn deployment.ASConnIn
case info.ConfigNamespaceContext:
cmdList = append(cmdList, createSetConfigNamespaceCmdList(tokens, val)...)

/*
Commenting out XDR context for now because of ordering issues.
case info.ConfigXDRContext:
cmdList = append(cmdList, createSetConfigXDRCmdList(tokens, val)...)
*/
case info.ConfigXDRContext:
cmdList = append(cmdList, createSetConfigXDRCmdList(tokens, val)...)

case info.ConfigLoggingContext:
cmds, err := createLogSetCmdList(tokens, val, conn, aerospikePolicy)
Expand All @@ -361,7 +363,6 @@ func CreateSetConfigCmdList(configMap DynamicConfigMap, conn deployment.ASConnIn
return cmdList, nil
}

/*
// Returns a list of config keys in the order in which they should be applied.
// The order is as follows:
// 1. Removed Namespaces -- If user has to change some of the DC direct fields, they will have to remove the namespace
Expand Down Expand Up @@ -397,7 +398,7 @@ func rearrangeConfigMap(log logr.Logger, configMap DynamicConfigMap) []string {
// If namespace is removed, directly add it to the final list
finalList = append(finalList, k)
} else {
// If namespace is added, add it after all DCs and their direct fields
// If namespace is added, add it after all DCs and their direct configs
if lastDCConfig == nil {
if lastDC != nil {
rearrangedConfigMap.InsertAfter(k, lastDC)
Expand All @@ -418,23 +419,19 @@ func rearrangeConfigMap(log logr.Logger, configMap DynamicConfigMap) []string {
// Handle DC direct fields
if tokens[len(tokens)-3] == info.ConfigDCContext {
var nap *list.Element
// Check if the key is related to 'node-address-ports'
isNodeAddressPortsKey := strings.HasSuffix(k, sep+keyNodeAddressPorts)

if isNodeAddressPortsKey {
// Check if the key is 'node-address-ports'
if strings.HasSuffix(k, sep+keyNodeAddressPorts) {
if _, ok := v[Remove]; ok {
dc := rearrangedConfigMap.PushFront(k)
if lastDC == nil {
lastDC = dc
}
continue
} else {
if lastDCConfig != nil {
// Add 'node-address-ports' after all DC direct fields
// There are certain fields that must be set before 'node-address-ports', for example, 'tls-name'.
lastDCConfig = rearrangedConfigMap.InsertAfter(k, lastDCConfig)
continue
}
} else if lastDCConfig != nil {
// Add 'node-address-ports' after all DC direct fields
// There are certain fields that must be set before 'node-address-ports', for example, 'tls-name'.
lastDCConfig = rearrangedConfigMap.InsertAfter(k, lastDCConfig)
continue
}
}

Expand All @@ -459,4 +456,3 @@ func rearrangeConfigMap(log logr.Logger, configMap DynamicConfigMap) []string {

return finalList
}
*/
8 changes: 4 additions & 4 deletions asconfig/as_setconfig_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package asconfig
import (
"testing"

"github.com/go-logr/logr"
"github.com/stretchr/testify/suite"
"go.uber.org/mock/gomock"

Expand Down Expand Up @@ -62,19 +63,19 @@ func (s *AsSetConfigTestSuite) TestCreateSetConfigCmdList() {

for _, tc := range testCases {
s.Run(tc.name, func() {
logger := logr.Discard()
policy := &aero.ClientPolicy{}

s.mockASConn.EXPECT().RunInfo(gomock.Any(), gomock.Any()).Return(map[string]string{
"logs": "0:stderr"}, nil).AnyTimes()
result, err := CreateSetConfigCmdList(tc.inputConf, s.mockASConn, policy)
result, err := CreateSetConfigCmdList(logger, tc.inputConf, s.mockASConn, policy)

s.Assert().Nil(err)
s.Assert().True(gomock.InAnyOrder(result).Matches(tc.expected))
})
}
}

/*
func (s *AsSetConfigTestSuite) TestCreateSetConfigCmdListOrdered() {
testCases := []struct {
name string
Expand All @@ -87,7 +88,7 @@ func (s *AsSetConfigTestSuite) TestCreateSetConfigCmdListOrdered() {
"xdr.dcs.{DC1}.namespaces.{ns1}.bin-policy": {Update: "no-bins"},
"xdr.dcs.{DC3}.name": {Add: "DC3"},
"xdr.dcs.{DC1}.namespaces.{ns2}.name": {Remove: "ns2"},
"xdr.dcs.{DC1}.node-address-ports": {Add: []string{"1.1.1.1:3000:tls-name"},
"xdr.dcs.{DC1}.node-address-ports": {Add: []string{"1.1.1.1:3000:tls-name"}},
"xdr.dcs.{DC1}.namespaces.{ns1}.name": {Add: "ns1"},
"xdr.dcs.{DC1}.tls-name": {Update: "tls-name"},
},
Expand All @@ -114,7 +115,6 @@ func (s *AsSetConfigTestSuite) TestCreateSetConfigCmdListOrdered() {
})
}
}
*/

func TestAsSetConfigTestSuite(t *testing.T) {
suite.Run(t, new(AsSetConfigTestSuite))
Expand Down
24 changes: 12 additions & 12 deletions asconfig/schema.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,9 @@ func baseVersion(ver string) (string, error) {
return baseVersion, nil
}

// getDynamic return the map of values which are dynamic
// GetDynamic return the map of values which are dynamic
// values.
func getDynamic(ver string) (sets.Set[string], error) {
func GetDynamic(ver string) (sets.Set[string], error) {
flatSchema, err := getFlatSchema(ver)
if err != nil {
return nil, err
Expand Down Expand Up @@ -178,34 +178,34 @@ func getDynamicSchema(flatSchema map[string]interface{}) sets.Set[string] {

// IsAllDynamicConfig returns true if all the fields in the given configMap are dynamically configured.
func IsAllDynamicConfig(log logr.Logger, configMap DynamicConfigMap, version string) (bool, error) {
dynamic, err := getDynamic(version)
dynamic, err := GetDynamic(version)
if err != nil {
// retry error fall back to rolling restart.
return false, err
}

for confKey := range configMap {
if !isDynamicConfig(log, dynamic, confKey, configMap[confKey]) {
if !IsDynamicConfig(log, dynamic, confKey, configMap[confKey]) {
return false, nil
}
}

return true, nil
}

// isDynamicConfig returns true if the given field is dynamically configured.
func isDynamicConfig(log logr.Logger, dynamic sets.Set[string], conf string,
// IsDynamicConfig returns true if the given field is dynamically configured.
func IsDynamicConfig(log logr.Logger, dynamic sets.Set[string], conf string,
valueMap map[Operation]interface{}) bool {
tokens := SplitKey(log, conf, sep)
baseKey := tokens[len(tokens)-1]
context := tokens[0]

if context == info.ConfigXDRContext {
// XDR context is always considered static.
return false
if baseKey == "replication-factor" || baseKey == keyNodeAddressPorts {
return true
}

if baseKey == "replication-factor" {
// Name key for XDR context is considered as dynamic, as both DCs and Namespaces in DCs can be added dynamically.
if context == info.ConfigXDRContext && baseKey == KeyName {
return true
}

Expand All @@ -223,14 +223,14 @@ func isDynamicConfig(log logr.Logger, dynamic sets.Set[string], conf string,
}
}

return dynamic.Contains(getFlatKey(tokens))
return dynamic.Contains(GetFlatKey(tokens))
}

// getDefaultValue returns the default value of a particular config
func getDefaultValue(defaultMap map[string]interface{}, conf string) interface{} {
tokens := strings.Split(conf, ".")

return defaultMap[getFlatKey(tokens)]
return defaultMap[GetFlatKey(tokens)]
}

// GetDefault return the map of default values.
Expand Down
2 changes: 1 addition & 1 deletion asconfig/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -1073,7 +1073,7 @@ func getContextAndName(log logr.Logger, key, _ string) (context, name string) {
return strings.Trim(ctx, "/"), keys[len(keys)-1]
}

func getFlatKey(tokens []string) string {
func GetFlatKey(tokens []string) string {
var key string

for _, token := range tokens {
Expand Down
10 changes: 10 additions & 0 deletions deployment/aeroinfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,16 @@ func InfoQuiesceUndo(log logr.Logger, policy *aero.ClientPolicy, allHosts []*Hos
return c.InfoQuiesceUndo(getHostIDsFromHostConns(allHosts))
}

// InfoRecluster recluster hosts.
func InfoRecluster(log logr.Logger, policy *aero.ClientPolicy, allHosts []*HostConn) error {
c, err := newCluster(log, policy, allHosts, allHosts)
if err != nil {
return fmt.Errorf("unable to create a cluster copy for running aeroinfo: %v", err)
}

return c.InfoRecluster(getHostIDsFromHostConns(allHosts))
}

// GetQuiescedNodes returns a list of node hostIDs of all nodes that are pending_quiesce=true.
func GetQuiescedNodes(log logr.Logger, policy *aero.ClientPolicy, allHosts []*HostConn) ([]string, error) {
c, err := newCluster(log, policy, allHosts, allHosts)
Expand Down
6 changes: 3 additions & 3 deletions deployment/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ func (c *cluster) InfoQuiesce(hostsToBeQuiesced, hostIDs, removedNamespaces []st
}
}

if err := c.infoRecluster(hostIDs); err != nil {
if err := c.InfoRecluster(hostIDs); err != nil {
return err
}

Expand Down Expand Up @@ -718,10 +718,10 @@ func (c *cluster) InfoQuiesceUndo(hostIDs []string) error {
}
}

return c.infoRecluster(hostIDs)
return c.InfoRecluster(hostIDs)
}

func (c *cluster) infoRecluster(hostIDs []string) error {
func (c *cluster) InfoRecluster(hostIDs []string) error {
lg := c.log.WithValues("nodes", hostIDs)

lg.V(1).Info("Running recluster command")
Expand Down
29 changes: 18 additions & 11 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,47 +6,54 @@ require (
github.com/aerospike/aerospike-client-go/v7 v7.1.0
github.com/deckarep/golang-set/v2 v2.3.1
github.com/docker/go-connections v0.4.0
github.com/go-logr/logr v1.2.4
github.com/go-logr/logr v1.4.1
github.com/xeipuuv/gojsonschema v1.2.0
go.uber.org/mock v0.3.0
k8s.io/apimachinery v0.27.2
k8s.io/apimachinery v0.29.0
)

require (
github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/containerd/log v0.1.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/distribution/reference v0.5.0 // indirect
github.com/docker/distribution v2.8.3+incompatible // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/moby/docker-image-spec v1.3.1 // indirect
github.com/moby/term v0.5.0 // indirect
github.com/morikuni/aec v1.0.0 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.0.2 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rogpeppe/go-internal v1.12.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.50.0 // indirect
go.opentelemetry.io/otel v1.25.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.25.0 // indirect
go.opentelemetry.io/otel/metric v1.25.0 // indirect
go.opentelemetry.io/otel/sdk v1.25.0 // indirect
go.opentelemetry.io/otel/trace v1.25.0 // indirect
golang.org/x/mod v0.13.0 // indirect
golang.org/x/time v0.5.0 // indirect
golang.org/x/tools v0.14.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20231127180814-3a041ad873d4 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
gotest.tools/v3 v3.5.1 // indirect
)

require (
github.com/docker/docker v24.0.7+incompatible
github.com/golang/protobuf v1.5.3 // indirect
github.com/stretchr/testify v1.8.4
github.com/docker/docker v26.1.0+incompatible
github.com/stretchr/testify v1.9.0
github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/yuin/gopher-lua v1.1.1 // indirect
golang.org/x/net v0.20.0 // indirect
golang.org/x/net v0.24.0 // indirect
golang.org/x/sync v0.6.0 // indirect
golang.org/x/sys v0.16.0 // indirect
golang.org/x/sys v0.19.0 // indirect
golang.org/x/text v0.14.0 // indirect
google.golang.org/grpc v1.59.0 // indirect
google.golang.org/grpc v1.63.0 // indirect
google.golang.org/protobuf v1.33.0 // indirect
)
Loading
Loading