diff --git a/vclusterops/add_node.go b/vclusterops/add_node.go index 5f88890..bbca681 100644 --- a/vclusterops/add_node.go +++ b/vclusterops/add_node.go @@ -47,13 +47,13 @@ type VAddNodeOptions struct { func VAddNodeOptionsFactory() VAddNodeOptions { opt := VAddNodeOptions{} // set default values to the params - opt.setDefaultValues() + opt.SetDefaultValues() return opt } -func (o *VAddNodeOptions) setDefaultValues() { - o.DatabaseOptions.setDefaultValues() +func (o *VAddNodeOptions) SetDefaultValues() { + o.DatabaseOptions.SetDefaultValues() o.SCName = new(string) o.SkipRebalanceShards = new(bool) @@ -81,7 +81,7 @@ func (o *VAddNodeOptions) validateExtraOptions() error { func (o *VAddNodeOptions) validateParseOptions(log vlog.Printer) error { // batch 1: validate required parameters - err := o.validateBaseOptions("db_add_node", log) + err := o.ValidateBaseOptions("db_add_node", log) if err != nil { return err } @@ -129,7 +129,7 @@ func (vcc *VClusterCommands) VAddNode(options *VAddNodeOptions) (VCoordinationDa } // get hosts from config file and options. - hosts, err := options.getHosts(options.Config) + hosts, err := options.GetHosts(options.Config) if err != nil { return vdb, err } @@ -179,7 +179,7 @@ func (vcc *VClusterCommands) VAddNode(options *VAddNodeOptions) (VCoordinationDa return vdb, err } - err = vdb.addHosts(options.NewHosts, *options.SCName) + err = vdb.addHosts(options.NewHosts) if err != nil { return vdb, err } @@ -190,8 +190,8 @@ func (vcc *VClusterCommands) VAddNode(options *VAddNodeOptions) (VCoordinationDa } certs := HTTPSCerts{key: options.Key, cert: options.Cert, caCert: options.CaCert} - clusterOpEngine := makeClusterOpEngine(instructions, &certs) - if runError := clusterOpEngine.run(vcc.Log); runError != nil { + clusterOpEngine := MakeClusterOpEngine(instructions, &certs) + if runError := clusterOpEngine.Run(vcc.Log); runError != nil { return vdb, fmt.Errorf("fail to complete add node operation, %w", runError) } return vdb, nil @@ -299,8 +299,8 @@ func (vcc *VClusterCommands) trimNodesInCatalog(vdb *VCoordinationDatabase, } certs := HTTPSCerts{key: options.Key, cert: options.Cert, caCert: options.CaCert} - clusterOpEngine := makeClusterOpEngine(instructions, &certs) - err := clusterOpEngine.run(vcc.Log) + clusterOpEngine := MakeClusterOpEngine(instructions, &certs) + err := clusterOpEngine.Run(vcc.Log) if err != nil { vcc.Log.Error(err, "fail to trim nodes from catalog, %v") return err @@ -319,9 +319,9 @@ func (vcc *VClusterCommands) trimNodesInCatalog(vdb *VCoordinationDatabase, // The generated instructions will later perform the following operations necessary // for a successful add_node: // - Check NMA connectivity +// - Check NMA versions // - If we have subcluster in the input, check if the subcluster exists. If not, we stop. // If we do not have a subcluster in the input, fetch the current default subcluster name -// - Check NMA versions // - Prepare directories // - Get network profiles // - Create the new node @@ -343,7 +343,11 @@ func (vcc *VClusterCommands) produceAddNodeInstructions(vdb *VCoordinationDataba password := options.Password nmaHealthOp := makeNMAHealthOp(vcc.Log, vdb.HostList) - instructions = append(instructions, &nmaHealthOp) + // require to have the same vertica version + nmaVerticaVersionOp := makeNMAVerticaVersionOp(vcc.Log, vdb.HostList, true) + instructions = append(instructions, + &nmaHealthOp, + &nmaVerticaVersionOp) if vdb.IsEon { httpsFindSubclusterOp, e := makeHTTPSFindSubclusterOp( @@ -355,10 +359,6 @@ func (vcc *VClusterCommands) produceAddNodeInstructions(vdb *VCoordinationDataba instructions = append(instructions, &httpsFindSubclusterOp) } - // require to have the same vertica version - nmaVerticaVersionOp := makeNMAVerticaVersionOpWithVDB(vcc.Log, true, vdb) - instructions = append(instructions, &nmaVerticaVersionOp) - // this is a copy of the original HostNodeMap that only // contains the hosts to add. newHostNodeMap := vdb.copyHostNodeMap(options.NewHosts) diff --git a/vclusterops/add_subcluster.go b/vclusterops/add_subcluster.go index d9a6fd0..6a50844 100644 --- a/vclusterops/add_subcluster.go +++ b/vclusterops/add_subcluster.go @@ -55,13 +55,13 @@ type VAddSubclusterInfo struct { func VAddSubclusterOptionsFactory() VAddSubclusterOptions { opt := VAddSubclusterOptions{} // set default values to the params - opt.setDefaultValues() + opt.SetDefaultValues() return opt } -func (options *VAddSubclusterOptions) setDefaultValues() { - options.DatabaseOptions.setDefaultValues() +func (options *VAddSubclusterOptions) SetDefaultValues() { + options.DatabaseOptions.SetDefaultValues() options.SCName = new(string) options.IsPrimary = new(bool) @@ -71,7 +71,7 @@ func (options *VAddSubclusterOptions) setDefaultValues() { } func (options *VAddSubclusterOptions) validateRequiredOptions(log vlog.Printer) error { - err := options.validateBaseOptions("db_add_subcluster", log) + err := options.ValidateBaseOptions("db_add_subcluster", log) if err != nil { return err } @@ -83,7 +83,7 @@ func (options *VAddSubclusterOptions) validateRequiredOptions(log vlog.Printer) } func (options *VAddSubclusterOptions) validateEonOptions(config *ClusterConfig) error { - isEon, err := options.isEonMode(config) + isEon, err := options.IsEonMode(config) if err != nil { return err } @@ -169,7 +169,7 @@ func (options *VAddSubclusterOptions) analyzeOptions() (err error) { return nil } -func (options *VAddSubclusterOptions) validateAnalyzeOptions(config *ClusterConfig, vcc *VClusterCommands) error { +func (options *VAddSubclusterOptions) ValidateAnalyzeOptions(config *ClusterConfig, vcc *VClusterCommands) error { if err := options.validateParseOptions(config, vcc); err != nil { return err } @@ -184,7 +184,7 @@ func (vcc *VClusterCommands) VAddSubcluster(options *VAddSubclusterOptions) erro * - Give the instructions to the VClusterOpEngine to run */ - err := options.validateAnalyzeOptions(options.Config, vcc) + err := options.ValidateAnalyzeOptions(options.Config, vcc) if err != nil { return err } @@ -199,7 +199,7 @@ func (vcc *VClusterCommands) VAddSubcluster(options *VAddSubclusterOptions) erro ControlSetSize: *options.ControlSetSize, CloneSC: *options.CloneSC, } - addSubclusterInfo.DBName, addSubclusterInfo.Hosts, err = options.getNameAndHosts(options.Config) + addSubclusterInfo.DBName, addSubclusterInfo.Hosts, err = options.GetNameAndHosts(options.Config) if err != nil { return err } @@ -211,10 +211,10 @@ func (vcc *VClusterCommands) VAddSubcluster(options *VAddSubclusterOptions) erro // Create a VClusterOpEngine, and add certs to the engine certs := HTTPSCerts{key: options.Key, cert: options.Cert, caCert: options.CaCert} - clusterOpEngine := makeClusterOpEngine(instructions, &certs) + clusterOpEngine := MakeClusterOpEngine(instructions, &certs) // Give the instructions to the VClusterOpEngine to run - runError := clusterOpEngine.run(vcc.Log) + runError := clusterOpEngine.Run(vcc.Log) if runError != nil { return fmt.Errorf("fail to add subcluster %s, %w", addSubclusterInfo.SCName, runError) } @@ -241,7 +241,7 @@ func (vcc *VClusterCommands) produceAddSubclusterInstructions(addSubclusterInfo usePassword := false if addSubclusterInfo.Password != nil { usePassword = true - err := options.validateUserName(vcc.Log) + err := options.ValidateUserName(vcc.Log) if err != nil { return instructions, err } diff --git a/vclusterops/cluster_config.go b/vclusterops/cluster_config.go index 8bc9295..189193c 100644 --- a/vclusterops/cluster_config.go +++ b/vclusterops/cluster_config.go @@ -138,7 +138,7 @@ func (c *ClusterConfig) GetPathPrefix(dbName string) (catalogPrefix string, dbConfig.Nodes[0].DepotPath, nil } -func (c *DatabaseConfig) getHosts() []string { +func (c *DatabaseConfig) GetHosts() []string { var hostList []string for _, vnode := range c.Nodes { diff --git a/vclusterops/cluster_op.go b/vclusterops/cluster_op.go index 70b5ea8..bb12728 100644 --- a/vclusterops/cluster_op.go +++ b/vclusterops/cluster_op.go @@ -95,18 +95,18 @@ const respSuccStatusCode = 0 // 3. The local node has not yet joined the cluster; the HTTP server will accept connections once the node joins the cluster. // HTTPCheckDBRunningOp in create_db need to check all scenarios to see any HTTP running // For HTTPSPollNodeStateOp in start_db, it requires only handling the first and second scenarios -func (hostResult *HostHTTPResult) isUnauthorizedRequest() bool { +func (hostResult *HostHTTPResult) IsUnauthorizedRequest() bool { return hostResult.statusCode == UnauthorizedCode } -// isSuccess returns true if status code is 200 -func (hostResult *HostHTTPResult) isSuccess() bool { +// IsSuccess returns true if status code is 200 +func (hostResult *HostHTTPResult) IsSuccess() bool { return hostResult.statusCode == SuccessCode } // check only password and certificate for start_db -func (hostResult *HostHTTPResult) isPasswordAndCertificateError(log vlog.Printer) bool { - if !hostResult.isUnauthorizedRequest() { +func (hostResult *HostHTTPResult) IsPasswordAndCertificateError(log vlog.Printer) bool { + if !hostResult.IsUnauthorizedRequest() { return false } resultString := fmt.Sprintf("%v", hostResult) @@ -119,12 +119,12 @@ func (hostResult *HostHTTPResult) isPasswordAndCertificateError(log vlog.Printer return false } -func (hostResult *HostHTTPResult) isInternalError() bool { +func (hostResult *HostHTTPResult) IsInternalError() bool { return hostResult.statusCode == InternalErrorCode } -func (hostResult *HostHTTPResult) isHTTPRunning() bool { - if hostResult.isPassing() || hostResult.isUnauthorizedRequest() || hostResult.isInternalError() { +func (hostResult *HostHTTPResult) IsHTTPRunning() bool { + if hostResult.isPassing() || hostResult.IsUnauthorizedRequest() || hostResult.IsInternalError() { return true } return false diff --git a/vclusterops/cluster_op_engine.go b/vclusterops/cluster_op_engine.go index 1611cee..22db09d 100644 --- a/vclusterops/cluster_op_engine.go +++ b/vclusterops/cluster_op_engine.go @@ -27,7 +27,7 @@ type VClusterOpEngine struct { execContext *OpEngineExecContext } -func makeClusterOpEngine(instructions []ClusterOp, certs *HTTPSCerts) VClusterOpEngine { +func MakeClusterOpEngine(instructions []ClusterOp, certs *HTTPSCerts) VClusterOpEngine { newClusterOpEngine := VClusterOpEngine{} newClusterOpEngine.instructions = instructions newClusterOpEngine.certs = certs @@ -38,8 +38,8 @@ func (opEngine *VClusterOpEngine) shouldGetCertsFromOptions() bool { return (opEngine.certs.key != "" && opEngine.certs.cert != "" && opEngine.certs.caCert != "") } -func (opEngine *VClusterOpEngine) run(log vlog.Printer) error { - execContext := makeOpEngineExecContext(log) +func (opEngine *VClusterOpEngine) Run(log vlog.Printer) error { + execContext := MakeOpEngineExecContext(log) opEngine.execContext = &execContext findCertsInOptions := opEngine.shouldGetCertsFromOptions() diff --git a/vclusterops/cluster_op_engine_context.go b/vclusterops/cluster_op_engine_context.go index ef01323..82c8028 100644 --- a/vclusterops/cluster_op_engine_context.go +++ b/vclusterops/cluster_op_engine_context.go @@ -29,9 +29,9 @@ type OpEngineExecContext struct { dbInfo string // store the db info that retrieved from communal storage } -func makeOpEngineExecContext(log vlog.Printer) OpEngineExecContext { +func MakeOpEngineExecContext(log vlog.Printer) OpEngineExecContext { newOpEngineExecContext := OpEngineExecContext{} - newOpEngineExecContext.dispatcher = makeHTTPRequestDispatcher(log) + newOpEngineExecContext.dispatcher = MakeHTTPRequestDispatcher(log) return newOpEngineExecContext } diff --git a/vclusterops/cluster_op_engine_test.go b/vclusterops/cluster_op_engine_test.go index 8222751..d871909 100644 --- a/vclusterops/cluster_op_engine_test.go +++ b/vclusterops/cluster_op_engine_test.go @@ -74,8 +74,8 @@ func TestSkipExecuteOp(t *testing.T) { opWithSkipDisabled := makeMockOp(false) instructions := []ClusterOp{&opWithSkipDisabled, &opWithSkipEnabled} certs := HTTPSCerts{key: "key", cert: "cert", caCert: "ca-cert"} - opEngn := makeClusterOpEngine(instructions, &certs) - err := opEngn.run(vlog.Printer{}) + opEngn := MakeClusterOpEngine(instructions, &certs) + err := opEngn.Run(vlog.Printer{}) assert.Equal(t, nil, err) assert.True(t, opWithSkipDisabled.calledPrepare) assert.True(t, opWithSkipDisabled.calledExecute) diff --git a/vclusterops/coordinator_database.go b/vclusterops/coordinator_database.go index 29ae32e..4f961ac 100644 --- a/vclusterops/coordinator_database.go +++ b/vclusterops/coordinator_database.go @@ -72,9 +72,9 @@ func MakeVCoordinationDatabase() VCoordinationDatabase { return VCoordinationDatabase{} } -func (vdb *VCoordinationDatabase) setFromCreateDBOptions(options *VCreateDatabaseOptions, log vlog.Printer) error { +func (vdb *VCoordinationDatabase) SetFromCreateDBOptions(options *VCreateDatabaseOptions, log vlog.Printer) error { // build after validating the options - err := options.validateAnalyzeOptions(log) + err := options.ValidateAnalyzeOptions(log) if err != nil { return err } @@ -103,7 +103,7 @@ func (vdb *VCoordinationDatabase) setFromCreateDBOptions(options *VCreateDatabas vdb.UseDepot = true } if *options.GetAwsCredentialsFromEnv { - err := vdb.getAwsCredentialsFromEnv() + err := vdb.GetAwsCredentialsFromEnv() if err != nil { return err } @@ -113,7 +113,7 @@ func (vdb *VCoordinationDatabase) setFromCreateDBOptions(options *VCreateDatabas // section 3: build VCoordinationNode info for _, host := range vdb.HostList { vNode := MakeVCoordinationNode() - err := vNode.setFromCreateDBOptions(options, host) + err := vNode.SetFromCreateDBOptions(options, host) if err != nil { return err } @@ -138,7 +138,7 @@ func (vdb *VCoordinationDatabase) addNode(vnode *VCoordinationNode) error { // addHosts adds a given list of hosts to the VDB's HostList // and HostNodeMap. -func (vdb *VCoordinationDatabase) addHosts(hosts []string, scName string) error { +func (vdb *VCoordinationDatabase) addHosts(hosts []string) error { totalHostCount := len(hosts) + len(vdb.HostList) nodeNameToHost := vdb.genNodeNameToHostMap() for _, host := range hosts { @@ -149,11 +149,10 @@ func (vdb *VCoordinationDatabase) addHosts(hosts []string, scName string) error } nodeNameToHost[name] = host nodeConfig := NodeConfig{ - Address: host, - Name: name, - Subcluster: scName, + Address: host, + Name: name, } - vNode.setFromNodeConfig(&nodeConfig, vdb) + vNode.SetFromNodeConfig(&nodeConfig, vdb) err := vdb.addNode(&vNode) if err != nil { return err @@ -163,7 +162,7 @@ func (vdb *VCoordinationDatabase) addHosts(hosts []string, scName string) error return nil } -func (vdb *VCoordinationDatabase) setFromClusterConfig(dbName string, +func (vdb *VCoordinationDatabase) SetFromClusterConfig(dbName string, clusterConfig *ClusterConfig) error { // we trust the information in the config file // so we do not perform validation here @@ -191,7 +190,7 @@ func (vdb *VCoordinationDatabase) setFromClusterConfig(dbName string, vdb.HostNodeMap = makeVHostNodeMap() for _, nodeConfig := range dbConfig.Nodes { vnode := VCoordinationNode{} - vnode.setFromNodeConfig(nodeConfig, vdb) + vnode.SetFromNodeConfig(nodeConfig, vdb) err = vdb.addNode(&vnode) if err != nil { return err @@ -201,10 +200,10 @@ func (vdb *VCoordinationDatabase) setFromClusterConfig(dbName string, return nil } -// copy copies the receiver's fields into a new VCoordinationDatabase struct and +// Copy copies the receiver's fields into a new VCoordinationDatabase struct and // returns that struct. You can choose to copy only a subset of the receiver's hosts // by passing a slice of hosts to keep. -func (vdb *VCoordinationDatabase) copy(targetHosts []string) VCoordinationDatabase { +func (vdb *VCoordinationDatabase) Copy(targetHosts []string) VCoordinationDatabase { v := VCoordinationDatabase{ Name: vdb.Name, CatalogPrefix: vdb.CatalogPrefix, @@ -317,7 +316,7 @@ func (vdb *VCoordinationDatabase) genCatalogPath(nodeName string) string { } // set aws id key and aws secret key -func (vdb *VCoordinationDatabase) getAwsCredentialsFromEnv() error { +func (vdb *VCoordinationDatabase) GetAwsCredentialsFromEnv() error { awsIDKey := os.Getenv("AWS_ACCESS_KEY_ID") if awsIDKey == "" { return fmt.Errorf("unable to get AWS ID key from environment variable") @@ -372,7 +371,7 @@ func MakeVCoordinationNode() VCoordinationNode { return VCoordinationNode{} } -func (vnode *VCoordinationNode) setFromCreateDBOptions( +func (vnode *VCoordinationNode) SetFromCreateDBOptions( options *VCreateDatabaseOptions, host string, ) error { @@ -408,12 +407,11 @@ func (vnode *VCoordinationNode) setFromCreateDBOptions( return fmt.Errorf("fail to set up vnode from options: host %s does not exist in options", host) } -func (vnode *VCoordinationNode) setFromNodeConfig(nodeConfig *NodeConfig, vdb *VCoordinationDatabase) { +func (vnode *VCoordinationNode) SetFromNodeConfig(nodeConfig *NodeConfig, vdb *VCoordinationDatabase) { // we trust the information in the config file // so we do not perform validation here vnode.Address = nodeConfig.Address vnode.Name = nodeConfig.Name - vnode.Subcluster = nodeConfig.Subcluster vnode.CatalogPath = vdb.genCatalogPath(vnode.Name) dataPath := vdb.genDataPath(vnode.Name) vnode.StorageLocations = append(vnode.StorageLocations, dataPath) diff --git a/vclusterops/create_db.go b/vclusterops/create_db.go index b154267..04ec7ba 100644 --- a/vclusterops/create_db.go +++ b/vclusterops/create_db.go @@ -60,12 +60,12 @@ type VCreateDatabaseOptions struct { func VCreateDatabaseOptionsFactory() VCreateDatabaseOptions { opt := VCreateDatabaseOptions{} // set default values to the params - opt.setDefaultValues() + opt.SetDefaultValues() return opt } -func (opt *VCreateDatabaseOptions) setDefaultValues() { - opt.DatabaseOptions.setDefaultValues() +func (opt *VCreateDatabaseOptions) SetDefaultValues() { + opt.DatabaseOptions.SetDefaultValues() // basic db info defaultPolicy := util.DefaultRestartPolicy @@ -106,8 +106,8 @@ func (opt *VCreateDatabaseOptions) setDefaultValues() { opt.SkipStartupPolling = new(bool) } -func (opt *VCreateDatabaseOptions) checkNilPointerParams() error { - if err := opt.DatabaseOptions.checkNilPointerParams(); err != nil { +func (opt *VCreateDatabaseOptions) CheckNilPointerParams() error { + if err := opt.DatabaseOptions.CheckNilPointerParams(); err != nil { return err } @@ -136,10 +136,10 @@ func (opt *VCreateDatabaseOptions) checkNilPointerParams() error { return util.ParamNotSetErrorMsg("get-aws-credentials-from-env-vars") } - return opt.checkExtraNilPointerParams() + return opt.CheckExtraNilPointerParams() } -func (opt *VCreateDatabaseOptions) checkExtraNilPointerParams() error { +func (opt *VCreateDatabaseOptions) CheckExtraNilPointerParams() error { // optional params if opt.ForceCleanupOnFailure == nil { return util.ParamNotSetErrorMsg("force-cleanup-on-failure") @@ -315,13 +315,13 @@ func (opt *VCreateDatabaseOptions) validateExtraOptions() error { func (opt *VCreateDatabaseOptions) validateParseOptions(log vlog.Printer) error { // check nil pointers in the required options - err := opt.checkNilPointerParams() + err := opt.CheckNilPointerParams() if err != nil { return err } // validate base options - err = opt.validateBaseOptions("create_db", log) + err = opt.ValidateBaseOptions("create_db", log) if err != nil { return err } @@ -366,7 +366,7 @@ func (opt *VCreateDatabaseOptions) analyzeOptions() error { return nil } -func (opt *VCreateDatabaseOptions) validateAnalyzeOptions(log vlog.Printer) error { +func (opt *VCreateDatabaseOptions) ValidateAnalyzeOptions(log vlog.Printer) error { if err := opt.validateParseOptions(log); err != nil { return err } @@ -383,7 +383,7 @@ func (vcc *VClusterCommands) VCreateDatabase(options *VCreateDatabaseOptions) (V */ // Analyze to produce vdb info, for later create db use and for cache db info vdb := MakeVCoordinationDatabase() - err := vdb.setFromCreateDBOptions(options, vcc.Log) + err := vdb.SetFromCreateDBOptions(options, vcc.Log) if err != nil { return vdb, err } @@ -396,10 +396,10 @@ func (vcc *VClusterCommands) VCreateDatabase(options *VCreateDatabaseOptions) (V // create a VClusterOpEngine, and add certs to the engine certs := HTTPSCerts{key: options.Key, cert: options.Cert, caCert: options.CaCert} - clusterOpEngine := makeClusterOpEngine(instructions, &certs) + clusterOpEngine := MakeClusterOpEngine(instructions, &certs) // Give the instructions to the VClusterOpEngine to run - err = clusterOpEngine.run(vcc.Log) + err = clusterOpEngine.Run(vcc.Log) if err != nil { vcc.Log.Error(err, "fail to create database") return vdb, err @@ -466,10 +466,10 @@ func (vcc *VClusterCommands) produceCreateDBBootstrapInstructions( nmaHealthOp := makeNMAHealthOp(vcc.Log, hosts) // require to have the same vertica version - nmaVerticaVersionOp := makeNMAVerticaVersionOp(vcc.Log, hosts, true, vdb.IsEon) + nmaVerticaVersionOp := makeNMAVerticaVersionOp(vcc.Log, hosts, true) // need username for https operations - err := options.validateUserName(vcc.Log) + err := options.ValidateUserName(vcc.Log) if err != nil { return instructions, err } diff --git a/vclusterops/drop_db.go b/vclusterops/drop_db.go index 4861e40..62f12c8 100644 --- a/vclusterops/drop_db.go +++ b/vclusterops/drop_db.go @@ -32,7 +32,7 @@ type VDropDatabaseOptions struct { func VDropDatabaseOptionsFactory() VDropDatabaseOptions { opt := VDropDatabaseOptions{} // set default values to the params - opt.setDefaultValues() + opt.SetDefaultValues() return opt } @@ -48,7 +48,7 @@ func (options *VDropDatabaseOptions) AnalyzeOptions() error { return nil } -func (options *VDropDatabaseOptions) validateAnalyzeOptions() error { +func (options *VDropDatabaseOptions) ValidateAnalyzeOptions() error { if *options.DBName == "" { return fmt.Errorf("database name must be provided") } @@ -62,7 +62,7 @@ func (vcc *VClusterCommands) VDropDatabase(options *VDropDatabaseOptions) error * - Give the instructions to the VClusterOpEngine to run */ - err := options.validateAnalyzeOptions() + err := options.ValidateAnalyzeOptions() if err != nil { return err } @@ -89,7 +89,7 @@ func (vcc *VClusterCommands) VDropDatabase(options *VDropDatabaseOptions) error if err != nil { return err } - err = vdb.setFromClusterConfig(*options.DBName, &clusterConfig) + err = vdb.SetFromClusterConfig(*options.DBName, &clusterConfig) if err != nil { return err } @@ -102,10 +102,10 @@ func (vcc *VClusterCommands) VDropDatabase(options *VDropDatabaseOptions) error // create a VClusterOpEngine, and add certs to the engine certs := HTTPSCerts{key: options.Key, cert: options.Cert, caCert: options.CaCert} - clusterOpEngine := makeClusterOpEngine(instructions, &certs) + clusterOpEngine := MakeClusterOpEngine(instructions, &certs) // give the instructions to the VClusterOpEngine to run - runError := clusterOpEngine.run(vcc.Log) + runError := clusterOpEngine.Run(vcc.Log) if runError != nil { return fmt.Errorf("fail to drop database: %w", runError) } @@ -126,6 +126,7 @@ func (vcc *VClusterCommands) VDropDatabase(options *VDropDatabaseOptions) error // The generated instructions will later perform the following operations necessary // for a successful drop_db: // - Check NMA connectivity +// - Check Vertica versions // - Check to see if any dbs running // - Delete directories func (vcc *VClusterCommands) produceDropDBInstructions(vdb *VCoordinationDatabase, options *VDropDatabaseOptions) ([]ClusterOp, error) { @@ -135,7 +136,7 @@ func (vcc *VClusterCommands) produceDropDBInstructions(vdb *VCoordinationDatabas usePassword := false if options.Password != nil { usePassword = true - err := options.validateUserName(vcc.Log) + err := options.ValidateUserName(vcc.Log) if err != nil { return instructions, err } @@ -143,6 +144,9 @@ func (vcc *VClusterCommands) produceDropDBInstructions(vdb *VCoordinationDatabas nmaHealthOp := makeNMAHealthOp(vcc.Log, hosts) + // require to have the same vertica version + nmaVerticaVersionOp := makeNMAVerticaVersionOp(vcc.Log, hosts, true) + // when checking the running database, // drop_db has the same checking items with create_db checkDBRunningOp, err := makeHTTPCheckRunningDBOp(vcc.Log, hosts, usePassword, @@ -158,6 +162,7 @@ func (vcc *VClusterCommands) produceDropDBInstructions(vdb *VCoordinationDatabas instructions = append(instructions, &nmaHealthOp, + &nmaVerticaVersionOp, &checkDBRunningOp, &nmaDeleteDirectoriesOp, ) diff --git a/vclusterops/fetch_node_state.go b/vclusterops/fetch_node_state.go index 2dcfcb6..7570fbc 100644 --- a/vclusterops/fetch_node_state.go +++ b/vclusterops/fetch_node_state.go @@ -13,7 +13,7 @@ type VFetchNodeStateOptions struct { func VFetchNodeStateOptionsFactory() VFetchNodeStateOptions { opt := VFetchNodeStateOptions{} // set default values to the params - opt.setDefaultValues() + opt.SetDefaultValues() return opt } @@ -40,7 +40,7 @@ func (options *VFetchNodeStateOptions) analyzeOptions() error { return nil } -func (options *VFetchNodeStateOptions) validateAnalyzeOptions(vcc *VClusterCommands) error { +func (options *VFetchNodeStateOptions) ValidateAnalyzeOptions(vcc *VClusterCommands) error { if err := options.validateParseOptions(vcc); err != nil { return err } @@ -55,7 +55,7 @@ func (vcc *VClusterCommands) VFetchNodeState(options *VFetchNodeStateOptions) ([ * - Give the instructions to the VClusterOpEngine to run */ - err := options.validateAnalyzeOptions(vcc) + err := options.ValidateAnalyzeOptions(vcc) if err != nil { return nil, err } @@ -70,10 +70,10 @@ func (vcc *VClusterCommands) VFetchNodeState(options *VFetchNodeStateOptions) ([ // create a VClusterOpEngine, and add certs to the engine certs := HTTPSCerts{key: options.Key, cert: options.Cert, caCert: options.CaCert} - clusterOpEngine := makeClusterOpEngine(instructions, &certs) + clusterOpEngine := MakeClusterOpEngine(instructions, &certs) // Give the instructions to the VClusterOpEngine to run - runError := clusterOpEngine.run(vcc.Log) + runError := clusterOpEngine.Run(vcc.Log) nodeStates := clusterOpEngine.execContext.nodesInfo return nodeStates, runError @@ -91,7 +91,7 @@ func (vcc *VClusterCommands) produceListAllNodesInstructions(options *VFetchNode usePassword := false if options.Password != nil { usePassword = true - err := options.validateUserName(vcc.Log) + err := options.ValidateUserName(vcc.Log) if err != nil { return instructions, err } diff --git a/vclusterops/helpers.go b/vclusterops/helpers.go index a81291f..b997023 100644 --- a/vclusterops/helpers.go +++ b/vclusterops/helpers.go @@ -102,7 +102,7 @@ func getInitiatorHost(primaryUpNodes, hostsToSkip []string) (string, error) { // getVDBFromRunningDB will retrieve db configurations by calling https endpoints of a running db func (vcc *VClusterCommands) getVDBFromRunningDB(vdb *VCoordinationDatabase, options *DatabaseOptions) error { - err := options.setUsePassword(vcc.Log) + err := options.SetUsePassword(vcc.Log) if err != nil { return fmt.Errorf("fail to set userPassword while retrieving database configurations, %w", err) } @@ -123,8 +123,8 @@ func (vcc *VClusterCommands) getVDBFromRunningDB(vdb *VCoordinationDatabase, opt instructions = append(instructions, &httpsGetNodesInfoOp, &httpsGetClusterInfoOp) certs := HTTPSCerts{key: options.Key, cert: options.Cert, caCert: options.CaCert} - clusterOpEngine := makeClusterOpEngine(instructions, &certs) - err = clusterOpEngine.run(vcc.Log) + clusterOpEngine := MakeClusterOpEngine(instructions, &certs) + err = clusterOpEngine.Run(vcc.Log) if err != nil { return fmt.Errorf("fail to retrieve database configurations, %w", err) } diff --git a/vclusterops/helpers_test.go b/vclusterops/helpers_test.go index 16cb530..f3dded6 100644 --- a/vclusterops/helpers_test.go +++ b/vclusterops/helpers_test.go @@ -28,7 +28,7 @@ func TestForupdateCatalogPathMapFromCatalogEditorPositive(t *testing.T) { mockNmaVNode1 := &NmaVNode{CatalogPath: "/data/test_db/v_test_db_node0001_catalog/Catalog", Address: "192.168.1.101"} mockNmaVNode2 := &NmaVNode{CatalogPath: "/Catalog/data/test_db/v_test_db_node0002_catalog/Catalog", Address: "192.168.1.102"} mockNmaVNode3 := &NmaVNode{CatalogPath: "/data/test_db/v_test_db_node0003_catalog/Catalog", Address: "192.168.1.103"} - mockHostNodeMap := map[string]*NmaVNode{"192.168.1.101": mockNmaVNode1, "192.168.1.102": mockNmaVNode2, "192.168.1.103": mockNmaVNode3} + mockHostNodeMap := map[string]NmaVNode{"192.168.1.101": *mockNmaVNode1, "192.168.1.102": *mockNmaVNode2, "192.168.1.103": *mockNmaVNode3} mockNmaVDB := &NmaVDatabase{HostNodeMap: mockHostNodeMap} host := []string{"192.168.1.101", "192.168.1.102", "192.168.1.103"} mockCatalogPath := make(map[string]string) @@ -44,7 +44,7 @@ func TestForupdateCatalogPathMapFromCatalogEditorNegative(t *testing.T) { // prepare data for nmaVDB mockNmaVNode1 := &NmaVNode{CatalogPath: "/data/test_db/v_test_db_node0001_catalog/Catalog", Address: "192.168.1.101"} mockNmaVNode2 := &NmaVNode{CatalogPath: "/data/test_db/v_test_db_node0002_catalog/Catalog", Address: "192.168.1.102"} - mockHostNodeMap := map[string]*NmaVNode{"192.168.1.101": mockNmaVNode1, "192.168.1.102": mockNmaVNode2} + mockHostNodeMap := map[string]NmaVNode{"192.168.1.101": *mockNmaVNode1, "192.168.1.102": *mockNmaVNode2} mockNmaVDB := &NmaVDatabase{HostNodeMap: mockHostNodeMap} host := []string{"192.168.1.101", "192.168.1.103"} mockCatalogPath := make(map[string]string) diff --git a/vclusterops/http_adapter.go b/vclusterops/http_adapter.go index a6b80aa..3f0ea71 100644 --- a/vclusterops/http_adapter.go +++ b/vclusterops/http_adapter.go @@ -37,7 +37,7 @@ type HTTPAdapter struct { host string } -func makeHTTPAdapter(log vlog.Printer) HTTPAdapter { +func MakeHTTPAdapter(log vlog.Printer) HTTPAdapter { newHTTPAdapter := HTTPAdapter{} newHTTPAdapter.name = "HTTPAdapter" newHTTPAdapter.log = log.WithName(newHTTPAdapter.name) diff --git a/vclusterops/http_request.go b/vclusterops/http_request.go index 79116b3..3621107 100644 --- a/vclusterops/http_request.go +++ b/vclusterops/http_request.go @@ -37,12 +37,12 @@ type HTTPSCerts struct { caCert string } -func (req *HostHTTPRequest) buildNMAEndpoint(url string) { +func (req *HostHTTPRequest) BuildNMAEndpoint(url string) { req.IsNMACommand = true req.Endpoint = NMACurVersion + url } -func (req *HostHTTPRequest) buildHTTPSEndpoint(url string) { +func (req *HostHTTPRequest) BuildHTTPSEndpoint(url string) { req.IsNMACommand = false req.Endpoint = HTTPCurVersion + url } diff --git a/vclusterops/http_request_dispatcher.go b/vclusterops/http_request_dispatcher.go index 15c0f9e..1a20d3c 100644 --- a/vclusterops/http_request_dispatcher.go +++ b/vclusterops/http_request_dispatcher.go @@ -22,7 +22,7 @@ type HTTPRequestDispatcher struct { pool AdapterPool } -func makeHTTPRequestDispatcher(log vlog.Printer) HTTPRequestDispatcher { +func MakeHTTPRequestDispatcher(log vlog.Printer) HTTPRequestDispatcher { newHTTPRequestDispatcher := HTTPRequestDispatcher{} newHTTPRequestDispatcher.name = "HTTPRequestDispatcher" newHTTPRequestDispatcher.log = log.WithName(newHTTPRequestDispatcher.name) @@ -31,11 +31,11 @@ func makeHTTPRequestDispatcher(log vlog.Printer) HTTPRequestDispatcher { } // set up the pool connection for each host -func (dispatcher *HTTPRequestDispatcher) setup(hosts []string) { +func (dispatcher *HTTPRequestDispatcher) Setup(hosts []string) { dispatcher.pool = getPoolInstance(dispatcher.log) for _, host := range hosts { - adapter := makeHTTPAdapter(dispatcher.log) + adapter := MakeHTTPAdapter(dispatcher.log) adapter.host = host dispatcher.pool.connections[host] = &adapter } diff --git a/vclusterops/https_add_subcluster_op.go b/vclusterops/https_add_subcluster_op.go index 441ee01..decb5f9 100644 --- a/vclusterops/https_add_subcluster_op.go +++ b/vclusterops/https_add_subcluster_op.go @@ -82,7 +82,7 @@ func (op *HTTPSAddSubclusterOp) setupClusterHTTPRequest(hosts []string) error { for _, host := range hosts { httpRequest := HostHTTPRequest{} httpRequest.Method = PostMethod - httpRequest.buildHTTPSEndpoint("subclusters/" + op.scName) + httpRequest.BuildHTTPSEndpoint("subclusters/" + op.scName) if op.useHTTPPassword { httpRequest.Password = op.httpsPassword httpRequest.Username = op.userName @@ -104,7 +104,7 @@ func (op *HTTPSAddSubclusterOp) prepare(execContext *OpEngineExecContext) error if err != nil { return err } - execContext.dispatcher.setup(hosts) + execContext.dispatcher.Setup(hosts) return op.setupClusterHTTPRequest(hosts) } @@ -123,7 +123,7 @@ func (op *HTTPSAddSubclusterOp) processResult(_ *OpEngineExecContext) error { for host, result := range op.clusterHTTPRequest.ResultCollection { op.logResponse(host, result) - if result.isUnauthorizedRequest() { + if result.IsUnauthorizedRequest() { // skip checking response from other nodes because we will get the same error there return result.err } diff --git a/vclusterops/https_check_db_running_op.go b/vclusterops/https_check_db_running.go similarity index 98% rename from vclusterops/https_check_db_running_op.go rename to vclusterops/https_check_db_running.go index 7bfc089..2911a2b 100644 --- a/vclusterops/https_check_db_running_op.go +++ b/vclusterops/https_check_db_running.go @@ -79,7 +79,7 @@ func (op *HTTPCheckRunningDBOp) setupClusterHTTPRequest(hosts []string) error { for _, host := range hosts { httpRequest := HostHTTPRequest{} httpRequest.Method = GetMethod - httpRequest.buildHTTPSEndpoint("nodes") + httpRequest.BuildHTTPSEndpoint("nodes") if op.useHTTPPassword { httpRequest.Password = op.httpsPassword httpRequest.Username = op.userName @@ -95,7 +95,7 @@ func (op *HTTPCheckRunningDBOp) logPrepare() { } func (op *HTTPCheckRunningDBOp) prepare(execContext *OpEngineExecContext) error { - execContext.dispatcher.setup(op.hosts) + execContext.dispatcher.Setup(op.hosts) return op.setupClusterHTTPRequest(op.hosts) } @@ -173,7 +173,7 @@ func (op *HTTPCheckRunningDBOp) processResult(_ *OpEngineExecContext) error { for host, result := range op.clusterHTTPRequest.ResultCollection { resSummaryStr := SuccessResult // VER-87303: it's possible that there's a DB running with a different password - if !result.isHTTPRunning() { + if !result.IsHTTPRunning() { resSummaryStr = FailureResult } op.log.PrintInfo("[%s] result from host %s summary %s, details: %+v.", @@ -182,7 +182,7 @@ func (op *HTTPCheckRunningDBOp) processResult(_ *OpEngineExecContext) error { if !result.isPassing() { allErrs = errors.Join(allErrs, result.err) } - if result.isFailing() && !result.isHTTPRunning() { + if result.isFailing() && !result.IsHTTPRunning() { downHosts[host] = true continue } else if result.isException() { diff --git a/vclusterops/https_check_node_state_op.go b/vclusterops/https_check_node_state_op.go index bf05855..7852142 100644 --- a/vclusterops/https_check_node_state_op.go +++ b/vclusterops/https_check_node_state_op.go @@ -56,7 +56,7 @@ func (op *HTTPCheckNodeStateOp) setupClusterHTTPRequest(hosts []string) error { for _, host := range hosts { httpRequest := HostHTTPRequest{} httpRequest.Method = GetMethod - httpRequest.buildHTTPSEndpoint("nodes") + httpRequest.BuildHTTPSEndpoint("nodes") if op.useHTTPPassword { httpRequest.Password = op.httpsPassword httpRequest.Username = op.userName @@ -68,7 +68,7 @@ func (op *HTTPCheckNodeStateOp) setupClusterHTTPRequest(hosts []string) error { } func (op *HTTPCheckNodeStateOp) prepare(execContext *OpEngineExecContext) error { - execContext.dispatcher.setup(op.hosts) + execContext.dispatcher.Setup(op.hosts) return op.setupClusterHTTPRequest(op.hosts) } @@ -88,7 +88,7 @@ func (op *HTTPCheckNodeStateOp) processResult(execContext *OpEngineExecContext) for host, result := range op.clusterHTTPRequest.ResultCollection { op.logResponse(host, result) - if result.isUnauthorizedRequest() { + if result.IsUnauthorizedRequest() { op.log.PrintError("[%s] unauthorized request: %s", op.name, result.content) // return here because we assume that // we will get the same error across other nodes @@ -98,7 +98,7 @@ func (op *HTTPCheckNodeStateOp) processResult(execContext *OpEngineExecContext) if !result.isPassing() { // for any error, we continue to the next node - if result.isInternalError() { + if result.IsInternalError() { op.log.PrintError("[%s] internal error of the /nodes endpoint: %s", op.name, result.content) // At internal error originated from the server, so its a // response, just not a successful one. diff --git a/vclusterops/https_check_subcluster_op.go b/vclusterops/https_check_subcluster_op.go index 974db5d..35b399a 100644 --- a/vclusterops/https_check_subcluster_op.go +++ b/vclusterops/https_check_subcluster_op.go @@ -55,7 +55,7 @@ func (op *HTTPSCheckSubclusterOp) setupClusterHTTPRequest(hosts []string) error for _, host := range hosts { httpRequest := HostHTTPRequest{} httpRequest.Method = GetMethod - httpRequest.buildHTTPSEndpoint("subclusters/" + op.scName) + httpRequest.BuildHTTPSEndpoint("subclusters/" + op.scName) if op.useHTTPPassword { httpRequest.Password = op.httpsPassword httpRequest.Username = op.userName @@ -70,7 +70,7 @@ func (op *HTTPSCheckSubclusterOp) prepare(execContext *OpEngineExecContext) erro if len(execContext.upHosts) == 0 { return fmt.Errorf(`[%s] Cannot find any up hosts in OpEngineExecContext`, op.name) } - execContext.dispatcher.setup(execContext.upHosts) + execContext.dispatcher.Setup(execContext.upHosts) return op.setupClusterHTTPRequest(execContext.upHosts) } @@ -96,7 +96,7 @@ func (op *HTTPSCheckSubclusterOp) processResult(_ *OpEngineExecContext) error { for host, result := range op.clusterHTTPRequest.ResultCollection { op.logResponse(host, result) - if result.isUnauthorizedRequest() { + if result.IsUnauthorizedRequest() { // skip checking response from other nodes because we will get the same error there return result.err } diff --git a/vclusterops/https_create_cluster_depot_op.go b/vclusterops/https_create_cluster_depot_op.go index 4d3b532..39034db 100644 --- a/vclusterops/https_create_cluster_depot_op.go +++ b/vclusterops/https_create_cluster_depot_op.go @@ -66,7 +66,7 @@ func (op *HTTPSCreateDepotOp) setupClusterHTTPRequest(hosts []string) error { for _, host := range hosts { httpRequest := HostHTTPRequest{} httpRequest.Method = PostMethod - httpRequest.buildHTTPSEndpoint("cluster/depot") + httpRequest.BuildHTTPSEndpoint("cluster/depot") if op.useHTTPPassword { httpRequest.Password = op.httpsPassword httpRequest.Username = op.userName @@ -79,7 +79,7 @@ func (op *HTTPSCreateDepotOp) setupClusterHTTPRequest(hosts []string) error { } func (op *HTTPSCreateDepotOp) prepare(execContext *OpEngineExecContext) error { - execContext.dispatcher.setup(op.hosts) + execContext.dispatcher.Setup(op.hosts) return op.setupClusterHTTPRequest(op.hosts) } diff --git a/vclusterops/https_create_node_op.go b/vclusterops/https_create_node_op.go index f7322a6..d6ef03a 100644 --- a/vclusterops/https_create_node_op.go +++ b/vclusterops/https_create_node_op.go @@ -56,7 +56,7 @@ func (op *HTTPSCreateNodeOp) setupClusterHTTPRequest(hosts []string) error { httpRequest.Method = PostMethod // note that this will be updated in Prepare() // because the endpoint only accept parameters in query - httpRequest.buildHTTPSEndpoint("nodes") + httpRequest.BuildHTTPSEndpoint("nodes") if op.useHTTPPassword { httpRequest.Password = op.httpsPassword httpRequest.Username = op.userName @@ -85,7 +85,7 @@ func (op *HTTPSCreateNodeOp) prepare(execContext *OpEngineExecContext) error { return err } - execContext.dispatcher.setup(op.hosts) + execContext.dispatcher.Setup(op.hosts) return op.setupClusterHTTPRequest(op.hosts) } diff --git a/vclusterops/https_create_nodes_depot_op.go b/vclusterops/https_create_nodes_depot_op.go index 92d0a56..3760927 100644 --- a/vclusterops/https_create_nodes_depot_op.go +++ b/vclusterops/https_create_nodes_depot_op.go @@ -57,7 +57,7 @@ func (op *HTTPSCreateNodesDepotOp) setupClusterHTTPRequest(hosts []string) error httpRequest := HostHTTPRequest{} httpRequest.Method = PostMethod node := op.HostNodeMap[host] - httpRequest.buildHTTPSEndpoint("nodes/" + node.Name + "/depot") + httpRequest.BuildHTTPSEndpoint("nodes/" + node.Name + "/depot") if op.useHTTPPassword { httpRequest.Password = op.httpsPassword httpRequest.Username = op.userName @@ -73,7 +73,7 @@ func (op *HTTPSCreateNodesDepotOp) setupClusterHTTPRequest(hosts []string) error } func (op *HTTPSCreateNodesDepotOp) prepare(execContext *OpEngineExecContext) error { - execContext.dispatcher.setup(op.hosts) + execContext.dispatcher.Setup(op.hosts) return op.setupClusterHTTPRequest(op.hosts) } diff --git a/vclusterops/https_drop_node_op.go b/vclusterops/https_drop_node_op.go index 6c45699..2854447 100644 --- a/vclusterops/https_drop_node_op.go +++ b/vclusterops/https_drop_node_op.go @@ -60,7 +60,7 @@ func (op *HTTPSDropNodeOp) setupClusterHTTPRequest(hosts []string) error { for _, host := range hosts { httpRequest := HostHTTPRequest{} httpRequest.Method = PostMethod - httpRequest.buildHTTPSEndpoint("nodes/" + op.targetHost + "/drop") + httpRequest.BuildHTTPSEndpoint("nodes/" + op.targetHost + "/drop") if op.useHTTPPassword { httpRequest.Password = op.httpsPassword httpRequest.Username = op.userName @@ -72,7 +72,7 @@ func (op *HTTPSDropNodeOp) setupClusterHTTPRequest(hosts []string) error { } func (op *HTTPSDropNodeOp) prepare(execContext *OpEngineExecContext) error { - execContext.dispatcher.setup(op.hosts) + execContext.dispatcher.Setup(op.hosts) return op.setupClusterHTTPRequest(op.hosts) } @@ -90,7 +90,7 @@ func (op *HTTPSDropNodeOp) processResult(_ *OpEngineExecContext) error { for host, result := range op.clusterHTTPRequest.ResultCollection { op.logResponse(host, result) - if !result.isSuccess() { + if !result.IsSuccess() { allErrs = errors.Join(allErrs, result.err) continue } diff --git a/vclusterops/https_drop_subcluster_op.go b/vclusterops/https_drop_subcluster_op.go index bee229e..d2cd9f7 100644 --- a/vclusterops/https_drop_subcluster_op.go +++ b/vclusterops/https_drop_subcluster_op.go @@ -53,7 +53,7 @@ func (op *httpsDropSubclusterOp) setupClusterHTTPRequest(hosts []string) error { for _, host := range hosts { httpRequest := HostHTTPRequest{} httpRequest.Method = PostMethod - httpRequest.buildHTTPSEndpoint("subclusters/" + op.scName + "/drop") + httpRequest.BuildHTTPSEndpoint("subclusters/" + op.scName + "/drop") if op.useHTTPPassword { httpRequest.Password = op.httpsPassword httpRequest.Username = op.userName @@ -66,7 +66,7 @@ func (op *httpsDropSubclusterOp) setupClusterHTTPRequest(hosts []string) error { } func (op *httpsDropSubclusterOp) prepare(execContext *OpEngineExecContext) error { - execContext.dispatcher.setup(op.hosts) + execContext.dispatcher.Setup(op.hosts) return op.setupClusterHTTPRequest(op.hosts) } @@ -85,7 +85,7 @@ func (op *httpsDropSubclusterOp) processResult(_ *OpEngineExecContext) error { for host, result := range op.clusterHTTPRequest.ResultCollection { op.logResponse(host, result) - if result.isUnauthorizedRequest() { + if result.IsUnauthorizedRequest() { return fmt.Errorf("[%s] wrong password/certificate for https service on host %s", op.name, host) } diff --git a/vclusterops/https_find_subcluster_op.go b/vclusterops/https_find_subcluster_op.go index d4fffdb..a4b64bf 100644 --- a/vclusterops/https_find_subcluster_op.go +++ b/vclusterops/https_find_subcluster_op.go @@ -54,7 +54,7 @@ func (op *HTTPSFindSubclusterOp) setupClusterHTTPRequest(hosts []string) error { for _, host := range hosts { httpRequest := HostHTTPRequest{} httpRequest.Method = GetMethod - httpRequest.buildHTTPSEndpoint("subclusters") + httpRequest.BuildHTTPSEndpoint("subclusters") if op.useHTTPPassword { httpRequest.Password = op.httpsPassword httpRequest.Username = op.userName @@ -66,7 +66,7 @@ func (op *HTTPSFindSubclusterOp) setupClusterHTTPRequest(hosts []string) error { } func (op *HTTPSFindSubclusterOp) prepare(execContext *OpEngineExecContext) error { - execContext.dispatcher.setup(op.hosts) + execContext.dispatcher.Setup(op.hosts) return op.setupClusterHTTPRequest(op.hosts) } @@ -95,7 +95,7 @@ func (op *HTTPSFindSubclusterOp) processResult(execContext *OpEngineExecContext) for host, result := range op.clusterHTTPRequest.ResultCollection { op.logResponse(host, result) - if result.isUnauthorizedRequest() { + if result.IsUnauthorizedRequest() { // skip checking response from other nodes because we will get the same error there return result.err } diff --git a/vclusterops/https_get_cluster_info_op.go b/vclusterops/https_get_cluster_info_op.go index 51c9589..28b95cf 100644 --- a/vclusterops/https_get_cluster_info_op.go +++ b/vclusterops/https_get_cluster_info_op.go @@ -57,7 +57,7 @@ func (op *httpsGetClusterInfoOp) setupClusterHTTPRequest(hosts []string) error { for _, host := range hosts { httpRequest := HostHTTPRequest{} httpRequest.Method = GetMethod - httpRequest.buildHTTPSEndpoint("cluster") + httpRequest.BuildHTTPSEndpoint("cluster") if op.useHTTPPassword { httpRequest.Password = op.httpsPassword httpRequest.Username = op.userName @@ -70,7 +70,7 @@ func (op *httpsGetClusterInfoOp) setupClusterHTTPRequest(hosts []string) error { } func (op *httpsGetClusterInfoOp) prepare(execContext *OpEngineExecContext) error { - execContext.dispatcher.setup(op.hosts) + execContext.dispatcher.Setup(op.hosts) return op.setupClusterHTTPRequest(op.hosts) } @@ -94,7 +94,7 @@ func (op *httpsGetClusterInfoOp) processResult(_ *OpEngineExecContext) error { for host, result := range op.clusterHTTPRequest.ResultCollection { op.logResponse(host, result) - if result.isUnauthorizedRequest() { + if result.IsUnauthorizedRequest() { return fmt.Errorf("[%s] wrong password/certificate for https service on host %s", op.name, host) } diff --git a/vclusterops/https_get_nodes_info_op.go b/vclusterops/https_get_nodes_info_op.go index eb407b1..e678e7a 100644 --- a/vclusterops/https_get_nodes_info_op.go +++ b/vclusterops/https_get_nodes_info_op.go @@ -51,7 +51,7 @@ func (op *httpsGetNodesInfoOp) setupClusterHTTPRequest(hosts []string) error { for _, host := range hosts { httpRequest := HostHTTPRequest{} httpRequest.Method = GetMethod - httpRequest.buildHTTPSEndpoint("nodes") + httpRequest.BuildHTTPSEndpoint("nodes") if op.useHTTPPassword { httpRequest.Password = op.httpsPassword httpRequest.Username = op.userName @@ -64,7 +64,7 @@ func (op *httpsGetNodesInfoOp) setupClusterHTTPRequest(hosts []string) error { } func (op *httpsGetNodesInfoOp) prepare(execContext *OpEngineExecContext) error { - execContext.dispatcher.setup(op.hosts) + execContext.dispatcher.Setup(op.hosts) return op.setupClusterHTTPRequest(op.hosts) } @@ -82,7 +82,7 @@ func (op *httpsGetNodesInfoOp) processResult(_ *OpEngineExecContext) error { for host, result := range op.clusterHTTPRequest.ResultCollection { op.logResponse(host, result) - if result.isUnauthorizedRequest() { + if result.IsUnauthorizedRequest() { return fmt.Errorf("[%s] wrong password/certificate for https service on host %s", op.name, host) } diff --git a/vclusterops/https_get_up_nodes_op.go b/vclusterops/https_get_up_nodes_op.go index 7217488..2b68e2e 100644 --- a/vclusterops/https_get_up_nodes_op.go +++ b/vclusterops/https_get_up_nodes_op.go @@ -55,7 +55,7 @@ func (op *HTTPSGetUpNodesOp) setupClusterHTTPRequest(hosts []string) error { for _, host := range hosts { httpRequest := HostHTTPRequest{} httpRequest.Method = GetMethod - httpRequest.buildHTTPSEndpoint("nodes") + httpRequest.BuildHTTPSEndpoint("nodes") if op.useHTTPPassword { httpRequest.Password = op.httpsPassword httpRequest.Username = op.userName @@ -67,7 +67,7 @@ func (op *HTTPSGetUpNodesOp) setupClusterHTTPRequest(hosts []string) error { } func (op *HTTPSGetUpNodesOp) prepare(execContext *OpEngineExecContext) error { - execContext.dispatcher.setup(op.hosts) + execContext.dispatcher.Setup(op.hosts) return op.setupClusterHTTPRequest(op.hosts) } @@ -122,7 +122,7 @@ func (op *HTTPSGetUpNodesOp) processResult(execContext *OpEngineExecContext) err // We assume all the hosts are in the same db cluster // If any of the hosts reject the request, other hosts will reject the request too // Do not try other hosts when we see a http failure - if result.isFailing() && result.isHTTPRunning() { + if result.isFailing() && result.IsHTTPRunning() { exceptionHosts = append(exceptionHosts, host) continue } diff --git a/vclusterops/https_install_packages_op.go b/vclusterops/https_install_packages_op.go index c263a39..5e085dd 100644 --- a/vclusterops/https_install_packages_op.go +++ b/vclusterops/https_install_packages_op.go @@ -50,7 +50,7 @@ func (op *HTTPSInstallPackagesOp) setupClusterHTTPRequest(hosts []string) error for _, host := range hosts { httpRequest := HostHTTPRequest{} httpRequest.Method = PostMethod - httpRequest.buildHTTPSEndpoint("packages") + httpRequest.BuildHTTPSEndpoint("packages") if op.useHTTPPassword { httpRequest.Password = op.httpsPassword httpRequest.Username = op.userName @@ -62,7 +62,7 @@ func (op *HTTPSInstallPackagesOp) setupClusterHTTPRequest(hosts []string) error } func (op *HTTPSInstallPackagesOp) prepare(execContext *OpEngineExecContext) error { - execContext.dispatcher.setup(op.hosts) + execContext.dispatcher.Setup(op.hosts) return op.setupClusterHTTPRequest(op.hosts) } diff --git a/vclusterops/https_mark_design_ksafe_op.go b/vclusterops/https_mark_design_ksafe_op.go index 12ffd66..b744993 100644 --- a/vclusterops/https_mark_design_ksafe_op.go +++ b/vclusterops/https_mark_design_ksafe_op.go @@ -68,7 +68,7 @@ func (op *HTTPSMarkDesignKSafeOp) setupClusterHTTPRequest(hosts []string) error for _, host := range hosts { httpRequest := HostHTTPRequest{} httpRequest.Method = PutMethod - httpRequest.buildHTTPSEndpoint("cluster/k-safety") + httpRequest.BuildHTTPSEndpoint("cluster/k-safety") if op.useHTTPPassword { httpRequest.Password = op.httpsPassword httpRequest.Username = op.userName @@ -81,7 +81,7 @@ func (op *HTTPSMarkDesignKSafeOp) setupClusterHTTPRequest(hosts []string) error } func (op *HTTPSMarkDesignKSafeOp) prepare(execContext *OpEngineExecContext) error { - execContext.dispatcher.setup(op.hosts) + execContext.dispatcher.Setup(op.hosts) return op.setupClusterHTTPRequest(op.hosts) } diff --git a/vclusterops/https_mark_nodes_ephemeral_op.go b/vclusterops/https_mark_nodes_ephemeral_op.go index 56f56ae..3b69e06 100644 --- a/vclusterops/https_mark_nodes_ephemeral_op.go +++ b/vclusterops/https_mark_nodes_ephemeral_op.go @@ -52,7 +52,7 @@ func (op *HTTPSMarkEphemeralNodeOp) setupClusterHTTPRequest(hosts []string) erro for _, host := range hosts { httpRequest := HostHTTPRequest{} httpRequest.Method = PostMethod - httpRequest.buildHTTPSEndpoint("nodes/" + op.targetNodeName + "/ephemeral") + httpRequest.BuildHTTPSEndpoint("nodes/" + op.targetNodeName + "/ephemeral") if op.useHTTPPassword { httpRequest.Password = op.httpsPassword httpRequest.Username = op.userName @@ -63,7 +63,7 @@ func (op *HTTPSMarkEphemeralNodeOp) setupClusterHTTPRequest(hosts []string) erro } func (op *HTTPSMarkEphemeralNodeOp) prepare(execContext *OpEngineExecContext) error { - execContext.dispatcher.setup(op.hosts) + execContext.dispatcher.Setup(op.hosts) return op.setupClusterHTTPRequest(op.hosts) } @@ -81,7 +81,7 @@ func (op *HTTPSMarkEphemeralNodeOp) processResult(_ *OpEngineExecContext) error for host, result := range op.clusterHTTPRequest.ResultCollection { op.logResponse(host, result) - if !result.isSuccess() { + if !result.IsSuccess() { allErrs = errors.Join(allErrs, result.err) continue } diff --git a/vclusterops/https_poll_node_state_op.go b/vclusterops/https_poll_node_state_op.go index 93c1b0e..53c86d7 100644 --- a/vclusterops/https_poll_node_state_op.go +++ b/vclusterops/https_poll_node_state_op.go @@ -18,6 +18,7 @@ package vclusterops import ( "errors" "fmt" + "sort" "strconv" "github.com/vertica/vcluster/vclusterops/util" @@ -48,9 +49,11 @@ func (cmd CmdType) String() string { type HTTPSPollNodeStateOp struct { OpBase OpHTTPSBase - currentHost string - timeout int - cmdType CmdType + allHosts map[string]any + upHosts map[string]any + notUpHosts []string + timeout int + cmdType CmdType } func makeHTTPSPollNodeStateOpHelper(log vlog.Printer, hosts []string, @@ -68,6 +71,11 @@ func makeHTTPSPollNodeStateOpHelper(log vlog.Printer, hosts []string, httpsPollNodeStateOp.userName = userName httpsPollNodeStateOp.httpsPassword = httpsPassword + httpsPollNodeStateOp.upHosts = make(map[string]any) + httpsPollNodeStateOp.allHosts = make(map[string]any) + for _, h := range hosts { + httpsPollNodeStateOp.allHosts[h] = struct{}{} + } return httpsPollNodeStateOp, nil } @@ -108,7 +116,7 @@ func (op *HTTPSPollNodeStateOp) setupClusterHTTPRequest(hosts []string) error { httpRequest := HostHTTPRequest{} httpRequest.Method = GetMethod httpRequest.Timeout = httpRequestTimeoutSeconds - httpRequest.buildHTTPSEndpoint("nodes/" + host) + httpRequest.BuildHTTPSEndpoint("nodes/" + host) if op.useHTTPPassword { httpRequest.Password = op.httpsPassword httpRequest.Username = op.userName @@ -121,7 +129,7 @@ func (op *HTTPSPollNodeStateOp) setupClusterHTTPRequest(hosts []string) error { } func (op *HTTPSPollNodeStateOp) prepare(execContext *OpEngineExecContext) error { - execContext.dispatcher.setup(op.hosts) + execContext.dispatcher.Setup(op.hosts) return op.setupClusterHTTPRequest(op.hosts) } @@ -141,9 +149,10 @@ func (op *HTTPSPollNodeStateOp) finalize(_ *OpEngineExecContext) error { func (op *HTTPSPollNodeStateOp) processResult(execContext *OpEngineExecContext) error { err := pollState(op, execContext) if err != nil { - // show the host that is not UP - msg := fmt.Sprintf("Cannot get the correct response from the host %s after %d seconds, details: %s", - op.currentHost, op.timeout, err) + // show the hosts that are not UP + sort.Strings(op.notUpHosts) + msg := fmt.Sprintf("The following hosts are not up after %d seconds: %v, details: %s", + op.timeout, op.notUpHosts, err) op.log.PrintError(msg) return errors.New(msg) } @@ -166,7 +175,6 @@ type NodesInfo struct { func (op *HTTPSPollNodeStateOp) shouldStopPolling() (bool, error) { for host, result := range op.clusterHTTPRequest.ResultCollection { op.logResponse(host, result) - op.currentHost = host // when we get timeout error, we know that the host is unreachable/dead if result.isTimeout() { @@ -177,7 +185,7 @@ func (op *HTTPSPollNodeStateOp) shouldStopPolling() (bool, error) { // We don't need to wait until timeout to determine if all nodes are up or not. // If we find the wrong password for the HTTPS service on any hosts, we should fail immediately. // We also need to let user know to wait until all nodes are up - if result.isPasswordAndCertificateError(op.log) { + if result.IsPasswordAndCertificateError(op.log) { switch op.cmdType { case StartDBCmd, RestartNodeCmd: op.log.PrintError("[%s] The credentials are incorrect. 'Catalog Sync' will not be executed.", diff --git a/vclusterops/https_poll_node_state_op_test.go b/vclusterops/https_poll_node_state_op_test.go index d52b1fe..203cd64 100644 --- a/vclusterops/https_poll_node_state_op_test.go +++ b/vclusterops/https_poll_node_state_op_test.go @@ -34,7 +34,7 @@ func TestTimeoutCase(t *testing.T) { instructions = append(instructions, &httpsPollNodeStateOp) certs := HTTPSCerts{} - clusterOpEngine := makeClusterOpEngine(instructions, &certs) - err = clusterOpEngine.run(vlog.Printer{}) + clusterOpEngine := MakeClusterOpEngine(instructions, &certs) + err = clusterOpEngine.Run(vlog.Printer{}) assert.ErrorContains(t, err, "[HTTPSPollNodeStateOp] cannot connect to host 192.0.2.1, please check if the host is still alive") } diff --git a/vclusterops/https_poll_subscription_state_op.go b/vclusterops/https_poll_subscription_state_op.go index ef92926..e59c34b 100644 --- a/vclusterops/https_poll_subscription_state_op.go +++ b/vclusterops/https_poll_subscription_state_op.go @@ -56,7 +56,7 @@ func (op *httpsPollSubscriptionStateOp) setupClusterHTTPRequest(hosts []string) httpRequest := HostHTTPRequest{} httpRequest.Method = GetMethod httpRequest.Timeout = httpRequestTimeoutSeconds - httpRequest.buildHTTPSEndpoint("subscriptions") + httpRequest.BuildHTTPSEndpoint("subscriptions") if op.useHTTPPassword { httpRequest.Password = op.httpsPassword httpRequest.Username = op.userName @@ -69,7 +69,7 @@ func (op *httpsPollSubscriptionStateOp) setupClusterHTTPRequest(hosts []string) } func (op *httpsPollSubscriptionStateOp) prepare(execContext *OpEngineExecContext) error { - execContext.dispatcher.setup(op.hosts) + execContext.dispatcher.Setup(op.hosts) return op.setupClusterHTTPRequest(op.hosts) } @@ -129,7 +129,7 @@ func (op *httpsPollSubscriptionStateOp) shouldStopPolling() (bool, error) { for host, result := range op.clusterHTTPRequest.ResultCollection { op.logResponse(host, result) - if result.isPasswordAndCertificateError(op.log) { + if result.IsPasswordAndCertificateError(op.log) { return true, fmt.Errorf("[%s] wrong password/certificate for https service on host %s", op.name, host) } diff --git a/vclusterops/https_re_ip_op.go b/vclusterops/https_re_ip_op.go index 590233c..47e2fdd 100644 --- a/vclusterops/https_re_ip_op.go +++ b/vclusterops/https_re_ip_op.go @@ -60,7 +60,7 @@ func (op *httpsReIPOp) setupClusterHTTPRequest(hosts []string) error { if !ok { return fmt.Errorf("[%s] cannot find node information for address %s", op.name, host) } - httpRequest.buildHTTPSEndpoint("nodes/" + nodesInfo.NodeName + "/ip") + httpRequest.BuildHTTPSEndpoint("nodes/" + nodesInfo.NodeName + "/ip") httpRequest.QueryParams = make(map[string]string) httpRequest.QueryParams["host"] = nodesInfo.TargetAddress httpRequest.QueryParams["control-host"] = nodesInfo.TargetControlAddress @@ -97,7 +97,7 @@ func (op *httpsReIPOp) prepare(execContext *OpEngineExecContext) error { // use up hosts to execute the HTTP re-IP endpoint op.upHosts = execContext.upHosts - execContext.dispatcher.setup(op.upHosts) + execContext.dispatcher.Setup(op.upHosts) return op.setupClusterHTTPRequest(op.nodeNamesList) } @@ -114,7 +114,7 @@ func (op *httpsReIPOp) processResult(_ *OpEngineExecContext) error { for host, result := range op.clusterHTTPRequest.ResultCollection { op.logResponse(host, result) - if result.isUnauthorizedRequest() { + if result.IsUnauthorizedRequest() { return fmt.Errorf("[%s] wrong password/certificate for https service on host %s", op.name, host) } diff --git a/vclusterops/https_rebalance_cluster_op.go b/vclusterops/https_rebalance_cluster_op.go index fe558e4..eb7e8a7 100644 --- a/vclusterops/https_rebalance_cluster_op.go +++ b/vclusterops/https_rebalance_cluster_op.go @@ -53,7 +53,7 @@ func (op *HTTPSRebalanceClusterOp) setupClusterHTTPRequest(hosts []string) error for _, host := range hosts { httpRequest := HostHTTPRequest{} httpRequest.Method = PostMethod - httpRequest.buildHTTPSEndpoint("cluster/rebalance") + httpRequest.BuildHTTPSEndpoint("cluster/rebalance") if op.useHTTPPassword { httpRequest.Password = op.httpsPassword httpRequest.Username = op.userName @@ -64,7 +64,7 @@ func (op *HTTPSRebalanceClusterOp) setupClusterHTTPRequest(hosts []string) error } func (op *HTTPSRebalanceClusterOp) prepare(execContext *OpEngineExecContext) error { - execContext.dispatcher.setup(op.hosts) + execContext.dispatcher.Setup(op.hosts) return op.setupClusterHTTPRequest(op.hosts) } @@ -82,11 +82,11 @@ func (op *HTTPSRebalanceClusterOp) processResult(_ *OpEngineExecContext) error { for host, result := range op.clusterHTTPRequest.ResultCollection { op.logResponse(host, result) - if result.isUnauthorizedRequest() { + if result.IsUnauthorizedRequest() { // skip checking response from other nodes because we will get the same error there return result.err } - if !result.isSuccess() { + if !result.IsSuccess() { allErrs = errors.Join(allErrs, result.err) // try processing other hosts' responses when the current host has some server errors continue diff --git a/vclusterops/https_rebalance_subcluster_shards_op.go b/vclusterops/https_rebalance_subcluster_shards_op.go index 2e07fb5..e53b679 100644 --- a/vclusterops/https_rebalance_subcluster_shards_op.go +++ b/vclusterops/https_rebalance_subcluster_shards_op.go @@ -56,7 +56,7 @@ func (op *HTTPSRebalanceSubclusterShardsOp) setupClusterHTTPRequest(hosts []stri for _, host := range hosts { httpRequest := HostHTTPRequest{} httpRequest.Method = PostMethod - httpRequest.buildHTTPSEndpoint("subclusters/" + op.scName + "/rebalance") + httpRequest.BuildHTTPSEndpoint("subclusters/" + op.scName + "/rebalance") if op.useHTTPPassword { httpRequest.Password = op.httpsPassword httpRequest.Username = op.userName @@ -76,7 +76,7 @@ func (op *HTTPSRebalanceSubclusterShardsOp) prepare(execContext *OpEngineExecCon op.scName = execContext.defaultSCName } - execContext.dispatcher.setup(op.hosts) + execContext.dispatcher.Setup(op.hosts) return op.setupClusterHTTPRequest(op.hosts) } @@ -95,7 +95,7 @@ func (op *HTTPSRebalanceSubclusterShardsOp) processResult(_ *OpEngineExecContext for host, result := range op.clusterHTTPRequest.ResultCollection { op.logResponse(host, result) - if result.isUnauthorizedRequest() { + if result.IsUnauthorizedRequest() { // skip checking response from other nodes because we will get the same error there return result.err } diff --git a/vclusterops/https_reload_spread_op.go b/vclusterops/https_reload_spread_op.go index 5524cd0..b036317 100644 --- a/vclusterops/https_reload_spread_op.go +++ b/vclusterops/https_reload_spread_op.go @@ -55,7 +55,7 @@ func (op *HTTPSReloadSpreadOp) setupClusterHTTPRequest(hosts []string) error { for _, host := range hosts { httpRequest := HostHTTPRequest{} httpRequest.Method = PostMethod - httpRequest.buildHTTPSEndpoint("config/spread/reload") + httpRequest.BuildHTTPSEndpoint("config/spread/reload") if op.useHTTPPassword { httpRequest.Password = op.httpsPassword httpRequest.Username = op.userName @@ -71,7 +71,7 @@ func (op *HTTPSReloadSpreadOp) prepare(execContext *OpEngineExecContext) error { if len(op.hosts) == 0 { op.hosts = execContext.upHosts } - execContext.dispatcher.setup(op.hosts) + execContext.dispatcher.Setup(op.hosts) return op.setupClusterHTTPRequest(op.hosts) } diff --git a/vclusterops/https_spread_remove_node_op.go b/vclusterops/https_spread_remove_node_op.go index b3ad346..1193122 100644 --- a/vclusterops/https_spread_remove_node_op.go +++ b/vclusterops/https_spread_remove_node_op.go @@ -56,7 +56,7 @@ func (op *HTTPSSpreadRemoveNodeOp) setupClusterHTTPRequest(hosts []string) error for _, host := range hosts { httpRequest := HostHTTPRequest{} httpRequest.Method = PostMethod - httpRequest.buildHTTPSEndpoint("config/spread/remove") + httpRequest.BuildHTTPSEndpoint("config/spread/remove") if op.useHTTPPassword { httpRequest.Password = op.httpsPassword httpRequest.Username = op.userName @@ -68,7 +68,7 @@ func (op *HTTPSSpreadRemoveNodeOp) setupClusterHTTPRequest(hosts []string) error } func (op *HTTPSSpreadRemoveNodeOp) prepare(execContext *OpEngineExecContext) error { - execContext.dispatcher.setup(op.hosts) + execContext.dispatcher.Setup(op.hosts) return op.setupClusterHTTPRequest(op.hosts) } diff --git a/vclusterops/https_startup_command_op.go b/vclusterops/https_startup_command_op.go index a965276..0598955 100644 --- a/vclusterops/https_startup_command_op.go +++ b/vclusterops/https_startup_command_op.go @@ -55,7 +55,7 @@ func (op *httpsStartUpCommandOp) setupClusterHTTPRequest(hosts []string) error { httpRequest := HostHTTPRequest{} httpRequest.Method = GetMethod - httpRequest.buildHTTPSEndpoint("startup/commands") + httpRequest.BuildHTTPSEndpoint("startup/commands") if op.useHTTPPassword { httpRequest.Password = op.httpsPassword @@ -78,7 +78,7 @@ func (op *httpsStartUpCommandOp) prepare(execContext *OpEngineExecContext) error } } op.hosts = primaryUpHosts - execContext.dispatcher.setup(op.hosts) + execContext.dispatcher.Setup(op.hosts) return op.setupClusterHTTPRequest(op.hosts) } @@ -96,7 +96,7 @@ func (op *httpsStartUpCommandOp) processResult(execContext *OpEngineExecContext) for host, result := range op.clusterHTTPRequest.ResultCollection { op.logResponse(host, result) - if result.isUnauthorizedRequest() { + if result.IsUnauthorizedRequest() { return fmt.Errorf("[%s] wrong password/certificate for https service on host %s", op.name, host) } diff --git a/vclusterops/https_stop_db_op.go b/vclusterops/https_stop_db_op.go index a28dd1c..7735af2 100644 --- a/vclusterops/https_stop_db_op.go +++ b/vclusterops/https_stop_db_op.go @@ -59,7 +59,7 @@ func (op *HTTPSStopDBOp) setupClusterHTTPRequest(hosts []string) error { for _, host := range hosts { httpRequest := HostHTTPRequest{} httpRequest.Method = PostMethod - httpRequest.buildHTTPSEndpoint("cluster/shutdown") + httpRequest.BuildHTTPSEndpoint("cluster/shutdown") if op.useHTTPPassword { httpRequest.Password = op.httpsPassword httpRequest.Username = op.userName @@ -77,7 +77,7 @@ func (op *HTTPSStopDBOp) prepare(execContext *OpEngineExecContext) error { } // use first up host to execute https post request hosts := []string{execContext.upHosts[0]} - execContext.dispatcher.setup(hosts) + execContext.dispatcher.Setup(hosts) return op.setupClusterHTTPRequest(hosts) } diff --git a/vclusterops/https_sync_catalog_op.go b/vclusterops/https_sync_catalog_op.go index 2321e62..d2c31d0 100644 --- a/vclusterops/https_sync_catalog_op.go +++ b/vclusterops/https_sync_catalog_op.go @@ -56,7 +56,7 @@ func (op *HTTPSSyncCatalogOp) setupClusterHTTPRequest(hosts []string) error { for _, host := range hosts { httpRequest := HostHTTPRequest{} httpRequest.Method = PostMethod - httpRequest.buildHTTPSEndpoint("cluster/catalog/sync") + httpRequest.BuildHTTPSEndpoint("cluster/catalog/sync") httpRequest.QueryParams = make(map[string]string) httpRequest.QueryParams["retry-count"] = strconv.Itoa(util.DefaultRetryCount) if op.useHTTPPassword { @@ -78,7 +78,7 @@ func (op *HTTPSSyncCatalogOp) prepare(execContext *OpEngineExecContext) error { // use first up host to execute https post request op.hosts = []string{execContext.upHosts[0]} } - execContext.dispatcher.setup(op.hosts) + execContext.dispatcher.Setup(op.hosts) return op.setupClusterHTTPRequest(op.hosts) } diff --git a/vclusterops/nma_bootstrap_catalog_op.go b/vclusterops/nma_bootstrap_catalog_op.go index 0dbb3ea..8db29ab 100644 --- a/vclusterops/nma_bootstrap_catalog_op.go +++ b/vclusterops/nma_bootstrap_catalog_op.go @@ -152,7 +152,7 @@ func (op *NMABootstrapCatalogOp) setupClusterHTTPRequest(hosts []string) error { for _, host := range hosts { httpRequest := HostHTTPRequest{} httpRequest.Method = PostMethod - httpRequest.buildNMAEndpoint("catalog/bootstrap") + httpRequest.BuildNMAEndpoint("catalog/bootstrap") httpRequest.RequestData = op.marshaledRequestBodyMap[host] op.clusterHTTPRequest.RequestCollection[host] = httpRequest } @@ -166,7 +166,7 @@ func (op *NMABootstrapCatalogOp) prepare(execContext *OpEngineExecContext) error return err } - execContext.dispatcher.setup(op.hosts) + execContext.dispatcher.Setup(op.hosts) return op.setupClusterHTTPRequest(op.hosts) } diff --git a/vclusterops/nma_delete_dir_op.go b/vclusterops/nma_delete_dir_op.go index 160b781..f99b4d4 100644 --- a/vclusterops/nma_delete_dir_op.go +++ b/vclusterops/nma_delete_dir_op.go @@ -81,7 +81,7 @@ func (op *NMADeleteDirectoriesOp) setupClusterHTTPRequest(hosts []string) error for _, host := range hosts { httpRequest := HostHTTPRequest{} httpRequest.Method = PostMethod - httpRequest.buildNMAEndpoint("directories/delete") + httpRequest.BuildNMAEndpoint("directories/delete") httpRequest.RequestData = op.hostRequestBodyMap[host] op.clusterHTTPRequest.RequestCollection[host] = httpRequest } @@ -90,7 +90,7 @@ func (op *NMADeleteDirectoriesOp) setupClusterHTTPRequest(hosts []string) error } func (op *NMADeleteDirectoriesOp) prepare(execContext *OpEngineExecContext) error { - execContext.dispatcher.setup(op.hosts) + execContext.dispatcher.Setup(op.hosts) return op.setupClusterHTTPRequest(op.hosts) } diff --git a/vclusterops/nma_download_config.go b/vclusterops/nma_download_config.go index eda5ce7..386e578 100644 --- a/vclusterops/nma_download_config.go +++ b/vclusterops/nma_download_config.go @@ -54,7 +54,7 @@ func (op *NMADownloadConfigOp) setupClusterHTTPRequest(hosts []string) error { for _, host := range hosts { httpRequest := HostHTTPRequest{} httpRequest.Method = GetMethod - httpRequest.buildNMAEndpoint(op.endpoint) + httpRequest.BuildNMAEndpoint(op.endpoint) catalogPath, ok := op.catalogPathMap[host] if !ok { @@ -112,7 +112,7 @@ func (op *NMADownloadConfigOp) prepare(execContext *OpEngineExecContext) error { op.hosts = primaryUpHosts } - execContext.dispatcher.setup(op.hosts) + execContext.dispatcher.Setup(op.hosts) return op.setupClusterHTTPRequest(op.hosts) } diff --git a/vclusterops/nma_download_file_op.go b/vclusterops/nma_download_file_op.go index 977fd40..7b6d093 100644 --- a/vclusterops/nma_download_file_op.go +++ b/vclusterops/nma_download_file_op.go @@ -131,7 +131,7 @@ func (op *NMADownloadFileOp) setupClusterHTTPRequest(hosts []string) error { for _, host := range hosts { httpRequest := HostHTTPRequest{} httpRequest.Method = PostMethod - httpRequest.buildNMAEndpoint("vertica/download-file") + httpRequest.BuildNMAEndpoint("vertica/download-file") httpRequest.RequestData = op.hostRequestBodyMap[host] op.clusterHTTPRequest.RequestCollection[host] = httpRequest @@ -141,7 +141,7 @@ func (op *NMADownloadFileOp) setupClusterHTTPRequest(hosts []string) error { } func (op *NMADownloadFileOp) prepare(execContext *OpEngineExecContext) error { - execContext.dispatcher.setup(op.hosts) + execContext.dispatcher.Setup(op.hosts) return op.setupClusterHTTPRequest(op.hosts) } diff --git a/vclusterops/nma_get_nodes_info_op.go b/vclusterops/nma_get_nodes_info_op.go index 266198a..fe5dded 100644 --- a/vclusterops/nma_get_nodes_info_op.go +++ b/vclusterops/nma_get_nodes_info_op.go @@ -48,7 +48,7 @@ func (op *nmaGetNodesInfoOp) setupClusterHTTPRequest(hosts []string) error { for _, host := range hosts { httpRequest := HostHTTPRequest{} httpRequest.Method = GetMethod - httpRequest.buildNMAEndpoint("nodes") + httpRequest.BuildNMAEndpoint("nodes") httpRequest.QueryParams = map[string]string{"db_name": op.dbName, "catalog_prefix": op.catalogPrefix} op.clusterHTTPRequest.RequestCollection[host] = httpRequest } @@ -57,7 +57,7 @@ func (op *nmaGetNodesInfoOp) setupClusterHTTPRequest(hosts []string) error { } func (op *nmaGetNodesInfoOp) prepare(execContext *OpEngineExecContext) error { - execContext.dispatcher.setup(op.hosts) + execContext.dispatcher.Setup(op.hosts) return op.setupClusterHTTPRequest(op.hosts) } diff --git a/vclusterops/nma_health_op.go b/vclusterops/nma_health_op.go index f3568b4..0e7c4cd 100644 --- a/vclusterops/nma_health_op.go +++ b/vclusterops/nma_health_op.go @@ -38,7 +38,7 @@ func (op *NMAHealthOp) setupClusterHTTPRequest(hosts []string) error { for _, host := range hosts { httpRequest := HostHTTPRequest{} httpRequest.Method = GetMethod - httpRequest.buildNMAEndpoint("health") + httpRequest.BuildNMAEndpoint("health") op.clusterHTTPRequest.RequestCollection[host] = httpRequest } @@ -46,7 +46,7 @@ func (op *NMAHealthOp) setupClusterHTTPRequest(hosts []string) error { } func (op *NMAHealthOp) prepare(execContext *OpEngineExecContext) error { - execContext.dispatcher.setup(op.hosts) + execContext.dispatcher.Setup(op.hosts) return op.setupClusterHTTPRequest(op.hosts) } diff --git a/vclusterops/nma_load_remote_catalog_op.go b/vclusterops/nma_load_remote_catalog_op.go index a3cfeb7..7875528 100644 --- a/vclusterops/nma_load_remote_catalog_op.go +++ b/vclusterops/nma_load_remote_catalog_op.go @@ -114,7 +114,7 @@ func (op *nmaLoadRemoteCatalogOp) setupClusterHTTPRequest(hosts []string) error for _, host := range hosts { httpRequest := HostHTTPRequest{} httpRequest.Method = PostMethod - httpRequest.buildNMAEndpoint("catalog/revive") + httpRequest.BuildNMAEndpoint("catalog/revive") httpRequest.RequestData = op.hostRequestBodyMap[host] httpRequest.Timeout = int(op.timeout) @@ -130,7 +130,7 @@ func (op *nmaLoadRemoteCatalogOp) prepare(execContext *OpEngineExecContext) erro return err } - execContext.dispatcher.setup(op.hosts) + execContext.dispatcher.Setup(op.hosts) return op.setupClusterHTTPRequest(op.hosts) } diff --git a/vclusterops/nma_network_profile_op.go b/vclusterops/nma_network_profile_op.go index f7863c8..b0219d2 100644 --- a/vclusterops/nma_network_profile_op.go +++ b/vclusterops/nma_network_profile_op.go @@ -39,7 +39,7 @@ func (op *NMANetworkProfileOp) setupClusterHTTPRequest(hosts []string) error { for _, host := range hosts { httpRequest := HostHTTPRequest{} httpRequest.Method = GetMethod - httpRequest.buildNMAEndpoint("network-profiles") + httpRequest.BuildNMAEndpoint("network-profiles") httpRequest.QueryParams = map[string]string{"broadcast-hint": host} op.clusterHTTPRequest.RequestCollection[host] = httpRequest @@ -49,7 +49,7 @@ func (op *NMANetworkProfileOp) setupClusterHTTPRequest(hosts []string) error { } func (op *NMANetworkProfileOp) prepare(execContext *OpEngineExecContext) error { - execContext.dispatcher.setup(op.hosts) + execContext.dispatcher.Setup(op.hosts) return op.setupClusterHTTPRequest(op.hosts) } diff --git a/vclusterops/nma_prepare_directories_op.go b/vclusterops/nma_prepare_directories_op.go index 87879eb..012cc4c 100644 --- a/vclusterops/nma_prepare_directories_op.go +++ b/vclusterops/nma_prepare_directories_op.go @@ -88,7 +88,7 @@ func (op *NMAPrepareDirectoriesOp) setupClusterHTTPRequest(hosts []string) error for _, host := range hosts { httpRequest := HostHTTPRequest{} httpRequest.Method = PostMethod - httpRequest.buildNMAEndpoint("directories/prepare") + httpRequest.BuildNMAEndpoint("directories/prepare") httpRequest.RequestData = op.hostRequestBodyMap[host] op.clusterHTTPRequest.RequestCollection[host] = httpRequest } @@ -97,7 +97,7 @@ func (op *NMAPrepareDirectoriesOp) setupClusterHTTPRequest(hosts []string) error } func (op *NMAPrepareDirectoriesOp) prepare(execContext *OpEngineExecContext) error { - execContext.dispatcher.setup(op.hosts) + execContext.dispatcher.Setup(op.hosts) return op.setupClusterHTTPRequest(op.hosts) } diff --git a/vclusterops/nma_re_ip_op.go b/vclusterops/nma_re_ip_op.go index 9860beb..bcd0bc1 100644 --- a/vclusterops/nma_re_ip_op.go +++ b/vclusterops/nma_re_ip_op.go @@ -78,7 +78,7 @@ func (op *NMAReIPOp) setupClusterHTTPRequest(hosts []string) error { for _, host := range hosts { httpRequest := HostHTTPRequest{} httpRequest.Method = PutMethod - httpRequest.buildNMAEndpoint("catalog/re-ip") + httpRequest.BuildNMAEndpoint("catalog/re-ip") httpRequest.RequestData = op.hostRequestBodyMap[host] op.clusterHTTPRequest.RequestCollection[host] = httpRequest @@ -170,7 +170,7 @@ func (op *NMAReIPOp) prepare(execContext *OpEngineExecContext) error { return err } - execContext.dispatcher.setup(op.hosts) + execContext.dispatcher.Setup(op.hosts) return op.setupClusterHTTPRequest(op.hosts) } diff --git a/vclusterops/nma_read_catalog_editor_op.go b/vclusterops/nma_read_catalog_editor_op.go index bc2f92d..8561b36 100644 --- a/vclusterops/nma_read_catalog_editor_op.go +++ b/vclusterops/nma_read_catalog_editor_op.go @@ -55,7 +55,7 @@ func (op *NMAReadCatalogEditorOp) setupClusterHTTPRequest(hosts []string) error for _, host := range hosts { httpRequest := HostHTTPRequest{} httpRequest.Method = GetMethod - httpRequest.buildNMAEndpoint("catalog/database") + httpRequest.BuildNMAEndpoint("catalog/database") catalogPath, ok := op.catalogPathMap[host] if !ok { @@ -92,7 +92,7 @@ func (op *NMAReadCatalogEditorOp) prepare(execContext *OpEngineExecContext) erro } } - execContext.dispatcher.setup(op.hosts) + execContext.dispatcher.Setup(op.hosts) return op.setupClusterHTTPRequest(op.hosts) } @@ -144,12 +144,6 @@ type NmaVNode struct { StartCommand []string `json:"start_command"` StorageLocations []string `json:"storage_locations"` Tag json.Number `json:"tag"` - Subcluster struct { - Name string `json:"sc_name"` - IsPrimary bool `json:"is_primary_sc"` - IsDefault bool `json:"is_default"` - IsSandbox bool `json:"sandbox"` - } `json:"sc_details"` } type NmaVDatabase struct { @@ -157,11 +151,11 @@ type NmaVDatabase struct { Versions NmaVersions `json:"versions"` Nodes []NmaVNode `json:"nodes"` // this map will not be unmarshaled but will be used in NMAStartNodeOp - HostNodeMap map[string]*NmaVNode `json:",omitempty"` - ControlMode string `json:"control_mode"` - WillUpgrade bool `json:"will_upgrade"` - SpreadEncryption string `json:"spread_encryption"` - CommunalStorageLocation string `json:"communal_storage_location"` + HostNodeMap map[string]NmaVNode `json:",omitempty"` + ControlMode string `json:"control_mode"` + WillUpgrade bool `json:"will_upgrade"` + SpreadEncryption string `json:"spread_encryption"` + CommunalStorageLocation string `json:"communal_storage_location"` // primary node count will not be unmarshaled but will be used in NMAReIPOp PrimaryNodeCount uint `json:",omitempty"` } @@ -186,10 +180,10 @@ func (op *NMAReadCatalogEditorOp) processResult(execContext *OpEngineExecContext var primaryNodeCount uint // build host to node map for NMAStartNodeOp - hostNodeMap := make(map[string]*NmaVNode) + hostNodeMap := make(map[string]NmaVNode) for i := 0; i < len(nmaVDB.Nodes); i++ { n := nmaVDB.Nodes[i] - hostNodeMap[n.Address] = &n + hostNodeMap[n.Address] = n if n.IsPrimary { primaryNodeCount++ } diff --git a/vclusterops/nma_spread_security_op.go b/vclusterops/nma_spread_security_op.go index 8a4fb19..7cb7c67 100644 --- a/vclusterops/nma_spread_security_op.go +++ b/vclusterops/nma_spread_security_op.go @@ -92,7 +92,7 @@ func (op *nmaSpreadSecurityOp) setupClusterHTTPRequest(hostRequestBodyMap map[st for host, requestBody := range hostRequestBodyMap { httpRequest := HostHTTPRequest{} httpRequest.Method = PostMethod - httpRequest.buildNMAEndpoint("catalog/spread-security") + httpRequest.BuildNMAEndpoint("catalog/spread-security") httpRequest.RequestData = requestBody op.clusterHTTPRequest.RequestCollection[host] = httpRequest } @@ -108,7 +108,7 @@ func (op *nmaSpreadSecurityOp) prepare(execContext *OpEngineExecContext) error { if err != nil { return err } - execContext.dispatcher.setup(op.hosts) + execContext.dispatcher.Setup(op.hosts) return op.setupClusterHTTPRequest(hostRequestBodyMap) } diff --git a/vclusterops/nma_start_node_op.go b/vclusterops/nma_start_node_op.go index 8221f55..c9adde7 100644 --- a/vclusterops/nma_start_node_op.go +++ b/vclusterops/nma_start_node_op.go @@ -101,7 +101,7 @@ func (op *nmaStartNodeOp) setupClusterHTTPRequest(hosts []string) error { for _, host := range hosts { httpRequest := HostHTTPRequest{} httpRequest.Method = PostMethod - httpRequest.buildNMAEndpoint("nodes/start") + httpRequest.BuildNMAEndpoint("nodes/start") httpRequest.RequestData = op.hostRequestBodyMap[host] op.clusterHTTPRequest.RequestCollection[host] = httpRequest } @@ -115,7 +115,7 @@ func (op *nmaStartNodeOp) prepare(execContext *OpEngineExecContext) error { return err } - execContext.dispatcher.setup(op.hosts) + execContext.dispatcher.Setup(op.hosts) return op.setupClusterHTTPRequest(op.hosts) } diff --git a/vclusterops/nma_upload_config.go b/vclusterops/nma_upload_config.go index 971fe80..34bf4c0 100644 --- a/vclusterops/nma_upload_config.go +++ b/vclusterops/nma_upload_config.go @@ -94,7 +94,7 @@ func (op *NMAUploadConfigOp) setupClusterHTTPRequest(hosts []string) error { for _, host := range hosts { httpRequest := HostHTTPRequest{} httpRequest.Method = PostMethod - httpRequest.buildNMAEndpoint(op.endpoint) + httpRequest.BuildNMAEndpoint(op.endpoint) httpRequest.RequestData = op.hostRequestBodyMap[host] op.clusterHTTPRequest.RequestCollection[host] = httpRequest } @@ -147,7 +147,7 @@ func (op *NMAUploadConfigOp) prepare(execContext *OpEngineExecContext) error { if err != nil { return err } - execContext.dispatcher.setup(op.hosts) + execContext.dispatcher.Setup(op.hosts) return op.setupClusterHTTPRequest(op.hosts) } diff --git a/vclusterops/nma_vertica_version_op.go b/vclusterops/nma_vertica_version_op.go index 89f1ea8..2fbedde 100644 --- a/vclusterops/nma_vertica_version_op.go +++ b/vclusterops/nma_vertica_version_op.go @@ -23,61 +23,29 @@ import ( "github.com/vertica/vcluster/vclusterops/vlog" ) -const ( - NoVersion = "NO_VERSION" - DefaultSC = "default_subcluster" -) - -type HostVersionMap map[string]string +const NoVersion = "NO_VERSION" type NMAVerticaVersionOp struct { OpBase - IsEon bool RequireSameVersion bool - HasIncomingSCNames bool - SCToHostVersionMap map[string]HostVersionMap - vdb *VCoordinationDatabase -} - -func makeHostVersionMap() HostVersionMap { - return make(HostVersionMap) -} - -func makeSCToHostVersionMap() map[string]HostVersionMap { - return make(map[string]HostVersionMap) + HostVersionMap map[string]string } -// makeNMAVerticaVersionOp is used when db has not been created -func makeNMAVerticaVersionOp(log vlog.Printer, hosts []string, sameVersion, isEon bool) NMAVerticaVersionOp { +func makeNMAVerticaVersionOp(log vlog.Printer, hosts []string, sameVersion bool) NMAVerticaVersionOp { nmaVerticaVersionOp := NMAVerticaVersionOp{} nmaVerticaVersionOp.name = "NMAVerticaVersionOp" nmaVerticaVersionOp.log = log.WithName(nmaVerticaVersionOp.name) nmaVerticaVersionOp.hosts = hosts nmaVerticaVersionOp.RequireSameVersion = sameVersion - nmaVerticaVersionOp.IsEon = isEon - nmaVerticaVersionOp.SCToHostVersionMap = makeSCToHostVersionMap() + nmaVerticaVersionOp.HostVersionMap = map[string]string{} return nmaVerticaVersionOp } -// makeNMAVerticaVersionOpWithoutHosts is used when db is down -func makeNMAVerticaVersionOpWithoutHosts(log vlog.Printer, sameVersion bool) NMAVerticaVersionOp { - // isEon is set to false temporarily, it will get the correct value from execute context in prepare() - return makeNMAVerticaVersionOp(log, nil, sameVersion, false) -} - -// makeNMAVerticaVersionOpWithVDB is used when db is up -func makeNMAVerticaVersionOpWithVDB(log vlog.Printer, sameVersion bool, vdb *VCoordinationDatabase) NMAVerticaVersionOp { - op := makeNMAVerticaVersionOp(log, nil, sameVersion, false) - op.vdb = vdb - op.IsEon = vdb.IsEon - return op -} - func (op *NMAVerticaVersionOp) setupClusterHTTPRequest(hosts []string) error { for _, host := range hosts { httpRequest := HostHTTPRequest{} httpRequest.Method = GetMethod - httpRequest.buildNMAEndpoint("vertica/version") + httpRequest.BuildNMAEndpoint("vertica/version") op.clusterHTTPRequest.RequestCollection[host] = httpRequest } @@ -85,63 +53,7 @@ func (op *NMAVerticaVersionOp) setupClusterHTTPRequest(hosts []string) error { } func (op *NMAVerticaVersionOp) prepare(execContext *OpEngineExecContext) error { - /* - * Initialize SCToHostVersionMap in three cases: - * - when db is up, we initialize SCToHostVersionMap using vdb content (from Vertica https service) - * - when db is down, we initialize SCToHostVersionMap using nmaVDatabase (from NMA /catalog/database) in execute context - * - when db has not been created, we initialize SCToHostVersionMap using op.hosts (from user input) - * An example of initialized SCToHostVersionMap: - { - "default_subcluster" : {"192.168.0.101": "", "192.168.0.102": ""}, - "subcluster1" : {"192.168.0.103": "", "192.168.0.104": ""}, - "subcluster2" : {"192.168.0.105": "", "192.168.0.106": ""}, - } - * - */ - if op.vdb != nil { - op.HasIncomingSCNames = true - for host, vnode := range op.vdb.HostNodeMap { - op.hosts = append(op.hosts, host) - sc := vnode.Subcluster - // Update subcluster of new nodes that will be assigned to default subcluster. - // When we created vdb in db_add_node without specifying subcluster, we did not know the default subcluster name - // so new nodes is using "" as their subclusters. Below line will correct node nodes' subclusters. - if op.vdb.IsEon && sc == "" && execContext.defaultSCName != "" { - op.vdb.HostNodeMap[host].Subcluster = execContext.defaultSCName - sc = execContext.defaultSCName - } - - // initialize the SCToHostVersionMap with empty versions - if op.SCToHostVersionMap[sc] == nil { - op.SCToHostVersionMap[sc] = makeHostVersionMap() - } - op.SCToHostVersionMap[sc][host] = "" - } - } else if len(op.hosts) == 0 { - op.HasIncomingSCNames = true - if execContext.nmaVDatabase.CommunalStorageLocation != "" { - op.IsEon = true - } - for host, vnode := range execContext.nmaVDatabase.HostNodeMap { - op.hosts = append(op.hosts, host) - // initialize the SCToHostVersionMap with empty versions - sc := vnode.Subcluster.Name - if op.SCToHostVersionMap[sc] == nil { - op.SCToHostVersionMap[sc] = makeHostVersionMap() - } - op.SCToHostVersionMap[sc][host] = "" - } - } else { - // When creating a db, the subclusters of all nodes will be the same so set it to a fixed value. - sc := DefaultSC - // initialize the SCToHostVersionMap with empty versions - op.SCToHostVersionMap[sc] = makeHostVersionMap() - for _, host := range op.hosts { - op.SCToHostVersionMap[sc][host] = "" - } - } - - execContext.dispatcher.setup(op.hosts) + execContext.dispatcher.Setup(op.hosts) return op.setupClusterHTTPRequest(op.hosts) } @@ -177,12 +89,7 @@ func (op *NMAVerticaVersionOp) parseAndCheckResponse(host, resultContent string) } op.log.Info("JSON response", "host", host, "responseObj", responseObj) - // update version for the host in SCToHostVersionMap - for sc, hostVersionMap := range op.SCToHostVersionMap { - if _, exists := hostVersionMap[host]; exists { - op.SCToHostVersionMap[sc][host] = version - } - } + op.HostVersionMap[host] = version return nil } @@ -207,41 +114,22 @@ func (op *NMAVerticaVersionOp) logResponseCollectVersions() error { } func (op *NMAVerticaVersionOp) logCheckVersionMatch() error { - /* An example of SCToHostVersionMap: - { - "default_subcluster" : {"192.168.0.101": "Vertica Analytic Database v24.1.0", "192.168.0.102": "Vertica Analytic Database v24.1.0"}, - "subcluster1" : {"192.168.0.103": "Vertica Analytic Database v24.0.0", "192.168.0.104": "Vertica Analytic Database v24.0.0"}, - "subcluster2" : {"192.168.0.105": "Vertica Analytic Database v24.0.0", "192.168.0.106": "Vertica Analytic Database v24.0.0"}, - } - */ - var versionStr string - for sc, hostVersionMap := range op.SCToHostVersionMap { - versionStr = NoVersion - for host, version := range hostVersionMap { - op.log.Info("version check", "host", host, "version", version) - if version == "" { - if op.IsEon && op.HasIncomingSCNames { - return fmt.Errorf("[%s] No version collected for host [%s] in subcluster [%s]", op.name, host, sc) - } - return fmt.Errorf("[%s] No version collected for host [%s]", op.name, host) - } else if versionStr == NoVersion { - // first time seeing a valid version, set it as the versionStr - versionStr = version - } else if version != versionStr && op.RequireSameVersion { - if op.IsEon && op.HasIncomingSCNames { - return fmt.Errorf("[%s] Found mismatched versions: [%s] and [%s] in subcluster [%s]", op.name, versionStr, version, sc) - } - return fmt.Errorf("[%s] Found mismatched versions: [%s] and [%s]", op.name, versionStr, version) - } - } - // no version collected at all - if versionStr == NoVersion { - if op.IsEon && op.HasIncomingSCNames { - return fmt.Errorf("[%s] No version collected for all hosts in subcluster [%s]", op.name, sc) - } - return fmt.Errorf("[%s] No version collected for all hosts", op.name) + versionStr := NoVersion + for host, version := range op.HostVersionMap { + op.log.Info("version check", "host", host, "version", version) + if version == "" { + return fmt.Errorf("[%s] No version collected for host: [%s]", op.name, host) + } else if versionStr == NoVersion { + // first time seeing a valid version, set it as the versionStr + versionStr = version + } else if version != versionStr && op.RequireSameVersion { + return fmt.Errorf("[%s] Found mismatched versions: [%s] and [%s]", op.name, versionStr, version) } } + // no version collected at all + if versionStr == NoVersion { + return fmt.Errorf("[%s] No version collected for all hosts", op.name) + } return nil } diff --git a/vclusterops/nma_vertica_version_op_test.go b/vclusterops/nma_vertica_version_op_test.go deleted file mode 100644 index adfd971..0000000 --- a/vclusterops/nma_vertica_version_op_test.go +++ /dev/null @@ -1,126 +0,0 @@ -/* - (c) Copyright [2023] Open Text. - Licensed under the Apache License, Version 2.0 (the "License"); - You may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package vclusterops - -import ( - "strings" - "testing" - - "github.com/stretchr/testify/assert" - "github.com/vertica/vcluster/vclusterops/vlog" -) - -func TestLogCheckVersionMatch(t *testing.T) { - op := makeNMAVerticaVersionOp(vlog.Printer{}, nil, true, true) - op.HasIncomingSCNames = true - - // case 1. one subcluster (enterprise db is one example of this case) - // positive test - op.SCToHostVersionMap[""] = HostVersionMap{ - "192.168.0.101": "Vertica Analytic Database v24.1.0", - "192.168.0.102": "Vertica Analytic Database v24.1.0", - "192.168.0.103": "Vertica Analytic Database v24.1.0", - } - err := op.logCheckVersionMatch() - assert.NoError(t, err) - // negative test - op.SCToHostVersionMap = makeSCToHostVersionMap() - op.SCToHostVersionMap["default_subcluster"] = HostVersionMap{ - "192.168.0.101": "Vertica Analytic Database v24.1.0", - "192.168.0.102": "Vertica Analytic Database v24.1.0", - "192.168.0.103": "Vertica Analytic Database v23.4.0", - } - err = op.logCheckVersionMatch() - assert.Error(t, err) - expectedErr1 := "Found mismatched versions: " + - "[Vertica Analytic Database v24.1.0] and [Vertica Analytic Database v23.4.0] in subcluster [default_subcluster]" - expectedErr2 := "Found mismatched versions: " + - "[Vertica Analytic Database v23.4.0] and [Vertica Analytic Database v24.1.0] in subcluster [default_subcluster]" - isExpected := strings.Contains(err.Error(), expectedErr1) || strings.Contains(err.Error(), expectedErr2) - assert.Equal(t, true, isExpected) - - // case 2. multiple subclusters - // positive test - op.SCToHostVersionMap = makeSCToHostVersionMap() - op.SCToHostVersionMap["default_subcluster"] = HostVersionMap{ - "192.168.0.101": "Vertica Analytic Database v24.1.0", - "192.168.0.102": "Vertica Analytic Database v24.1.0", - "192.168.0.103": "Vertica Analytic Database v24.1.0", - } - op.SCToHostVersionMap["sc1"] = HostVersionMap{ - "192.168.0.104": "Vertica Analytic Database v23.4.0", - "192.168.0.105": "Vertica Analytic Database v23.4.0", - "192.168.0.106": "Vertica Analytic Database v23.4.0", - } - op.SCToHostVersionMap["sc2"] = HostVersionMap{ - "192.168.0.107": "Vertica Analytic Database v23.3.0", - "192.168.0.108": "Vertica Analytic Database v23.3.0", - "192.168.0.109": "Vertica Analytic Database v23.3.0", - } - err = op.logCheckVersionMatch() - assert.NoError(t, err) - // negative test 1 - op.SCToHostVersionMap = makeSCToHostVersionMap() - op.SCToHostVersionMap["default_subcluster"] = HostVersionMap{ - "192.168.0.101": "Vertica Analytic Database v24.1.0", - "192.168.0.102": "Vertica Analytic Database v24.1.0", - "192.168.0.103": "Vertica Analytic Database v24.1.0", - } - op.SCToHostVersionMap["sc1"] = HostVersionMap{ - "192.168.0.104": "Vertica Analytic Database v23.4.0", - "192.168.0.105": "Vertica Analytic Database v23.4.0", - "192.168.0.106": "Vertica Analytic Database v23.4.0", - } - op.SCToHostVersionMap["sc2"] = HostVersionMap{ - "192.168.0.107": "Vertica Analytic Database v23.4.0", - "192.168.0.108": "Vertica Analytic Database v23.3.0", - "192.168.0.109": "Vertica Analytic Database v23.4.0", - } - err = op.logCheckVersionMatch() - assert.Error(t, err) - expectedErr1 = "Found mismatched versions: " + - "[Vertica Analytic Database v23.4.0] and [Vertica Analytic Database v23.3.0] in subcluster [sc2]" - expectedErr2 = "Found mismatched versions: " + - "[Vertica Analytic Database v23.3.0] and [Vertica Analytic Database v23.4.0] in subcluster [sc2]" - isExpected = strings.Contains(err.Error(), expectedErr1) || strings.Contains(err.Error(), expectedErr2) - assert.Equal(t, true, isExpected) - - // case 3: no version found in the nodes - // no version found for one node - op.SCToHostVersionMap = makeSCToHostVersionMap() - op.SCToHostVersionMap["default_subcluster"] = HostVersionMap{ - "192.168.0.101": "Vertica Analytic Database v24.1.0", - "192.168.0.102": "Vertica Analytic Database v24.1.0", - "192.168.0.103": "", - } - op.SCToHostVersionMap["sc1"] = HostVersionMap{ - "192.168.0.104": "Vertica Analytic Database v23.4.0", - "192.168.0.105": "Vertica Analytic Database v23.4.0", - "192.168.0.106": "Vertica Analytic Database v23.4.0", - } - err = op.logCheckVersionMatch() - assert.ErrorContains(t, err, "No version collected for host [192.168.0.103] in subcluster [default_subcluster]") - // no version found for all the nodes in a subcluster - op.SCToHostVersionMap = makeSCToHostVersionMap() - op.SCToHostVersionMap["default_subcluster"] = HostVersionMap{ - "192.168.0.101": "Vertica Analytic Database v24.1.0", - "192.168.0.102": "Vertica Analytic Database v24.1.0", - "192.168.0.103": "Vertica Analytic Database v24.1.0", - } - op.SCToHostVersionMap["sc1"] = HostVersionMap{} - err = op.logCheckVersionMatch() - assert.ErrorContains(t, err, "No version collected for all hosts in subcluster [sc1]") -} diff --git a/vclusterops/re_ip.go b/vclusterops/re_ip.go index 3da0c1d..8708f05 100644 --- a/vclusterops/re_ip.go +++ b/vclusterops/re_ip.go @@ -34,7 +34,7 @@ type VReIPOptions struct { func VReIPFactory() VReIPOptions { opt := VReIPOptions{} // set default values to the params - opt.setDefaultValues() + opt.SetDefaultValues() return opt } @@ -49,7 +49,7 @@ func (opt *VReIPOptions) validateParseOptions(log vlog.Printer) error { return util.ValidateCommunalStorageLocation(*opt.CommunalStorageLocation) } - return opt.validateBaseOptions("re_ip", log) + return opt.ValidateBaseOptions("re_ip", log) } func (opt *VReIPOptions) analyzeOptions() error { @@ -62,7 +62,7 @@ func (opt *VReIPOptions) analyzeOptions() error { return nil } -func (opt *VReIPOptions) validateAnalyzeOptions(log vlog.Printer) error { +func (opt *VReIPOptions) ValidateAnalyzeOptions(log vlog.Printer) error { if err := opt.validateParseOptions(log); err != nil { return err } @@ -115,7 +115,7 @@ func (vcc *VClusterCommands) VReIP(options *VReIPOptions) error { * - Give the instructions to the VClusterOpEngine to run */ - err := options.validateAnalyzeOptions(vcc.Log) + err := options.ValidateAnalyzeOptions(vcc.Log) if err != nil { return err } @@ -146,10 +146,10 @@ func (vcc *VClusterCommands) VReIP(options *VReIPOptions) error { // create a VClusterOpEngine, and add certs to the engine certs := HTTPSCerts{key: options.Key, cert: options.Cert, caCert: options.CaCert} - clusterOpEngine := makeClusterOpEngine(instructions, &certs) + clusterOpEngine := MakeClusterOpEngine(instructions, &certs) // give the instructions to the VClusterOpEngine to run - runError := clusterOpEngine.run(vcc.Log) + runError := clusterOpEngine.Run(vcc.Log) if runError != nil { return fmt.Errorf("fail to re-ip: %w", runError) } @@ -160,6 +160,7 @@ func (vcc *VClusterCommands) VReIP(options *VReIPOptions) error { // The generated instructions will later perform the following operations necessary // for a successful re_ip: // - Check NMA connectivity +// - Check Vertica versions // - Read database info from catalog editor // (now we should know which hosts have the latest catalog) // - Run re-ip on the target nodes @@ -173,6 +174,7 @@ func (vcc *VClusterCommands) produceReIPInstructions(options *VReIPOptions, vdb hosts := options.Hosts nmaHealthOp := makeNMAHealthOp(vcc.Log, hosts) + nmaVerticaVersionOp := makeNMAVerticaVersionOp(vcc.Log, hosts, true) // get network profiles of the new addresses var newAddresses []string @@ -183,6 +185,7 @@ func (vcc *VClusterCommands) produceReIPInstructions(options *VReIPOptions, vdb instructions = append(instructions, &nmaHealthOp, + &nmaVerticaVersionOp, &nmaNetworkProfileOp, ) diff --git a/vclusterops/re_ip_test.go b/vclusterops/re_ip_test.go index c0f61b0..4066a21 100644 --- a/vclusterops/re_ip_test.go +++ b/vclusterops/re_ip_test.go @@ -26,23 +26,23 @@ import ( func TestReIPOptions(t *testing.T) { opt := VReIPFactory() - err := opt.validateAnalyzeOptions(vlog.Printer{}) + err := opt.ValidateAnalyzeOptions(vlog.Printer{}) assert.Error(t, err) *opt.DBName = "test_db" opt.RawHosts = []string{"192.168.1.101", "192.168.1.102"} - err = opt.validateAnalyzeOptions(vlog.Printer{}) + err = opt.ValidateAnalyzeOptions(vlog.Printer{}) assert.ErrorContains(t, err, "must specify an absolute catalog path") *opt.CatalogPrefix = "/data" - err = opt.validateAnalyzeOptions(vlog.Printer{}) + err = opt.ValidateAnalyzeOptions(vlog.Printer{}) assert.ErrorContains(t, err, "the re-ip list is not provided") var info ReIPInfo info.NodeAddress = "192.168.1.102" info.TargetAddress = "192.168.1.103" opt.ReIPList = append(opt.ReIPList, info) - err = opt.validateAnalyzeOptions(vlog.Printer{}) + err = opt.ValidateAnalyzeOptions(vlog.Printer{}) assert.NoError(t, err) } diff --git a/vclusterops/remove_node.go b/vclusterops/remove_node.go index 4b1328c..51a4597 100644 --- a/vclusterops/remove_node.go +++ b/vclusterops/remove_node.go @@ -38,13 +38,13 @@ type VRemoveNodeOptions struct { func VRemoveNodeOptionsFactory() VRemoveNodeOptions { opt := VRemoveNodeOptions{} // set default values to the params - opt.setDefaultValues() + opt.SetDefaultValues() return opt } -func (o *VRemoveNodeOptions) setDefaultValues() { - o.DatabaseOptions.setDefaultValues() +func (o *VRemoveNodeOptions) SetDefaultValues() { + o.DatabaseOptions.SetDefaultValues() o.ForceDelete = new(bool) *o.ForceDelete = true @@ -65,7 +65,7 @@ func (o *VRemoveNodeOptions) ParseHostToRemoveList(hosts string) error { } func (o *VRemoveNodeOptions) validateRequiredOptions(log vlog.Printer) error { - err := o.validateBaseOptions("db_remove_node", log) + err := o.ValidateBaseOptions("db_remove_node", log) if err != nil { return err } @@ -116,7 +116,7 @@ func (o *VRemoveNodeOptions) validateAnalyzeOptions(log vlog.Printer) error { if err != nil { return err } - return o.setUsePassword(log) + return o.SetUsePassword(log) } func (vcc *VClusterCommands) VRemoveNode(options *VRemoveNodeOptions) (VCoordinationDatabase, error) { @@ -129,7 +129,7 @@ func (vcc *VClusterCommands) VRemoveNode(options *VRemoveNodeOptions) (VCoordina } // get db name and hosts from config file and options. - dbName, hosts, err := options.getNameAndHosts(options.Config) + dbName, hosts, err := options.GetNameAndHosts(options.Config) if err != nil { return vdb, err } @@ -169,14 +169,14 @@ func (vcc *VClusterCommands) VRemoveNode(options *VRemoveNodeOptions) (VCoordina } certs := HTTPSCerts{key: options.Key, cert: options.Cert, caCert: options.CaCert} - clusterOpEngine := makeClusterOpEngine(instructions, &certs) - if runError := clusterOpEngine.run(vcc.Log); runError != nil { + clusterOpEngine := MakeClusterOpEngine(instructions, &certs) + if runError := clusterOpEngine.Run(vcc.Log); runError != nil { return vdb, fmt.Errorf("fail to complete remove node operation, %w", runError) } remainingHosts := util.SliceDiff(vdb.HostList, options.HostsToRemove) // we return a vdb that contains only the remaining hosts - return vdb.copy(remainingHosts), nil + return vdb.Copy(remainingHosts), nil } // checkRemoveNodeRequirements validates the following remove_node requirements: @@ -266,7 +266,7 @@ func (vcc *VClusterCommands) produceRemoveNodeInstructions(vdb *VCoordinationDat // this is a copy of the original that only // contains the hosts to remove. - v := vdb.copy(options.HostsToRemove) + v := vdb.Copy(options.HostsToRemove) if vdb.IsEon { // we pass the set of subclusters of the nodes to remove. err = vcc.produceRebalanceSubclusterShardsOps(&instructions, initiatorHost, v.getSCNames(), diff --git a/vclusterops/remove_subcluster.go b/vclusterops/remove_subcluster.go index c856f21..65b3a8c 100644 --- a/vclusterops/remove_subcluster.go +++ b/vclusterops/remove_subcluster.go @@ -41,13 +41,13 @@ func VRemoveScOptionsFactory() VRemoveScOptions { } func (o *VRemoveScOptions) setDefaultValues() { - o.DatabaseOptions.setDefaultValues() + o.DatabaseOptions.SetDefaultValues() o.SubclusterToRemove = new(string) o.ForceDelete = new(bool) } func (o *VRemoveScOptions) validateRequiredOptions(log vlog.Printer) error { - err := o.validateBaseOptions("db_remove_subcluster", log) + err := o.ValidateBaseOptions("db_remove_subcluster", log) if err != nil { return err } @@ -101,7 +101,7 @@ func (o *VRemoveScOptions) validateAnalyzeOptions(log vlog.Printer) error { if err != nil { return err } - return o.setUsePassword(log) + return o.SetUsePassword(log) } /* @@ -212,8 +212,8 @@ func (vcc *VClusterCommands) removeScPreCheck(vdb *VCoordinationDatabase, option ) certs := HTTPSCerts{key: options.Key, cert: options.Cert, caCert: options.CaCert} - clusterOpEngine := makeClusterOpEngine(instructions, &certs) - err = clusterOpEngine.run(vcc.Log) + clusterOpEngine := MakeClusterOpEngine(instructions, &certs) + err = clusterOpEngine.Run(vcc.Log) if err != nil { // VER-88585 will improve this rfc error flow if strings.Contains(err.Error(), "does not exist in the database") { @@ -262,8 +262,8 @@ func (vcc *VClusterCommands) dropSubcluster(vdb *VCoordinationDatabase, options instructions = append(instructions, &httpsDropScOp) certs := HTTPSCerts{key: options.Key, cert: options.Cert, caCert: options.CaCert} - clusterOpEngine := makeClusterOpEngine(instructions, &certs) - err = clusterOpEngine.run(vcc.Log) + clusterOpEngine := MakeClusterOpEngine(instructions, &certs) + err = clusterOpEngine.Run(vcc.Log) if err != nil { vcc.Log.Error(err, "fail to drop subcluster, details: %v", dropScErrMsg) return err diff --git a/vclusterops/restart_node.go b/vclusterops/restart_node.go index ff388ce..f4dbc68 100644 --- a/vclusterops/restart_node.go +++ b/vclusterops/restart_node.go @@ -52,11 +52,11 @@ func VRestartNodesOptionsFactory() VRestartNodesOptions { } func (options *VRestartNodesOptions) setDefaultValues() { - options.DatabaseOptions.setDefaultValues() + options.DatabaseOptions.SetDefaultValues() } func (options *VRestartNodesOptions) validateRequiredOptions(log vlog.Printer) error { - err := options.validateBaseOptions("restart_node", log) + err := options.ValidateBaseOptions("restart_node", log) if err != nil { return err } @@ -102,7 +102,7 @@ func (options *VRestartNodesOptions) ParseNodesList(nodeListStr string) error { return nil } -func (options *VRestartNodesOptions) validateAnalyzeOptions(log vlog.Printer) error { +func (options *VRestartNodesOptions) ValidateAnalyzeOptions(log vlog.Printer) error { if err := options.validateParseOptions(log); err != nil { return err } @@ -120,13 +120,13 @@ func (vcc *VClusterCommands) VRestartNodes(options *VRestartNodesOptions) error */ // validate and analyze options - err := options.validateAnalyzeOptions(vcc.Log) + err := options.ValidateAnalyzeOptions(vcc.Log) if err != nil { return err } // get db name and hosts from config file and options - dbName, hosts, err := options.getNameAndHosts(options.Config) + dbName, hosts, err := options.GetNameAndHosts(options.Config) if err != nil { return err } @@ -181,10 +181,10 @@ func (vcc *VClusterCommands) VRestartNodes(options *VRestartNodesOptions) error // create a VClusterOpEngine, and add certs to the engine certs := HTTPSCerts{key: options.Key, cert: options.Cert, caCert: options.CaCert} - clusterOpEngine := makeClusterOpEngine(instructions, &certs) + clusterOpEngine := MakeClusterOpEngine(instructions, &certs) // Give the instructions to the VClusterOpEngine to run - err = clusterOpEngine.run(vcc.Log) + err = clusterOpEngine.Run(vcc.Log) if err != nil { return fmt.Errorf("fail to restart node, %w", err) } @@ -197,14 +197,13 @@ func (vcc *VClusterCommands) VRestartNodes(options *VRestartNodesOptions) error // The generated instructions will later perform the following operations necessary // for a successful restart_node: // - Check NMA connectivity -// - Get UP nodes through HTTPS call, if any node is UP then the DB is UP and ready for starting nodes -// - If need to do re-ip: -// 1. Call network profile -// 2. Call https re-ip endpoint -// 3. Reload spread -// 4. Call https /v1/nodes to update nodes' info // - Check Vertica versions -// - Use any UP primary nodes as source host for syncing spread.conf and vertica.conf +// - Call network profile +// - Call https re-ip endpoint +// - Reload spread +// - Get UP nodes through HTTPS call, if any node is UP then the DB is UP and ready for starting nodes +// - Use any UP primary nodes as source host for syncing spread.conf and vertica.conf, source host can be picked +// by a HTTPS /v1/nodes call for finding UP primary nodes // - Sync the confs to the nodes to be restarted // - Call https /v1/startup/command to get restart command of the nodes to be restarted // - restart nodes @@ -215,8 +214,10 @@ func (vcc *VClusterCommands) produceRestartNodesInstructions(restartNodeInfo *VR var instructions []ClusterOp nmaHealthOp := makeNMAHealthOp(vcc.Log, options.Hosts) + // require to have the same vertica version + nmaVerticaVersionOp := makeNMAVerticaVersionOp(vcc.Log, options.Hosts, true) // need username for https operations - err := options.setUsePassword(vcc.Log) + err := options.SetUsePassword(vcc.Log) if err != nil { return instructions, err } @@ -228,6 +229,7 @@ func (vcc *VClusterCommands) produceRestartNodesInstructions(restartNodeInfo *VR } instructions = append(instructions, &nmaHealthOp, + &nmaVerticaVersionOp, &httpsGetUpNodesOp, ) @@ -260,10 +262,6 @@ func (vcc *VClusterCommands) produceRestartNodesInstructions(restartNodeInfo *VR ) } - // require to have the same vertica version - nmaVerticaVersionOp := makeNMAVerticaVersionOpWithVDB(vcc.Log, true, vdb) - instructions = append(instructions, &nmaVerticaVersionOp) - // The second parameter (sourceConfHost) in produceTransferConfigOps is set to a nil value in the upload and download step // we use information from v1/nodes endpoint to get all node information to update the sourceConfHost value // after we find any UP primary nodes as source host for syncing spread.conf and vertica.conf diff --git a/vclusterops/revive_db.go b/vclusterops/revive_db.go index 84deda4..f07c440 100644 --- a/vclusterops/revive_db.go +++ b/vclusterops/revive_db.go @@ -42,7 +42,7 @@ func VReviveDBOptionsFactory() VReviveDatabaseOptions { } func (options *VReviveDatabaseOptions) setDefaultValues() { - options.DatabaseOptions.setDefaultValues() + options.DatabaseOptions.SetDefaultValues() // set default values for revive db options options.LoadCatalogTimeout = new(uint) @@ -92,7 +92,7 @@ func (options *VReviveDatabaseOptions) analyzeOptions() (err error) { return nil } -func (options *VReviveDatabaseOptions) validateAnalyzeOptions() error { +func (options *VReviveDatabaseOptions) ValidateAnalyzeOptions() error { if err := options.validateParseOptions(); err != nil { return err } @@ -108,7 +108,7 @@ func (vcc *VClusterCommands) VReviveDatabase(options *VReviveDatabaseOptions) (d */ // validate and analyze options - err = options.validateAnalyzeOptions() + err = options.ValidateAnalyzeOptions() if err != nil { return dbInfo, err } @@ -124,8 +124,8 @@ func (vcc *VClusterCommands) VReviveDatabase(options *VReviveDatabaseOptions) (d // generate clusterOpEngine certs certs := HTTPSCerts{key: options.Key, cert: options.Cert, caCert: options.CaCert} // feed the pre-revive db instructions to the VClusterOpEngine - clusterOpEngine := makeClusterOpEngine(preReviveDBInstructions, &certs) - err = clusterOpEngine.run(vcc.Log) + clusterOpEngine := MakeClusterOpEngine(preReviveDBInstructions, &certs) + err = clusterOpEngine.Run(vcc.Log) if err != nil { return dbInfo, fmt.Errorf("fail to collect the information of database in revive_db %w", err) } @@ -142,8 +142,8 @@ func (vcc *VClusterCommands) VReviveDatabase(options *VReviveDatabaseOptions) (d } // feed revive db instructions to the VClusterOpEngine - clusterOpEngine = makeClusterOpEngine(reviveDBInstructions, &certs) - err = clusterOpEngine.run(vcc.Log) + clusterOpEngine = MakeClusterOpEngine(reviveDBInstructions, &certs) + err = clusterOpEngine.Run(vcc.Log) if err != nil { return dbInfo, fmt.Errorf("fail to revive database %w", err) } @@ -159,6 +159,7 @@ func (vcc *VClusterCommands) VReviveDatabase(options *VReviveDatabaseOptions) (d // producePreReviveDBInstructions will build the first half of revive_db instructions // The generated instructions will later perform the following operations // - Check NMA connectivity +// - Check NMA version // - Check any DB running on the hosts // - Download and read the description file from communal storage on the initiator func (vcc *VClusterCommands) producePreReviveDBInstructions(options *VReviveDatabaseOptions, @@ -166,6 +167,7 @@ func (vcc *VClusterCommands) producePreReviveDBInstructions(options *VReviveData var instructions []ClusterOp nmaHealthOp := makeNMAHealthOp(vcc.Log, options.Hosts) + nmaVerticaVersionOp := makeNMAVerticaVersionOp(vcc.Log, options.Hosts, true) checkDBRunningOp, err := makeHTTPCheckRunningDBOp(vcc.Log, options.Hosts, false, /*use password auth*/ "" /*username for https call*/, nil /*password for https call*/, ReviveDB) @@ -183,6 +185,7 @@ func (vcc *VClusterCommands) producePreReviveDBInstructions(options *VReviveData instructions = append(instructions, &nmaHealthOp, + &nmaVerticaVersionOp, &checkDBRunningOp, &nmaDownLoadFileOp, ) diff --git a/vclusterops/start_db.go b/vclusterops/start_db.go index 326dd81..1aae413 100644 --- a/vclusterops/start_db.go +++ b/vclusterops/start_db.go @@ -34,22 +34,22 @@ func VStartDatabaseOptionsFactory() VStartDatabaseOptions { opt := VStartDatabaseOptions{} // set default values to the params - opt.setDefaultValues() + opt.SetDefaultValues() return opt } -func (options *VStartDatabaseOptions) setDefaultValues() { - options.DatabaseOptions.setDefaultValues() +func (options *VStartDatabaseOptions) SetDefaultValues() { + options.DatabaseOptions.SetDefaultValues() } func (options *VStartDatabaseOptions) validateRequiredOptions(log vlog.Printer) error { - err := options.validateBaseOptions("start_db", log) + err := options.ValidateBaseOptions("start_db", log) if err != nil { return err } if *options.HonorUserInput { - err = options.validateCatalogPath() + err = options.ValidateCatalogPath() if err != nil { return err } @@ -88,7 +88,7 @@ func (options *VStartDatabaseOptions) analyzeOptions() (err error) { return nil } -func (options *VStartDatabaseOptions) validateAnalyzeOptions(log vlog.Printer) error { +func (options *VStartDatabaseOptions) ValidateAnalyzeOptions(log vlog.Printer) error { if err := options.validateParseOptions(log); err != nil { return err } @@ -102,20 +102,20 @@ func (vcc *VClusterCommands) VStartDatabase(options *VStartDatabaseOptions) erro * - Give the instructions to the VClusterOpEngine to run */ - err := options.validateAnalyzeOptions(vcc.Log) + err := options.ValidateAnalyzeOptions(vcc.Log) if err != nil { return err } // get db name and hosts from config file and options - dbName, hosts, err := options.getNameAndHosts(options.Config) + dbName, hosts, err := options.GetNameAndHosts(options.Config) if err != nil { return err } options.DBName = &dbName options.Hosts = hosts - options.CatalogPrefix, err = options.getCatalogPrefix(options.Config) + options.CatalogPrefix, err = options.GetCatalogPrefix(options.Config) if err != nil { return err } @@ -127,7 +127,7 @@ func (vcc *VClusterCommands) VStartDatabase(options *VStartDatabaseOptions) erro var pVDB *VCoordinationDatabase // retrieve database information from cluster_config.json for EON databases - isEon, err := options.isEonMode(options.Config) + isEon, err := options.IsEonMode(options.Config) if err != nil { return err } @@ -157,10 +157,10 @@ func (vcc *VClusterCommands) VStartDatabase(options *VStartDatabaseOptions) erro // create a VClusterOpEngine, and add certs to the engine certs := HTTPSCerts{key: options.Key, cert: options.Cert, caCert: options.CaCert} - clusterOpEngine := makeClusterOpEngine(instructions, &certs) + clusterOpEngine := MakeClusterOpEngine(instructions, &certs) // Give the instructions to the VClusterOpEngine to run - runError := clusterOpEngine.run(vcc.Log) + runError := clusterOpEngine.Run(vcc.Log) if runError != nil { return fmt.Errorf("fail to start database: %w", runError) } @@ -174,9 +174,9 @@ func (vcc *VClusterCommands) VStartDatabase(options *VStartDatabaseOptions) erro // The generated instructions will later perform the following operations necessary // for a successful start_db: // - Check NMA connectivity +// - Check Vertica versions // - Check to see if any dbs running // - Use NMA /catalog/database to get the best source node for spread.conf and vertica.conf -// - Check Vertica versions // - Sync the confs to the rest of nodes who have lower catalog version (results from the previous step) // - Start all nodes of the database // - Poll node startup @@ -185,8 +185,10 @@ func (vcc *VClusterCommands) produceStartDBInstructions(options *VStartDatabaseO var instructions []ClusterOp nmaHealthOp := makeNMAHealthOp(vcc.Log, options.Hosts) + // require to have the same vertica version + nmaVerticaVersionOp := makeNMAVerticaVersionOp(vcc.Log, options.Hosts, true) // need username for https operations - err := options.setUsePassword(vcc.Log) + err := options.SetUsePassword(vcc.Log) if err != nil { return instructions, err } @@ -198,6 +200,7 @@ func (vcc *VClusterCommands) produceStartDBInstructions(options *VStartDatabaseO } instructions = append(instructions, &nmaHealthOp, + &nmaVerticaVersionOp, &checkDBRunningOp, ) @@ -213,12 +216,7 @@ func (vcc *VClusterCommands) produceStartDBInstructions(options *VStartDatabaseO if err != nil { return instructions, err } - // require to have the same vertica version - nmaVerticaVersionOp := makeNMAVerticaVersionOpWithoutHosts(vcc.Log, true) - instructions = append(instructions, - &nmaReadCatalogEditorOp, - &nmaVerticaVersionOp, - ) + instructions = append(instructions, &nmaReadCatalogEditorOp) if enabled, keyType := options.isSpreadEncryptionEnabled(); enabled { instructions = append(instructions, diff --git a/vclusterops/stop_db.go b/vclusterops/stop_db.go index 79de3f5..53fe56c 100644 --- a/vclusterops/stop_db.go +++ b/vclusterops/stop_db.go @@ -44,20 +44,20 @@ type VStopDatabaseInfo struct { func VStopDatabaseOptionsFactory() VStopDatabaseOptions { opt := VStopDatabaseOptions{} // set default values to the params - opt.setDefaultValues() + opt.SetDefaultValues() return opt } -func (options *VStopDatabaseOptions) setDefaultValues() { - options.DatabaseOptions.setDefaultValues() +func (options *VStopDatabaseOptions) SetDefaultValues() { + options.DatabaseOptions.SetDefaultValues() options.CheckUserConn = new(bool) options.ForceKill = new(bool) } func (options *VStopDatabaseOptions) validateRequiredOptions(log vlog.Printer) error { - err := options.validateBaseOptions("stop_db", log) + err := options.ValidateBaseOptions("stop_db", log) if err != nil { return err } @@ -67,7 +67,7 @@ func (options *VStopDatabaseOptions) validateRequiredOptions(log vlog.Printer) e func (options *VStopDatabaseOptions) validateEonOptions(config *ClusterConfig, log vlog.Printer) error { // if db is enterprise db and we see --drain-seconds, we will ignore it - isEon, err := options.isEonMode(config) + isEon, err := options.IsEonMode(config) if err != nil { return err } @@ -123,7 +123,7 @@ func (options *VStopDatabaseOptions) analyzeOptions() (err error) { return nil } -func (options *VStopDatabaseOptions) validateAnalyzeOptions(config *ClusterConfig, log vlog.Printer) error { +func (options *VStopDatabaseOptions) ValidateAnalyzeOptions(config *ClusterConfig, log vlog.Printer) error { if err := options.validateParseOptions(config, log); err != nil { return err } @@ -137,7 +137,7 @@ func (vcc *VClusterCommands) VStopDatabase(options *VStopDatabaseOptions) error * - Give the instructions to the VClusterOpEngine to run */ - err := options.validateAnalyzeOptions(options.Config, vcc.Log) + err := options.ValidateAnalyzeOptions(options.Config, vcc.Log) if err != nil { return err } @@ -147,12 +147,12 @@ func (vcc *VClusterCommands) VStopDatabase(options *VStopDatabaseOptions) error stopDBInfo.UserName = *options.UserName stopDBInfo.Password = options.Password stopDBInfo.DrainSeconds = options.DrainSeconds - stopDBInfo.DBName, stopDBInfo.Hosts, err = options.getNameAndHosts(options.Config) + stopDBInfo.DBName, stopDBInfo.Hosts, err = options.GetNameAndHosts(options.Config) if err != nil { return err } - stopDBInfo.IsEon, err = options.isEonMode(options.Config) + stopDBInfo.IsEon, err = options.IsEonMode(options.Config) if err != nil { return err } @@ -164,10 +164,10 @@ func (vcc *VClusterCommands) VStopDatabase(options *VStopDatabaseOptions) error // Create a VClusterOpEngine, and add certs to the engine certs := HTTPSCerts{key: options.Key, cert: options.Cert, caCert: options.CaCert} - clusterOpEngine := makeClusterOpEngine(instructions, &certs) + clusterOpEngine := MakeClusterOpEngine(instructions, &certs) // Give the instructions to the VClusterOpEngine to run - runError := clusterOpEngine.run(vcc.Log) + runError := clusterOpEngine.Run(vcc.Log) if runError != nil { return fmt.Errorf("fail to stop database: %w", runError) } @@ -193,7 +193,7 @@ func (vcc *VClusterCommands) produceStopDBInstructions(stopDBInfo *VStopDatabase usePassword := false if stopDBInfo.Password != nil { usePassword = true - err := options.validateUserName(vcc.Log) + err := options.ValidateUserName(vcc.Log) if err != nil { return instructions, err } diff --git a/vclusterops/vcluster_database_options.go b/vclusterops/vcluster_database_options.go index 2420ee4..c7d0a7d 100644 --- a/vclusterops/vcluster_database_options.go +++ b/vclusterops/vcluster_database_options.go @@ -72,7 +72,7 @@ const ( commandAddCluster = "db_add_subcluster" ) -func (opt *DatabaseOptions) setDefaultValues() { +func (opt *DatabaseOptions) SetDefaultValues() { opt.DBName = new(string) opt.CatalogPrefix = new(string) opt.DataPrefix = new(string) @@ -85,7 +85,7 @@ func (opt *DatabaseOptions) setDefaultValues() { opt.ConfigurationParameters = make(map[string]string) } -func (opt *DatabaseOptions) checkNilPointerParams() error { +func (opt *DatabaseOptions) CheckNilPointerParams() error { // basic params if opt.DBName == nil { return util.ParamNotSetErrorMsg("name") @@ -103,7 +103,7 @@ func (opt *DatabaseOptions) checkNilPointerParams() error { return nil } -func (opt *DatabaseOptions) validateBaseOptions(commandName string, log vlog.Printer) error { +func (opt *DatabaseOptions) ValidateBaseOptions(commandName string, log vlog.Printer) error { // get vcluster commands log.WithName(commandName) // database name @@ -116,19 +116,19 @@ func (opt *DatabaseOptions) validateBaseOptions(commandName string, log vlog.Pri } // raw hosts and password - err = opt.validateHostsAndPwd(commandName, log) + err = opt.ValidateHostsAndPwd(commandName, log) if err != nil { return err } // paths - err = opt.validatePaths(commandName) + err = opt.ValidatePaths(commandName) if err != nil { return err } // config directory - err = opt.validateConfigDir(commandName) + err = opt.ValidateConfigDir(commandName) if err != nil { return err } @@ -142,8 +142,8 @@ func (opt *DatabaseOptions) validateBaseOptions(commandName string, log vlog.Pri return nil } -// validateHostsAndPwd will validate raw hosts and password -func (opt *DatabaseOptions) validateHostsAndPwd(commandName string, log vlog.Printer) error { +// ValidateHostsAndPwd will validate raw hosts and password +func (opt *DatabaseOptions) ValidateHostsAndPwd(commandName string, log vlog.Printer) error { // when we create db, we need hosts and set password to "" if user did not provide one if commandName == commandCreateDB { // raw hosts @@ -172,7 +172,7 @@ func (opt *DatabaseOptions) validateHostsAndPwd(commandName string, log vlog.Pri } // validate catalog, data, and depot paths -func (opt *DatabaseOptions) validatePaths(commandName string) error { +func (opt *DatabaseOptions) ValidatePaths(commandName string) error { // validate for the following commands only // TODO: add other commands into the command list commands := []string{commandCreateDB, commandDropDB} @@ -181,7 +181,7 @@ func (opt *DatabaseOptions) validatePaths(commandName string) error { } // catalog prefix path - err := opt.validateCatalogPath() + err := opt.ValidateCatalogPath() if err != nil { return err } @@ -202,13 +202,13 @@ func (opt *DatabaseOptions) validatePaths(commandName string) error { return nil } -func (opt *DatabaseOptions) validateCatalogPath() error { +func (opt *DatabaseOptions) ValidateCatalogPath() error { // catalog prefix path return util.ValidateRequiredAbsPath(opt.CatalogPrefix, "catalog path") } // validate config directory -func (opt *DatabaseOptions) validateConfigDir(commandName string) error { +func (opt *DatabaseOptions) ValidateConfigDir(commandName string) error { // validate for the following commands only // TODO: add other commands into the command list commands := []string{commandCreateDB, commandDropDB, commandStopDB, commandStartDB, commandAddCluster} @@ -237,7 +237,7 @@ func (opt *DatabaseOptions) ParseHostList(hosts string) error { return nil } -func (opt *DatabaseOptions) validateUserName(log vlog.Printer) error { +func (opt *DatabaseOptions) ValidateUserName(log vlog.Printer) error { if *opt.UserName == "" { username, err := util.GetCurrentUsername() if err != nil { @@ -250,13 +250,13 @@ func (opt *DatabaseOptions) validateUserName(log vlog.Printer) error { return nil } -func (opt *DatabaseOptions) setUsePassword(log vlog.Printer) error { +func (opt *DatabaseOptions) SetUsePassword(log vlog.Printer) error { // when password is specified, // we will use username/password to call https endpoints opt.usePassword = false if opt.Password != nil { opt.usePassword = true - err := opt.validateUserName(log) + err := opt.ValidateUserName(log) if err != nil { return err } @@ -265,8 +265,8 @@ func (opt *DatabaseOptions) setUsePassword(log vlog.Printer) error { return nil } -// isEonMode can choose the right eon mode from user input and config file -func (opt *DatabaseOptions) isEonMode(config *ClusterConfig) (bool, error) { +// IsEonMode can choose the right eon mode from user input and config file +func (opt *DatabaseOptions) IsEonMode(config *ClusterConfig) (bool, error) { // when config file is not available, we use user input // HonorUserInput must be true at this time, otherwise vcluster has stopped when it cannot find the config file if config == nil { @@ -286,8 +286,8 @@ func (opt *DatabaseOptions) isEonMode(config *ClusterConfig) (bool, error) { return isEon, nil } -// getNameAndHosts can choose the right dbName and hosts from user input and config file -func (opt *DatabaseOptions) getNameAndHosts(config *ClusterConfig) (dbName string, hosts []string, err error) { +// GetNameAndHosts can choose the right dbName and hosts from user input and config file +func (opt *DatabaseOptions) GetNameAndHosts(config *ClusterConfig) (dbName string, hosts []string, err error) { // when config file is not available, we use user input // HonorUserInput must be true at this time, otherwise vcluster has stopped when it cannot find the config file dbName = *opt.DBName @@ -301,7 +301,7 @@ func (opt *DatabaseOptions) getNameAndHosts(config *ClusterConfig) (dbName strin return dbName, hosts, cannotFindDBFromConfigErr(dbName) } - hosts = dbConfig.getHosts() + hosts = dbConfig.GetHosts() // if HonorUserInput is set, we choose the user input if *opt.DBName != "" && *opt.HonorUserInput { dbName = *opt.DBName @@ -312,8 +312,8 @@ func (opt *DatabaseOptions) getNameAndHosts(config *ClusterConfig) (dbName strin return dbName, hosts, nil } -// getHosts chooses the right hosts from user input and config file -func (opt *DatabaseOptions) getHosts(config *ClusterConfig) (hosts []string, err error) { +// GetHosts chooses the right hosts from user input and config file +func (opt *DatabaseOptions) GetHosts(config *ClusterConfig) (hosts []string, err error) { // when config file is not available, we use user input // HonorUserInput must be true at this time, otherwise vcluster has stopped when it cannot find the config file if config == nil { @@ -325,7 +325,7 @@ func (opt *DatabaseOptions) getHosts(config *ClusterConfig) (hosts []string, err return hosts, cannotFindDBFromConfigErr(*opt.DBName) } - hosts = dbConfig.getHosts() + hosts = dbConfig.GetHosts() // if HonorUserInput is set, we choose the user input if len(opt.Hosts) > 0 && *opt.HonorUserInput { hosts = opt.Hosts @@ -333,8 +333,8 @@ func (opt *DatabaseOptions) getHosts(config *ClusterConfig) (hosts []string, err return hosts, nil } -// getCatalogPrefix can choose the right catalog prefix from user input and config file -func (opt *DatabaseOptions) getCatalogPrefix(clusterConfig *ClusterConfig) (catalogPrefix *string, err error) { +// GetCatalogPrefix can choose the right catalog prefix from user input and config file +func (opt *DatabaseOptions) GetCatalogPrefix(clusterConfig *ClusterConfig) (catalogPrefix *string, err error) { // when config file is not available, we use user input // HonorUserInput must be true at this time, otherwise vcluster has stopped when it cannot find the config file if clusterConfig == nil { @@ -450,8 +450,8 @@ func (opt *DatabaseOptions) getVDBWhenDBIsDown(vcc *VClusterCommands) (vdb VCoor ) certs := HTTPSCerts{key: opt.Key, cert: opt.Cert, caCert: opt.CaCert} - clusterOpEngine := makeClusterOpEngine(instructions1, &certs) - err = clusterOpEngine.run(vcc.Log) + clusterOpEngine := MakeClusterOpEngine(instructions1, &certs) + err = clusterOpEngine.Run(vcc.Log) if err != nil { vcc.Log.PrintError("fail to retrieve node names from NMA /nodes: %v", err) return vdb, err @@ -468,8 +468,8 @@ func (opt *DatabaseOptions) getVDBWhenDBIsDown(vcc *VClusterCommands) (vdb VCoor } instructions2 = append(instructions2, &nmaDownLoadFileOp) - clusterOpEngine = makeClusterOpEngine(instructions2, &certs) - err = clusterOpEngine.run(vcc.Log) + clusterOpEngine = MakeClusterOpEngine(instructions2, &certs) + err = clusterOpEngine.Run(vcc.Log) if err != nil { vcc.Log.PrintError("fail to retrieve node details from %s: %v", descriptionFileName, err) return vdb, err