Skip to content

Commit

Permalink
Sync from server repo (e07e5e2bf3f)
Browse files Browse the repository at this point in the history
  • Loading branch information
jizhuoyu committed Jun 18, 2024
1 parent bf13430 commit 937a09c
Show file tree
Hide file tree
Showing 8 changed files with 163 additions and 8 deletions.
4 changes: 4 additions & 0 deletions commands/cluster_command_launcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,8 @@ const (
scrutinizeSubCmd = "scrutinize"
showRestorePointsSubCmd = "show_restore_points"
installPkgSubCmd = "install_packages"
// hidden Cmds (for internal testing only)
promoteSandboxSubCmd = "promote_sandbox"
)

// cmdGlobals holds global variables shared by multiple
Expand Down Expand Up @@ -535,6 +537,8 @@ func constructCmds() []*cobra.Command {
makeCmdManageConfig(),
makeCmdReplication(),
makeCmdCreateConnection(),
// hidden cmds (for internal testing only)
makeCmdPromoteSandbox(),
}
}

Expand Down
130 changes: 130 additions & 0 deletions commands/cmd_promote_sandbox.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
/*
(c) Copyright [2023-2024] 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.
DISCLAIMER:
The subcommand (promote_sandbox) within this file is intended solely for internal testing purposes.
It is not designed, intended, or authorized for use in production environments. The behavior of this
subcommand may change without prior notice and is not guaranteed to be maintained in future releases.
Use of this function in any production code or reliance upon its behavior is strongly discouraged and
undertaken at your own risk. Open Text assumes no responsibility for any consequences arising from the
use of this function outside of its intended testing context.
*/

package commands

import (
"github.com/spf13/cobra"
"github.com/spf13/viper"
"github.com/vertica/vcluster/vclusterops"
"github.com/vertica/vcluster/vclusterops/vlog"
)

/* cmdPromoteSandbox
*
* Parses arguments to promote a sandbox to main cluster.
* This should not be used by VCluster CLI users. See the disclaimer above.
*
* Implements ClusterCommand interface
*/
type cmdPromoteSandbox struct {
promoteSandboxOpts *vclusterops.VPromoteSandboxToMainOptions
CmdBase
}

func makeCmdPromoteSandbox() *cobra.Command {
newCmd := &cmdPromoteSandbox{}
opt := vclusterops.VPromoteSandboxToMainFactory()
newCmd.promoteSandboxOpts = &opt

cmd := makeBasicCobraCmd(
newCmd,
promoteSandboxSubCmd,
"",
"",
[]string{dbNameFlag, hostsFlag, ipv6Flag, eonModeFlag, configFlag, passwordFlag},
)

// local flags
newCmd.setLocalFlags(cmd)

// required flags
markFlagsRequired(cmd, sandboxFlag)

// hide this subcommand
cmd.Hidden = true

return cmd
}

// setLocalFlags will set the local flags the command has
func (c *cmdPromoteSandbox) setLocalFlags(cmd *cobra.Command) {
cmd.Flags().StringVar(
&c.promoteSandboxOpts.SandboxName,
sandboxFlag,
"",
"The name of the sandbox",
)
}

func (c *cmdPromoteSandbox) Parse(inputArgv []string, logger vlog.Printer) error {
c.argv = inputArgv
logger.LogArgParse(&c.argv)

// reset some options that are not included in user input
c.ResetUserInputOptions(&c.promoteSandboxOpts.DatabaseOptions)

// promote_sandbox only works for an Eon db so we assume the user always runs this subcommand
// on an Eon db. When Eon mode cannot be found in config file, we set its value to true.
if !viper.IsSet(eonModeKey) {
c.promoteSandboxOpts.IsEon = true
}

return c.validateParse(logger)
}

func (c *cmdPromoteSandbox) validateParse(logger vlog.Printer) error {
logger.Info("Called validateParse()")
if !c.usePassword() {
err := c.getCertFilesFromCertPaths(&c.promoteSandboxOpts.DatabaseOptions)
if err != nil {
return err
}
}

err := c.ValidateParseBaseOptions(&c.promoteSandboxOpts.DatabaseOptions)
if err != nil {
return err
}
return c.setDBPassword(&c.promoteSandboxOpts.DatabaseOptions)
}

func (c *cmdPromoteSandbox) Run(vcc vclusterops.ClusterCommands) error {
vcc.LogInfo("Called method Run()")

options := c.promoteSandboxOpts

err := vcc.VPromoteSandboxToMain(options)
if err != nil {
vcc.LogError(err, "fail to promote sandbox to main", "sandbox", c.promoteSandboxOpts.SandboxName)
return err
}
vcc.DisplayInfo("Successfully promoted sandbox %q to main", c.promoteSandboxOpts.SandboxName)
return nil
}

// SetDatabaseOptions will assign a vclusterops.DatabaseOptions instance to the one in CmdPromoteSandbox
func (c *cmdPromoteSandbox) SetDatabaseOptions(opt *vclusterops.DatabaseOptions) {
c.promoteSandboxOpts.DatabaseOptions = *opt
}
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ go 1.20

require (
github.com/deckarep/golang-set/v2 v2.3.1
github.com/fatih/color v1.14.1
github.com/go-logr/logr v1.2.4
github.com/go-logr/zapr v1.2.4
github.com/spf13/cobra v1.8.0
Expand All @@ -16,6 +17,7 @@ require (
go.uber.org/zap v1.25.0
golang.org/x/exp v0.0.0-20230905200255-921286631fa9
golang.org/x/sys v0.15.0
golang.org/x/term v0.15.0
gopkg.in/yaml.v3 v3.0.1
k8s.io/apimachinery v0.26.2
)
Expand All @@ -28,7 +30,6 @@ require (
github.com/aws/aws-sdk-go v1.49.5 // indirect
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/emicklei/go-restful/v3 v3.11.0 // indirect
github.com/fatih/color v1.14.1 // indirect
github.com/fsnotify/fsnotify v1.7.0 // indirect
github.com/go-openapi/jsonpointer v0.19.5 // indirect
github.com/go-openapi/jsonreference v0.20.0 // indirect
Expand Down Expand Up @@ -71,7 +72,6 @@ require (
golang.org/x/net v0.19.0 // indirect
golang.org/x/oauth2 v0.15.0 // indirect
golang.org/x/sync v0.5.0 // indirect
golang.org/x/term v0.15.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/time v0.5.0 // indirect
google.golang.org/api v0.153.0 // indirect
Expand Down
9 changes: 8 additions & 1 deletion vclusterops/cluster_op.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,7 +227,7 @@ func (op *opBase) setLogger(logger vlog.Printer) {
func (op *opBase) parseAndCheckResponse(host, responseContent string, responseObj any) error {
err := util.GetJSONLogErrors(responseContent, &responseObj, op.name, op.logger)
if err != nil {
op.logger.Error(err, "fail to parse response on host, detail", "host", host)
op.logger.Error(err, "fail to parse response on host, detail", "host", host, "original responseContent", responseContent)
return err
}
op.logger.Info("JSON response", "host", host, "responseObj", responseObj)
Expand All @@ -248,6 +248,13 @@ func (op *opBase) parseAndCheckStringResponse(host, responseContent string) (str
return responseStr, err
}

func (op *opBase) parseAndCheckGenericJSONResponse(host, responseContent string) (nmaGenericJSONResponse, error) {
var genericResponse nmaGenericJSONResponse
err := op.parseAndCheckResponse(host, responseContent, &genericResponse)

return genericResponse, err
}

func (op *opBase) setClusterHTTPRequestName() {
op.clusterHTTPRequest.Name = op.name
}
Expand Down
6 changes: 6 additions & 0 deletions vclusterops/helpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -468,3 +468,9 @@ func (vcc *VClusterCommands) doReIP(options *DatabaseOptions, scName string,

return nil
}

// An nmaGenericJSONResponse is the default response that is generated,
// the response value is of type "string" in JSON format.
type nmaGenericJSONResponse struct {
RespStr string
}
3 changes: 2 additions & 1 deletion vclusterops/nma_get_config_parameter_op.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,10 +121,11 @@ func (op *nmaGetConfigurationParameterOp) processResult(_ *opEngineExecContext)
op.logResponse(host, result)

if result.isPassing() {
err := op.parseAndCheckResponse(host, result.content, op.retrievedParamValue)
genericResponse, err := op.parseAndCheckGenericJSONResponse(host, result.content)
if err != nil {
allErrs = errors.Join(allErrs, err)
}
*op.retrievedParamValue = genericResponse.RespStr
} else {
allErrs = errors.Join(allErrs, result.err)
}
Expand Down
11 changes: 7 additions & 4 deletions vclusterops/promote_sandbox_to_main.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ func (opt *VPromoteSandboxToMainOptions) validateEonOptions(_ vlog.Printer) erro
if !opt.IsEon {
return fmt.Errorf("promote a sandbox to main is only supported in Eon mode")
}
if opt.SandboxName == "" {
return fmt.Errorf("must specify a sandbox name")
}
return nil
}

Expand All @@ -49,12 +52,12 @@ func (opt *VPromoteSandboxToMainOptions) validateParseOptions(logger vlog.Printe
return err
}

// need to provide a password or certs in source database
if opt.Password == nil && (opt.Cert == "" || opt.Key == "") {
return fmt.Errorf("must provide a password or a key-certificate pair")
err = opt.validateBaseOptions(PromoteSandboxToMainCmd, logger)
if err != nil {
return err
}

return opt.validateBaseOptions(PromoteSandboxToMainCmd, logger)
return opt.validateAuthOptions("", logger)
}

// analyzeOptions will modify some options based on what is chosen
Expand Down
4 changes: 4 additions & 0 deletions vclusterops/promote_sandbox_to_main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ func TestPromoteSandboxToMainOptions_validateParseOptions(t *testing.T) {
opt.Password = &testPassword

err := opt.validateParseOptions(logger)
assert.ErrorContains(t, err, "must specify a sandbox name")

opt.SandboxName = "sand1"
err = opt.validateParseOptions(logger)
assert.NoError(t, err)

opt.UserName = ""
Expand Down

0 comments on commit 937a09c

Please sign in to comment.