diff --git a/.golangci.yml b/.golangci.yml index 3ceb39966..ffa44752b 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,12 +1,11 @@ +version: "2" linters: - disable-all: true + default: none enable: - dupword - errcheck - - gci - gocheckcompilerdirectives - godot - - goimports - ineffassign - misspell - nolintlint @@ -14,36 +13,65 @@ linters: - unconvert - unparam - unused - fast: false - -linters-settings: - errcheck: - check-type-assertions: true - - gci: - sections: - - standard - - default - - misspell: - locale: US - extra-words: - - typo: "cancelation" - correction: "cancellation" - - typo: "cancelations" - correction: "cancellations" - - typo: "cancelling" - correction: "canceling" - - typo: "cancelled" - correction: "canceled" + settings: + errcheck: + check-type-assertions: true + misspell: + locale: US + extra-words: + - typo: cancelation + correction: cancellation + - typo: cancelations + correction: cancellations + - typo: cancelling + correction: canceling + - typo: cancelled + correction: canceled + staticcheck: + checks: + # default rules: + - "all" + - "-ST1000" + - "-ST1003" + - "-ST1016" + - "-ST1020" + - "-ST1021" + - "-ST1022" + # custom: + - "-ST1005" + exclusions: + generated: lax + presets: + - comments + - common-false-positives + - legacy + - std-error-handling + rules: + - linters: + - staticcheck + path: \.go$ + text: is deprecated + - path: (.+)\.go$ + text: "composites: .+(primitive.(Binary|Decimal128|E|Timestamp)|types.(Destination|Source)(Client|Database)) struct literal uses unkeyed fields" + paths: + - third_party$ + - builtin$ + - examples$ issues: max-same-issues: 0 - exclude: - - "composites: .+(primitive.(Binary|Decimal128|E|Timestamp)|types.(Destination|Source)(Client|Database)) struct literal uses unkeyed fields" - # TODO (TOOLS-3633): Remove this exclusion and actually fix the issues. - exclude-rules: - - path: '\.go$' - linters: - - staticcheck - text: "is deprecated" +formatters: + enable: + - gci + - goimports + settings: + gci: + sections: + - standard + - default + exclusions: + generated: lax + paths: + - third_party$ + - builtin$ + - examples$ diff --git a/bsondump/bsondump.go b/bsondump/bsondump.go index e36b6f2e3..d35c3d1bd 100644 --- a/bsondump/bsondump.go +++ b/bsondump/bsondump.go @@ -11,7 +11,6 @@ import ( "bytes" "fmt" "io" - "math" "os" "strings" "time" @@ -96,7 +95,7 @@ func New(opts Options) (*BSONDump, error) { // 16kb + 16mb - This is the maximum size we would get when dumping the // oplog itself. See https://jira.mongodb.org/browse/TOOLS-3001. - maxBSONSize := (16 * 1024) + (16 * math.Pow(1024, 2)) + maxBSONSize := (16 * 1024) + (16 * float64(1024*1024)) dumper.InputSource.SetMaxBSONSize(int32(maxBSONSize)) writer, err := opts.GetWriter() diff --git a/bsondump/bsondump_test.go b/bsondump/bsondump_test.go index 3a1736eb0..9e370988a 100644 --- a/bsondump/bsondump_test.go +++ b/bsondump/bsondump_test.go @@ -9,7 +9,6 @@ package bsondump import ( "bytes" "crypto/rand" - "math" "os" "os/exec" "path/filepath" @@ -273,7 +272,7 @@ func TestBsondumpMaxBSONSize(t *testing.T) { testtype.SkipUnlessTestType(t, testtype.UnitTestType) // 16mb + 16kb - maxSize := int(16*math.Pow(1024, 2)) + sixteenKB + maxSize := int(16*float64(1024*1024)) + sixteenKB t.Run("bsondump with file at exactly max size of 16mb + 16kb", func(t *testing.T) { _, err := runBsondumpWithLargeFile(t, maxSize) diff --git a/buildscript/build.go b/buildscript/build.go index 5b578bd0d..e1ed5dc6a 100644 --- a/buildscript/build.go +++ b/buildscript/build.go @@ -39,7 +39,7 @@ func CheckMinimumGoVersion(ctx *task.Context) error { return fmt.Errorf("failed to get current go version: %w", err) } - _, _ = ctx.Write([]byte(fmt.Sprintf("Found Go version \"%s\"\n", goVersionStr))) + _, _ = fmt.Fprintf(ctx, "Found Go version \"%s\"\n", goVersionStr) versionPattern := `go(\d+\.\d+\.*\d*)` @@ -232,13 +232,14 @@ func getBuildFlags(ctx *task.Context, forTests bool) []string { pf, err := getPlatform() if err == nil { - if pf.OS == platform.OSLinux { + switch pf.OS { + case platform.OSLinux: // We don't want to enable -buildmode=pie for tests. This interferes with enabling the race // detector. if !forTests { flags = append(flags, "-buildmode=pie") } - } else if pf.OS == platform.OSWindows { + case platform.OSWindows: flags = append(flags, "-buildmode=exe") } } else { diff --git a/buildscript/deps.go b/buildscript/deps.go index a8f0a74ba..8d3516ccb 100644 --- a/buildscript/deps.go +++ b/buildscript/deps.go @@ -108,11 +108,11 @@ func stopPodmanMachine(ctx *task.Context) error { var ( // This matches a file that starts with "license" or "licence", in any // case, with an optional extension. - licenseRegexp1 = regexp.MustCompile("(?i)^licen[cs]e(?:\\..+)?$") + licenseRegexp1 = regexp.MustCompile(`(?i)^licen[cs]e(?:\..+)?$`) // This matches a file that has an extension of "license" or "licence", in // any case. - licenseRegexp2 = regexp.MustCompile("(?i)\\.licen[cs]e$") - trailingSpaceRegexp = regexp.MustCompile("(?m)[^\\n\\S]+$") + licenseRegexp2 = regexp.MustCompile(`(?i)\.licen[cs]e$`) + trailingSpaceRegexp = regexp.MustCompile(`(?m)[^\\n\\S]+$`) horizontalLine = strings.Repeat("-", 70) ) diff --git a/buildscript/sa.go b/buildscript/sa.go index 280c17225..52cf94311 100644 --- a/buildscript/sa.go +++ b/buildscript/sa.go @@ -30,9 +30,9 @@ const ( // the new config file syntax did not seem trivial. eslintVersion = "8.57.0" gitHubCodeownersVersion = "0.2.1" - golangCILintVersion = "1.64.5" + golangCILintVersion = "2.2.2" golinesVersion = "0.12.2" - gosecVersion = "2.20.0" + gosecVersion = "2.22.5" preciousVersion = "0.7.3" ubiVersion = "0.4.2" prettierVersion = "3.4.2" @@ -408,9 +408,9 @@ func SAEvergreenValidate(ctx *task.Context) error { // See ticket for more details. if strings.HasSuffix(output, "is valid with warnings") { for _, line := range strings.Split(output, "\n") { - if !(strings.HasSuffix(line, "unmarshal errors:") || - strings.HasSuffix(line, "already set in map") || - strings.HasSuffix(line, "is valid with warnings")) { + if !strings.HasSuffix(line, "unmarshal errors:") && + !strings.HasSuffix(line, "already set in map") && + !strings.HasSuffix(line, "is valid with warnings") { return fmt.Errorf("error from `evergreen validate`: %s", output) } } diff --git a/common/archive/demultiplexer.go b/common/archive/demultiplexer.go index b82e46077..457821d8b 100644 --- a/common/archive/demultiplexer.go +++ b/common/archive/demultiplexer.go @@ -288,7 +288,7 @@ func (receiver *RegularCollectionReceiver) Sum64() (uint64, bool) { // Read() runs in the restoring goroutine. func (receiver *RegularCollectionReceiver) Read(r []byte) (int, error) { - if receiver.partialReadBuf != nil && len(receiver.partialReadBuf) > 0 { + if len(receiver.partialReadBuf) > 0 { wLen := len(receiver.partialReadBuf) copyLen := copy(r, receiver.partialReadBuf) if wLen == copyLen { @@ -552,7 +552,6 @@ func (prioritizer *Prioritizer) Get() *intents.Intent { } // Finish is part of the IntentPrioritizer interface, and does nothing. -func (prioritizer *Prioritizer) Finish(*intents.Intent) { +func (*Prioritizer) Finish(*intents.Intent) { // no-op - return } diff --git a/common/archive/multiplexer_roundtrip_test.go b/common/archive/multiplexer_roundtrip_test.go index aada60b9c..2c258470f 100644 --- a/common/archive/multiplexer_roundtrip_test.go +++ b/common/archive/multiplexer_roundtrip_test.go @@ -126,7 +126,6 @@ func TestBasicMux(t *testing.T) { }) }) }) - return } func TestParallelMux(t *testing.T) { @@ -193,7 +192,6 @@ func TestParallelMux(t *testing.T) { wg.Wait() So(demuxErr, ShouldBeNil) }) - return } func makeIns( @@ -386,6 +384,4 @@ func TestTOOLS2403(t *testing.T) { wg.Wait() require.NoError(demuxErr) - - return } diff --git a/common/archive/parser_test.go b/common/archive/parser_test.go index 4ebbe427c..a387d5ec1 100644 --- a/common/archive/parser_test.go +++ b/common/archive/parser_test.go @@ -163,5 +163,4 @@ func TestParsing(t *testing.T) { So(tc.bodies, ShouldBeNil) }) }) - return } diff --git a/common/archive/prelude.go b/common/archive/prelude.go index ce556d6ad..1a7e7d79a 100644 --- a/common/archive/prelude.go +++ b/common/archive/prelude.go @@ -114,7 +114,7 @@ func NewPrelude( prelude.AddMetadata(&CollectionMetadata{ Database: intent.DB, Collection: intent.C, - Metadata: archiveMetadata.Buffer.String(), + Metadata: archiveMetadata.String(), Type: intent.Type, }) } else { diff --git a/common/bsonutil/bsonutil.go b/common/bsonutil/bsonutil.go index 30cd5f3d3..5bec82370 100644 --- a/common/bsonutil/bsonutil.go +++ b/common/bsonutil/bsonutil.go @@ -38,7 +38,7 @@ func IsEqual(left, right bson.D) (bool, error) { return false, err } - return bytes.Compare(leftBytes, rightBytes) == 0, nil + return bytes.Equal(leftBytes, rightBytes), nil } // ConvertLegacyExtJSONDocumentToBSON iterates through the document map and converts JSON diff --git a/common/db/db.go b/common/db/db.go index 8d57c4af3..eea351676 100644 --- a/common/db/db.go +++ b/common/db/db.go @@ -123,7 +123,7 @@ func NewSessionProvider(opts options.ToolOptions) (*SessionProvider, error) { } err = client.Ping(context.Background(), nil) if err != nil { - return nil, fmt.Errorf("failed to connect to %s: %v", opts.URI.ParsedConnString(), err) + return nil, fmt.Errorf("failed to connect to %s: %v", opts.ParsedConnString(), err) } // create the provider @@ -279,7 +279,7 @@ func addCACertsFromFile(cfg *tls.Config, file string) error { cfg.RootCAs = x509.NewCertPool() } - if cfg.RootCAs.AppendCertsFromPEM(data) == false { + if !cfg.RootCAs.AppendCertsFromPEM(data) { return fmt.Errorf( "SSL trusted server certificates file does not contain any valid certificates. File: `%v`", file, @@ -317,7 +317,7 @@ func AKSCallback( // configure the client according to the options set in the uri and in the provided ToolOptions, with ToolOptions having precedence. func configureClient(opts options.ToolOptions) (*mongo.Client, error) { - if opts.URI == nil || opts.URI.ConnectionString == "" { + if opts.URI == nil || opts.ConnectionString == "" { // XXX Normal operations shouldn't ever reach here because a URI should // be created in options parsing, but tests still manually construct // options and generally don't construct a URI, so we invoke the URI @@ -328,7 +328,7 @@ func configureClient(opts options.ToolOptions) (*mongo.Client, error) { } clientopt := mopt.Client() - cs := opts.URI.ParsedConnString() + cs := opts.ParsedConnString() clientopt.Hosts = cs.Hosts @@ -338,9 +338,9 @@ func configureClient(opts options.ToolOptions) (*mongo.Client, error) { clientopt.SetConnectTimeout(time.Duration(opts.Timeout) * time.Second) clientopt.SetSocketTimeout(time.Duration(opts.SocketTimeout) * time.Second) - if opts.Connection.ServerSelectionTimeout > 0 { + if opts.ServerSelectionTimeout > 0 { clientopt.SetServerSelectionTimeout( - time.Duration(opts.Connection.ServerSelectionTimeout) * time.Second, + time.Duration(opts.ServerSelectionTimeout) * time.Second, ) } if opts.ReplicaSetName != "" { @@ -453,20 +453,21 @@ func configureClient(opts options.ToolOptions) (*mongo.Client, error) { clientopt.SetWriteConcern(writeconcern.New(opts...)) } - if opts.Auth != nil && opts.Auth.IsSet() { + if opts.Auth != nil && opts.IsSet() { cred := mopt.Credential{ - Username: opts.Auth.Username, - Password: opts.Auth.Password, + Username: opts.Username, + Password: opts.Password, AuthSource: opts.GetAuthenticationDatabase(), - AuthMechanism: opts.Auth.Mechanism, + AuthMechanism: opts.Mechanism, } - if cs.AuthMechanism == "MONGODB-AWS" { + switch cs.AuthMechanism { + case "MONGODB-AWS": cred.Username = cs.Username cred.Password = cs.Password cred.AuthSource = cs.AuthSource cred.AuthMechanism = cs.AuthMechanism cred.AuthMechanismProperties = cs.AuthMechanismProperties - } else if cs.AuthMechanism == "MONGODB-OIDC" { + case "MONGODB-OIDC": if env, ok := cs.AuthMechanismProperties["ENVIRONMENT"]; ok && env == "azure" { _, okApp := os.LookupEnv("AZURE_APP_CLIENT_ID") _, okClient := os.LookupEnv("AZURE_IDENTITY_CLIENT_ID") @@ -496,8 +497,8 @@ func configureClient(opts options.ToolOptions) (*mongo.Client, error) { } if opts.Kerberos != nil && cred.AuthMechanism == "GSSAPI" { props := make(map[string]string) - if opts.Kerberos.Service != "" { - props["SERVICE_NAME"] = opts.Kerberos.Service + if opts.Service != "" { + props["SERVICE_NAME"] = opts.Service } // XXX How do we use opts.Kerberos.ServiceHost if at all? cred.AuthMechanismProperties = props @@ -523,7 +524,7 @@ func configureClient(opts options.ToolOptions) (*mongo.Client, error) { } var x509Subject string - keyPasswd := opts.SSL.SSLPEMKeyPassword + keyPasswd := opts.SSLPEMKeyPassword var err error if cs.SSLClientCertificateKeyPasswordSet && cs.SSLClientCertificateKeyPassword != nil { keyPasswd = cs.SSLClientCertificateKeyPassword() diff --git a/common/db/db_test.go b/common/db/db_test.go index 481c3bee0..db9e0fac1 100644 --- a/common/db/db_test.go +++ b/common/db/db_test.go @@ -332,7 +332,7 @@ func TestServerCertificateVerification(t *testing.T) { SSL: &ssl, Auth: &auth, } - opts.URI.ConnString.SSLCaFile = "../db/testdata/ia.pem" + opts.ConnString.SSLCaFile = "../db/testdata/ia.pem" provider, err := NewSessionProvider(opts) So(err, ShouldBeNil) So(provider.client.Ping(context.Background(), nil), ShouldBeNil) @@ -366,7 +366,7 @@ func TestServerPKCS8Verification(t *testing.T) { SSL: &ssl, Auth: &auth, } - opts.URI.ConnString.SSLCaFile = "../db/testdata/ca-ia.pem" + opts.ConnString.SSLCaFile = "../db/testdata/ca-ia.pem" provider, err := NewSessionProvider(opts) So(err, ShouldBeNil) So(provider.client.Ping(context.Background(), nil), ShouldBeNil) @@ -387,7 +387,7 @@ func TestServerPKCS8Verification(t *testing.T) { SSL: &ssl, Auth: &auth, } - opts.URI.ConnString.SSLCaFile = "../db/testdata/ca-ia.pem" + opts.ConnString.SSLCaFile = "../db/testdata/ca-ia.pem" provider, err := NewSessionProvider(opts) So(err, ShouldBeNil) So(provider.client.Ping(context.Background(), nil), ShouldBeNil) @@ -481,7 +481,7 @@ func TestConfigureClientAKS(t *testing.T) { _, err = configureClient(*toolOptions) So(err, ShouldBeNil) - So(toolOptions.Auth.Mechanism, ShouldEqual, "MONGODB-OIDC") + So(toolOptions.Mechanism, ShouldEqual, "MONGODB-OIDC") os.Unsetenv("AZURE_APP_CLIENT_ID") os.Unsetenv("AZURE_IDENTITY_CLIENT_ID") os.Unsetenv("AZURE_TENANT_ID") diff --git a/common/db/query.go b/common/db/query.go index d85018d7e..0976020f9 100644 --- a/common/db/query.go +++ b/common/db/query.go @@ -26,7 +26,7 @@ func (q *DeferredQuery) Count(isView bool) (int, error) { filter = bson.D{} } else if val, ok := q.Filter.(bson.D); ok && (val == nil || len(val.Map()) == 0) { emptyFilter = true - } else if val, ok := q.Filter.(bson.M); ok && (val == nil || len(val) == 0) { + } else if val, ok := q.Filter.(bson.M); ok && (len(val) == 0) { emptyFilter = true } diff --git a/common/intents/intent_prioritizer.go b/common/intents/intent_prioritizer.go index d5745e96e..653502997 100644 --- a/common/intents/intent_prioritizer.go +++ b/common/intents/intent_prioritizer.go @@ -59,7 +59,6 @@ func (legacy *legacyPrioritizer) Get() *Intent { func (legacy *legacyPrioritizer) Finish(*Intent) { // no-op - return } //===== Longest Task First ===== @@ -95,7 +94,6 @@ func (ltf *longestTaskFirstPrioritizer) Get() *Intent { func (ltf *longestTaskFirstPrioritizer) Finish(*Intent) { // no-op - return } // BySizeAndView attaches the methods for sort.Interface for sorting intents diff --git a/common/json/encode.go b/common/json/encode.go index 6fa78fc5a..cf78600e5 100644 --- a/common/json/encode.go +++ b/common/json/encode.go @@ -643,8 +643,7 @@ func (me *mapEncoder) encode(e *encodeState, v reflect.Value, _ bool) { return } e.WriteByte('{') - var sv stringValues - sv = v.MapKeys() + var sv stringValues = v.MapKeys() sort.Sort(sv) for i, k := range sv { if i > 0 { diff --git a/common/json/encode_test.go b/common/json/encode_test.go index 6f39a3c17..6fb970d18 100644 --- a/common/json/encode_test.go +++ b/common/json/encode_test.go @@ -426,8 +426,8 @@ func TestStringBytes(t *testing.T) { t.Fatal(err) } - enc := es.Buffer.String() - encBytes := esBytes.Buffer.String() + enc := es.String() + encBytes := esBytes.String() if enc != encBytes { i := 0 for i < len(enc) && i < len(encBytes) && enc[i] == encBytes[i] { diff --git a/common/json/fold.go b/common/json/fold.go index cb8161061..371b70816 100644 --- a/common/json/fold.go +++ b/common/json/fold.go @@ -102,10 +102,8 @@ func equalFoldRight(s, t []byte) bool { t = t[size:] } - if len(t) > 0 { - return false - } - return true + + return len(t) == 0 } // asciiEqualFold is a specialization of bytes.EqualFold for use when diff --git a/common/json/json_format.go b/common/json/json_format.go index f91d4f0ba..0db8b6017 100644 --- a/common/json/json_format.go +++ b/common/json/json_format.go @@ -24,7 +24,7 @@ func (b BinData) MarshalJSON() ([]byte, error) { } func (d128 Decimal128) MarshalJSON() ([]byte, error) { - s := d128.Decimal128.String() + s := d128.String() return []byte(fmt.Sprintf(`{ "$numberDecimal" : "%s" }`, s)), nil } diff --git a/common/options/options.go b/common/options/options.go index d99cc18a8..b5e4fc41d 100644 --- a/common/options/options.go +++ b/common/options/options.go @@ -452,12 +452,12 @@ func (uri *URI) LogUnsupportedOptions() { // --authenticationDatabase if it's provided, otherwise, the database that's // specified in the tool's --db arg. func (opts *ToolOptions) GetAuthenticationDatabase() string { - if opts.Auth.Source != "" { - return opts.Auth.Source - } else if opts.Auth.RequiresExternalDB() { + if opts.Source != "" { + return opts.Source + } else if opts.RequiresExternalDB() { return "$external" - } else if opts.Namespace != nil && opts.Namespace.DB != "" { - return opts.Namespace.DB + } else if opts.Namespace != nil && opts.DB != "" { + return opts.DB } return "" } @@ -478,7 +478,7 @@ func (opts *ToolOptions) AddOptions(extraOpts ExtraOptions) { // AddToExtraOptionsRegistry appends an additional options group to the extra options // registry found in opts.URI. func (opts *ToolOptions) AddToExtraOptionsRegistry(extraOpts ExtraOptions) { - opts.URI.extraOptionsRegistry = append(opts.URI.extraOptionsRegistry, extraOpts) + opts.extraOptionsRegistry = append(opts.extraOptionsRegistry, extraOpts) } func (opts *ToolOptions) CallArgParser(args []string) ([]string, error) { @@ -563,12 +563,12 @@ func LogSensitiveOptionWarnings(args []string) { } // Log a message for --password, if specified. - if tempOpts.Auth.Password != "" { + if tempOpts.Password != "" { log.Logvf(log.Always, passwordMsg) } // Log a message for --uri or a positional connection string, if either is specified. - uri := tempOpts.URI.ConnectionString + uri := tempOpts.ConnectionString if uri != "" { if cs, err := connstring.Parse(uri); err == nil && cs.Password != "" { log.Logvf(log.Always, uriMsg) @@ -576,7 +576,7 @@ func LogSensitiveOptionWarnings(args []string) { } // Log a message for --sslPEMKeyPassword, if specified. - if tempOpts.SSL.SSLPEMKeyPassword != "" { + if tempOpts.SSLPEMKeyPassword != "" { log.Logvf(log.Always, sslMsg) } } @@ -594,12 +594,12 @@ func (opts *ToolOptions) ParseConfigFile(args []string) error { } // No --config option was specified. - if opts.General.ConfigPath == "" { + if opts.ConfigPath == "" { return nil } // --config option specifies a file path. - configBytes, err := os.ReadFile(opts.General.ConfigPath) + configBytes, err := os.ReadFile(opts.ConfigPath) if err != nil { return errors.Wrapf(err, "error opening file with --config") } @@ -613,16 +613,16 @@ func (opts *ToolOptions) ParseConfigFile(args []string) error { } err = yaml.UnmarshalStrict(configBytes, &config) if err != nil { - return errors.Wrapf(err, "error parsing config file %s", opts.General.ConfigPath) + return errors.Wrapf(err, "error parsing config file %s", opts.ConfigPath) } // Assign each parsed value to its respective ToolOptions field. - opts.Auth.Password = config.Password - opts.URI.ConnectionString = config.ConnectionString - opts.SSL.SSLPEMKeyPassword = config.SSLPEMKeyPassword + opts.Password = config.Password + opts.ConnectionString = config.ConnectionString + opts.SSLPEMKeyPassword = config.SSLPEMKeyPassword // Mongomirror has an extra option to set. - for _, extraOpt := range opts.URI.extraOptionsRegistry { + for _, extraOpt := range opts.extraOptionsRegistry { if destinationAuth, ok := extraOpt.(DestinationAuthOptions); ok { destinationAuth.SetDestinationPassword(config.DestinationPassword) break @@ -676,7 +676,7 @@ func (opts *ToolOptions) setURIFromPositionalArg(args []string) ([]string, error // connection string. If a value is set on the connection string, but not the options, // that value is added to the options. func (opts *ToolOptions) NormalizeOptionsAndURI() error { - if opts.URI == nil || opts.URI.ConnectionString == "" { + if opts.URI == nil || opts.ConnectionString == "" { // If URI not provided, get replica set name and generate connection string _, opts.ReplicaSetName = util.SplitHostArg(opts.Host) uri, err := NewURI(util.BuildURI(opts.Host, opts.Port)) @@ -686,7 +686,7 @@ func (opts *ToolOptions) NormalizeOptionsAndURI() error { opts.URI = uri } - cs, err := connstring.Parse(opts.URI.ConnectionString) + cs, err := connstring.Parse(opts.ConnectionString) if err != nil { return err } @@ -701,7 +701,7 @@ func (opts *ToolOptions) NormalizeOptionsAndURI() error { if err != nil { return fmt.Errorf("error reading password: %v", err) } - opts.Auth.Password = pass + opts.Password = pass opts.ConnString.Password = pass } @@ -714,7 +714,7 @@ func (opts *ToolOptions) NormalizeOptionsAndURI() error { if err != nil { return fmt.Errorf("error reading password: %v", err) } - opts.SSL.SSLPEMKeyPassword = pass + opts.SSLPEMKeyPassword = pass } err = opts.ConnString.Validate() @@ -757,7 +757,7 @@ func (opts *ToolOptions) handleUnknownOption( // we check that it is not equal to its default value. To check that a URI option is set, // some options have an "OptionSet" field. func (opts *ToolOptions) setOptionsFromURI(cs *connstring.ConnString) error { - opts.URI.ConnString = cs + opts.ConnString = cs if opts.enabledOptions.Connection { // Port can be set in --port, --host, or URI @@ -765,7 +765,7 @@ func (opts *ToolOptions) setOptionsFromURI(cs *connstring.ConnString) error { if opts.Port != "" { // if --port is set, check that each host:port pair in the URI the port defined in --port for i, host := range cs.Hosts { - if strings.Index(host, ":") != -1 { + if strings.Contains(host, ":") { hostPort := strings.Split(host, ":")[1] if hostPort != opts.Port { return ConflictingArgsErrorFormat( @@ -789,7 +789,7 @@ func (opts *ToolOptions) setOptionsFromURI(cs *connstring.ConnString) error { if opts.Port != "" { for i := range seedlist { - if strings.Index(seedlist[i], ":") == -1 { // no port + if !strings.Contains(seedlist[i], ":") { // no port seedlist[i] = seedlist[i] + ":" + opts.Port } } @@ -862,76 +862,76 @@ func (opts *ToolOptions) setOptionsFromURI(cs *connstring.ConnString) error { return fmt.Errorf("loadBalanced cannot be set to true if multiple hosts are specified") } - if opts.Connection.ServerSelectionTimeout != 0 && cs.ServerSelectionTimeoutSet { - if (time.Duration(opts.Connection.ServerSelectionTimeout) * time.Millisecond) != cs.ServerSelectionTimeout { + if opts.ServerSelectionTimeout != 0 && cs.ServerSelectionTimeoutSet { + if (time.Duration(opts.ServerSelectionTimeout) * time.Millisecond) != cs.ServerSelectionTimeout { return ConflictingArgsErrorFormat( "serverSelectionTimeout", strconv.Itoa(int(cs.ServerSelectionTimeout/time.Millisecond)), - strconv.Itoa(opts.Connection.ServerSelectionTimeout), + strconv.Itoa(opts.ServerSelectionTimeout), "--serverSelectionTimeout", ) } } - if opts.Connection.ServerSelectionTimeout != 0 && !cs.ServerSelectionTimeoutSet { + if opts.ServerSelectionTimeout != 0 && !cs.ServerSelectionTimeoutSet { cs.ServerSelectionTimeout = time.Duration( - opts.Connection.ServerSelectionTimeout, + opts.ServerSelectionTimeout, ) * time.Millisecond cs.ServerSelectionTimeoutSet = true } - if opts.Connection.ServerSelectionTimeout == 0 && cs.ServerSelectionTimeoutSet { - opts.Connection.ServerSelectionTimeout = int( + if opts.ServerSelectionTimeout == 0 && cs.ServerSelectionTimeoutSet { + opts.ServerSelectionTimeout = int( cs.ServerSelectionTimeout / time.Millisecond, ) } - if opts.Connection.Timeout != 3 && cs.ConnectTimeoutSet { - if (time.Duration(opts.Connection.Timeout) * time.Millisecond) != cs.ConnectTimeout { + if opts.Timeout != 3 && cs.ConnectTimeoutSet { + if (time.Duration(opts.Timeout) * time.Millisecond) != cs.ConnectTimeout { return ConflictingArgsErrorFormat( "connectTimeout", strconv.Itoa(int(cs.ConnectTimeout/time.Millisecond)), - strconv.Itoa(opts.Connection.Timeout), + strconv.Itoa(opts.Timeout), "--dialTimeout", ) } } - if opts.Connection.Timeout != 3 && !cs.ConnectTimeoutSet { - cs.ConnectTimeout = time.Duration(opts.Connection.Timeout) * time.Millisecond + if opts.Timeout != 3 && !cs.ConnectTimeoutSet { + cs.ConnectTimeout = time.Duration(opts.Timeout) * time.Millisecond cs.ConnectTimeoutSet = true } - if opts.Connection.Timeout == 3 && cs.ConnectTimeoutSet { - opts.Connection.Timeout = int(cs.ConnectTimeout / time.Millisecond) + if opts.Timeout == 3 && cs.ConnectTimeoutSet { + opts.Timeout = int(cs.ConnectTimeout / time.Millisecond) } - if opts.Connection.SocketTimeout != 0 && cs.SocketTimeoutSet { - if (time.Duration(opts.Connection.SocketTimeout) * time.Millisecond) != cs.SocketTimeout { + if opts.SocketTimeout != 0 && cs.SocketTimeoutSet { + if (time.Duration(opts.SocketTimeout) * time.Millisecond) != cs.SocketTimeout { return ConflictingArgsErrorFormat( "SocketTimeout", strconv.Itoa(int(cs.SocketTimeout/time.Millisecond)), - strconv.Itoa(opts.Connection.SocketTimeout), + strconv.Itoa(opts.SocketTimeout), "--socketTimeout", ) } } - if opts.Connection.SocketTimeout != 0 && !cs.SocketTimeoutSet { - cs.SocketTimeout = time.Duration(opts.Connection.SocketTimeout) * time.Millisecond + if opts.SocketTimeout != 0 && !cs.SocketTimeoutSet { + cs.SocketTimeout = time.Duration(opts.SocketTimeout) * time.Millisecond cs.SocketTimeoutSet = true } - if opts.Connection.SocketTimeout == 0 && cs.SocketTimeoutSet { - opts.Connection.SocketTimeout = int(cs.SocketTimeout / time.Millisecond) + if opts.SocketTimeout == 0 && cs.SocketTimeoutSet { + opts.SocketTimeout = int(cs.SocketTimeout / time.Millisecond) } if len(cs.Compressors) != 0 { - if opts.Connection.Compressors != "none" && - opts.Connection.Compressors != strings.Join(cs.Compressors, ",") { + if opts.Compressors != "none" && + opts.Compressors != strings.Join(cs.Compressors, ",") { return ConflictingArgsErrorFormat( "compressors", strings.Join(cs.Compressors, ","), - opts.Connection.Compressors, + opts.Compressors, "--compressors", ) } } else { - cs.Compressors = strings.Split(opts.Connection.Compressors, ",") + cs.Compressors = strings.Split(opts.Compressors, ",") } } @@ -1179,32 +1179,32 @@ func (opts *ToolOptions) setOptionsFromURI(cs *connstring.ConnString) error { ) } - gssapiServiceName, _ := cs.AuthMechanismProperties["SERVICE_NAME"] + gssapiServiceName := cs.AuthMechanismProperties["SERVICE_NAME"] - if opts.Kerberos.Service != "" && cs.AuthMechanismPropertiesSet { - if opts.Kerberos.Service != gssapiServiceName { + if opts.Service != "" && cs.AuthMechanismPropertiesSet { + if opts.Service != gssapiServiceName { return ConflictingArgsErrorFormat( "Kerberos service name", gssapiServiceName, - opts.Kerberos.Service, + opts.Service, "--gssapiServiceName", ) } } - if opts.Kerberos.Service != "" && !cs.AuthMechanismPropertiesSet { + if opts.Service != "" && !cs.AuthMechanismPropertiesSet { if cs.AuthMechanismProperties == nil { cs.AuthMechanismProperties = make(map[string]string) } - cs.AuthMechanismProperties["SERVICE_NAME"] = opts.Kerberos.Service + cs.AuthMechanismProperties["SERVICE_NAME"] = opts.Service cs.AuthMechanismPropertiesSet = true } - if opts.Kerberos.Service == "" && cs.AuthMechanismPropertiesSet { - opts.Kerberos.Service = gssapiServiceName + if opts.Service == "" && cs.AuthMechanismPropertiesSet { + opts.Service = gssapiServiceName } } if strings.ToLower(cs.AuthMechanism) == "mongodb-aws" { - awsSessionToken, _ := cs.AuthMechanismProperties["AWS_SESSION_TOKEN"] + awsSessionToken := cs.AuthMechanismProperties["AWS_SESSION_TOKEN"] if opts.AWSSessionToken != "" && cs.AuthMechanismPropertiesSet { if opts.AWSSessionToken != awsSessionToken { @@ -1227,7 +1227,7 @@ func (opts *ToolOptions) setOptionsFromURI(cs *connstring.ConnString) error { opts.AWSSessionToken = awsSessionToken } } - for _, extraOpts := range opts.URI.extraOptionsRegistry { + for _, extraOpts := range opts.extraOptionsRegistry { if uriSetter, ok := extraOpts.(URISetter); ok { err := uriSetter.SetOptionsFromURI(cs) if err != nil { diff --git a/common/options/options_test.go b/common/options/options_test.go index 3f00707c8..b9751e65e 100644 --- a/common/options/options_test.go +++ b/common/options/options_test.go @@ -580,15 +580,15 @@ func TestParseAndSetOptions(t *testing.T) { for _, testCase := range testCases { t.Log("Test Case:", testCase.Name) - testCase.OptsIn.URI.ConnectionString = "mongodb://dummy" - testCase.OptsExpected.URI.ConnectionString = "mongodb://dummy" + testCase.OptsIn.ConnectionString = "mongodb://dummy" + testCase.OptsExpected.ConnectionString = "mongodb://dummy" BuiltWithGSSAPI = testCase.WithGSSAPI defer func() { BuiltWithGSSAPI = true }() - testCase.OptsIn.URI.ConnString = testCase.CS + testCase.OptsIn.ConnString = testCase.CS err := testCase.OptsIn.setOptionsFromURI(testCase.CS) @@ -600,31 +600,31 @@ func TestParseAndSetOptions(t *testing.T) { require.Equal( t, - testCase.OptsExpected.Connection.Timeout, - testCase.OptsIn.Connection.Timeout, + testCase.OptsExpected.Timeout, + testCase.OptsIn.Timeout, ) require.Equal( t, - testCase.OptsExpected.Connection.SocketTimeout, - testCase.OptsIn.Connection.SocketTimeout, + testCase.OptsExpected.SocketTimeout, + testCase.OptsIn.SocketTimeout, ) require.Equal(t, testCase.OptsExpected.Username, testCase.OptsIn.Username) require.Equal(t, testCase.OptsExpected.Password, testCase.OptsIn.Password) require.Equal(t, testCase.OptsExpected.Source, testCase.OptsIn.Source) - require.Equal(t, testCase.OptsExpected.Auth.Mechanism, testCase.OptsIn.Auth.Mechanism) + require.Equal(t, testCase.OptsExpected.Mechanism, testCase.OptsIn.Mechanism) require.Equal( t, - testCase.OptsExpected.Auth.AWSSessionToken, - testCase.OptsIn.Auth.AWSSessionToken, + testCase.OptsExpected.AWSSessionToken, + testCase.OptsIn.AWSSessionToken, ) require.Equal(t, testCase.OptsExpected.Direct, testCase.OptsIn.Direct) require.Equal(t, testCase.OptsExpected.ReplicaSetName, testCase.OptsIn.ReplicaSetName) - require.Equal(t, testCase.OptsExpected.SSL.UseSSL, testCase.OptsIn.SSL.UseSSL) - require.Equal(t, testCase.OptsExpected.Kerberos.Service, testCase.OptsIn.Kerberos.Service) + require.Equal(t, testCase.OptsExpected.UseSSL, testCase.OptsIn.UseSSL) + require.Equal(t, testCase.OptsExpected.Service, testCase.OptsIn.Service) require.Equal( t, - testCase.OptsExpected.Kerberos.ServiceHost, - testCase.OptsIn.Kerberos.ServiceHost, + testCase.OptsExpected.ServiceHost, + testCase.OptsIn.ServiceHost, ) require.Equal(t, testCase.OptsExpected.RetryWrites, testCase.OptsIn.RetryWrites) require.Equal( @@ -657,16 +657,16 @@ func runConfigFileTestCases(t *testing.T, testCases []configTester) { if testCase.outcome == ShouldSucceed { require.NoError(t, err) - require.Equal(t, testCase.expectedOpts.Auth.Password, opts.Auth.Password) + require.Equal(t, testCase.expectedOpts.Password, opts.Password) require.Equal( t, - testCase.expectedOpts.URI.ConnectionString, - opts.URI.ConnectionString, + testCase.expectedOpts.ConnectionString, + opts.ConnectionString, ) require.Equal( t, - testCase.expectedOpts.SSL.SSLPEMKeyPassword, - opts.SSL.SSLPEMKeyPassword, + testCase.expectedOpts.SSLPEMKeyPassword, + opts.SSLPEMKeyPassword, ) } else { require.Error(t, err) @@ -677,9 +677,9 @@ func runConfigFileTestCases(t *testing.T, testCases []configTester) { func createExpectedOpts(pw string, uri string, ssl string) *ToolOptions { opts := New("test", "", "", "", false, EnabledOptions{true, true, true, true}) - opts.Auth.Password = pw - opts.URI.ConnectionString = uri - opts.SSL.SSLPEMKeyPassword = ssl + opts.Password = pw + opts.ConnectionString = uri + opts.SSLPEMKeyPassword = ssl return opts } @@ -777,7 +777,7 @@ func TestParseConfigFile(t *testing.T) { opts := New("test", "", "", "", false, EnabledOptions{Auth: true}) _, err := opts.ParseArgs(args) require.NoError(t, err) - require.Equal(t, "def456", opts.Auth.Password) + require.Equal(t, "def456", opts.Password) }) t.Run("with --password followed by --config", func(t *testing.T) { @@ -785,7 +785,7 @@ func TestParseConfigFile(t *testing.T) { opts := New("test", "", "", "", false, EnabledOptions{Auth: true}) _, err := opts.ParseArgs(args) require.NoError(t, err) - require.Equal(t, "ghi789", opts.Auth.Password) + require.Equal(t, "ghi789", opts.Password) }) }) } @@ -1223,7 +1223,7 @@ func TestPasswordPrompt(t *testing.T) { defer cleanup() opts := newTestOpts(t) - opts.Auth.Username = "someuser" + opts.Username = "someuser" err := opts.NormalizeOptionsAndURI() require.NoError(t, err) @@ -1241,7 +1241,7 @@ func TestPasswordPrompt(t *testing.T) { defer cleanup() opts := newTestOpts(t) - opts.Auth.Username = "someuser" + opts.Username = "someuser" opts.Host = "localhost" opts.Port = "12345" opts.URI = nil @@ -1262,9 +1262,9 @@ func TestPasswordPrompt(t *testing.T) { defer cleanup() opts := newTestOpts(t) - opts.Auth.Username = "someuser" - opts.Auth.Mechanism = "PLAIN" - opts.SSL.UseSSL = true + opts.Username = "someuser" + opts.Mechanism = "PLAIN" + opts.UseSSL = true err := opts.NormalizeOptionsAndURI() require.NoError(t, err) diff --git a/common/txn/buffer.go b/common/txn/buffer.go index c86bf09a7..17ab8b71b 100644 --- a/common/txn/buffer.go +++ b/common/txn/buffer.go @@ -137,9 +137,7 @@ LOOP: break LOOP } // store it - for _, op := range innerOps { - state.buffer = append(state.buffer, op) - } + state.buffer = append(state.buffer, innerOps...) } if t.meta.IsFinal() { break LOOP diff --git a/common/txn/meta_test.go b/common/txn/meta_test.go index ba3e32ebf..ebb4a7ac6 100644 --- a/common/txn/meta_test.go +++ b/common/txn/meta_test.go @@ -35,8 +35,6 @@ func runNonTxnMetaCase(t *testing.T, c *TestData) { if meta.IsTxn() { t.Errorf("case %s: non-txn meta looks like transaction", c.name) } - - return } func runTxnMetaCase(t *testing.T, c *TestData) { diff --git a/common/util/file.go b/common/util/file.go index 60c0913cc..bf712ce23 100644 --- a/common/util/file.go +++ b/common/util/file.go @@ -93,7 +93,7 @@ func (dc *DeferredCloser) CloseWithErrorCapture(deferredErr *error) { return } - err := dc.Closer.Close() + err := dc.Close() dc.closed = true if err != nil && *deferredErr == nil { *deferredErr = err diff --git a/common/util/mongo.go b/common/util/mongo.go index 972f126c8..25e05abe2 100644 --- a/common/util/mongo.go +++ b/common/util/mongo.go @@ -77,7 +77,7 @@ func BuildURI(host, port string) string { // host part is empty string, make it localhost if port != "" { for i := range seedlist { - if strings.Index(seedlist[i], ":") == -1 { + if !strings.Contains(seedlist[i], ":") { seedlist[i] = seedlist[i] + ":" + port } } diff --git a/mongodump/main/mongodump.go b/mongodump/main/mongodump.go index b44482c4b..76dc2dac5 100644 --- a/mongodump/main/mongodump.go +++ b/mongodump/main/mongodump.go @@ -51,7 +51,7 @@ func main() { log.SetVerbosity(opts.Verbosity) // verify uri options and log them - opts.URI.LogUnsupportedOptions() + opts.LogUnsupportedOptions() // kick off the progress bar manager progressManager := progress.NewBarWriter( diff --git a/mongodump/mongodump.go b/mongodump/mongodump.go index ad4c1d899..e6c896742 100644 --- a/mongodump/mongodump.go +++ b/mongodump/mongodump.go @@ -88,36 +88,36 @@ func newNotifier() *notifier { return ¬ifier{notified: make(chan struct{})} } // ValidateOptions checks for any incompatible sets of options. func (dump *MongoDump) ValidateOptions() error { switch { - case dump.OutputOptions.Out == "-" && dump.ToolOptions.Namespace.Collection == "": + case dump.OutputOptions.Out == "-" && dump.ToolOptions.Collection == "": return fmt.Errorf("can only dump a single collection to stdout") - case dump.ToolOptions.Namespace.DB == "" && dump.ToolOptions.Namespace.Collection != "": + case dump.ToolOptions.DB == "" && dump.ToolOptions.Collection != "": return fmt.Errorf("cannot dump a collection without a specified database") - case dump.InputOptions.Query != "" && dump.ToolOptions.Namespace.Collection == "": + case dump.InputOptions.Query != "" && dump.ToolOptions.Collection == "": return fmt.Errorf("cannot dump using a query without a specified collection") - case dump.InputOptions.QueryFile != "" && dump.ToolOptions.Namespace.Collection == "": + case dump.InputOptions.QueryFile != "" && dump.ToolOptions.Collection == "": return fmt.Errorf("cannot dump using a queryFile without a specified collection") case dump.InputOptions.Query != "" && dump.InputOptions.QueryFile != "": return fmt.Errorf("either query or queryFile can be specified as a query option, not both") case dump.InputOptions.Query != "" && dump.InputOptions.TableScan: return fmt.Errorf("cannot use --forceTableScan when specifying --query") - case dump.OutputOptions.DumpDBUsersAndRoles && dump.ToolOptions.Namespace.DB == "": + case dump.OutputOptions.DumpDBUsersAndRoles && dump.ToolOptions.DB == "": return fmt.Errorf("must specify a database when running with dumpDbUsersAndRoles") - case dump.OutputOptions.DumpDBUsersAndRoles && dump.ToolOptions.Namespace.Collection != "": + case dump.OutputOptions.DumpDBUsersAndRoles && dump.ToolOptions.Collection != "": return fmt.Errorf("cannot specify a collection when running with dumpDbUsersAndRoles") - case strings.HasPrefix(dump.ToolOptions.Namespace.Collection, "system.buckets."): + case strings.HasPrefix(dump.ToolOptions.Collection, "system.buckets."): return fmt.Errorf("cannot specify a system.buckets collection in --collection. " + "Specifying the timeseries collection will dump the system.buckets collection") - case dump.OutputOptions.Oplog && dump.ToolOptions.Namespace.DB != "": + case dump.OutputOptions.Oplog && dump.ToolOptions.DB != "": return fmt.Errorf("--oplog mode only supported on full dumps") - case len(dump.OutputOptions.ExcludedCollections) > 0 && dump.ToolOptions.Namespace.Collection != "": + case len(dump.OutputOptions.ExcludedCollections) > 0 && dump.ToolOptions.Collection != "": return fmt.Errorf("--collection is not allowed when --excludeCollection is specified") - case len(dump.OutputOptions.ExcludedCollectionPrefixes) > 0 && dump.ToolOptions.Namespace.Collection != "": + case len(dump.OutputOptions.ExcludedCollectionPrefixes) > 0 && dump.ToolOptions.Collection != "": return fmt.Errorf( "--collection is not allowed when --excludeCollectionsWithPrefix is specified", ) - case len(dump.OutputOptions.ExcludedCollections) > 0 && dump.ToolOptions.Namespace.DB == "": + case len(dump.OutputOptions.ExcludedCollections) > 0 && dump.ToolOptions.DB == "": return fmt.Errorf("--db is required when --excludeCollection is specified") - case len(dump.OutputOptions.ExcludedCollectionPrefixes) > 0 && dump.ToolOptions.Namespace.DB == "": + case len(dump.OutputOptions.ExcludedCollectionPrefixes) > 0 && dump.ToolOptions.DB == "": return fmt.Errorf("--db is required when --excludeCollectionsWithPrefix is specified") case dump.OutputOptions.Out != "" && dump.OutputOptions.Archive != "": return fmt.Errorf("--out not allowed when --archive is specified") @@ -141,7 +141,7 @@ func (dump *MongoDump) Init() error { pref, err := db.NewReadPreference( dump.InputOptions.ReadPreference, - dump.ToolOptions.URI.ParsedConnString(), + dump.ToolOptions.ParsedConnString(), ) if err != nil { return fmt.Errorf("error parsing --readPreference : %v", err) @@ -188,12 +188,12 @@ func (dump *MongoDump) Init() error { func (dump *MongoDump) verifyCollectionExists() (bool, error) { // Running MongoDump against a DB with no collection specified works. In this case, return true so the process // can continue. - if dump.ToolOptions.Namespace.Collection == "" { + if dump.ToolOptions.Collection == "" { return true, nil } coll := dump.SessionProvider.DB(dump.ToolOptions.Namespace.DB). - Collection(dump.ToolOptions.Namespace.Collection) + Collection(dump.ToolOptions.Collection) collInfo, err := db.GetCollectionInfo(coll) if err != nil { return false, err @@ -234,7 +234,7 @@ func (dump *MongoDump) Dump() (err error) { } if !exists { log.Logvf(log.Always, "namespace with DB %s and collection %s does not exist", - dump.ToolOptions.Namespace.DB, dump.ToolOptions.Namespace.Collection) + dump.ToolOptions.DB, dump.ToolOptions.Collection) return nil } @@ -951,8 +951,8 @@ func (dump *MongoDump) DumpPreludeMetadata() error { filename := "prelude.json" - if dump.ToolOptions.Namespace.DB != "" { - filename = filepath.Join(dump.ToolOptions.Namespace.DB, filename) + if dump.ToolOptions.DB != "" { + filename = filepath.Join(dump.ToolOptions.DB, filename) } if dump.OutputOptions.Out == "" { filename = filepath.Join("dump", filename) diff --git a/mongodump/mongodump_test.go b/mongodump/mongodump_test.go index c676459d5..875018120 100644 --- a/mongodump/mongodump_test.go +++ b/mongodump/mongodump_test.go @@ -562,7 +562,7 @@ func testQuery(md *MongoDump, session *mongo.Client) string { // we can only dump using query per collection for _, testCollName := range testCollectionNames { - md.ToolOptions.Namespace.Collection = testCollName + md.ToolOptions.Collection = testCollName err := md.Init() So(err, ShouldBeNil) @@ -622,10 +622,10 @@ func testDumpOneCollection(md *MongoDump, dumpDir string) { So(err, ShouldBeNil) So(countColls, ShouldEqual, 1) - collOriginal := session.Database(testDB).Collection(md.ToolOptions.Namespace.Collection) + collOriginal := session.Database(testDB).Collection(md.ToolOptions.Collection) So(session.Database(testRestoreDB).Drop(context.Background()), ShouldBeNil) - collRestore := session.Database(testRestoreDB).Collection(md.ToolOptions.Namespace.Collection) + collRestore := session.Database(testRestoreDB).Collection(md.ToolOptions.Collection) err = readBSONIntoDatabase(dumpDBDir, testRestoreDB) So(err, ShouldBeNil) @@ -663,8 +663,8 @@ func TestMongoDumpValidateOptions(t *testing.T) { md := simpleMongoDumpInstance() Convey("we cannot dump a collection when a database specified", func() { - md.ToolOptions.Namespace.Collection = "some_collection" - md.ToolOptions.Namespace.DB = "" + md.ToolOptions.Collection = "some_collection" + md.ToolOptions.DB = "" err := md.ValidateOptions() So(err, ShouldNotBeNil) @@ -676,7 +676,7 @@ func TestMongoDumpValidateOptions(t *testing.T) { }) Convey("we have to specify a collection name if using a query", func() { - md.ToolOptions.Namespace.Collection = "" + md.ToolOptions.Collection = "" md.OutputOptions.Out = "" md.InputOptions.Query = "{_id:\"\"}" @@ -744,7 +744,7 @@ func TestMongoDumpBSON(t *testing.T) { md.InputOptions.Query = "" Convey("and that for a particular collection", func() { - md.ToolOptions.Namespace.Collection = testCollectionNames[0] + md.ToolOptions.Collection = testCollectionNames[0] err = md.Init() So(err, ShouldBeNil) @@ -783,7 +783,7 @@ func TestMongoDumpBSON(t *testing.T) { }) Convey("and that it dumps a collection with a slash in its name", func() { - md.ToolOptions.Namespace.Collection = testCollectionNames[2] + md.ToolOptions.Collection = testCollectionNames[2] Convey("to the filesystem", func() { err = md.Init() @@ -799,7 +799,7 @@ func TestMongoDumpBSON(t *testing.T) { }) Convey("for an entire database", func() { - md.ToolOptions.Namespace.Collection = "" + md.ToolOptions.Collection = "" err = md.Init() So(err, ShouldBeNil) @@ -832,7 +832,7 @@ func TestMongoDumpBSON(t *testing.T) { "that does not exist. The dumped directory shouldn't be created", func() { md.OutputOptions.Out = "dump" - md.ToolOptions.Namespace.DB = "nottestdb" + md.ToolOptions.DB = "nottestdb" err = md.Dump() So(err, ShouldBeNil) @@ -867,7 +867,7 @@ func TestMongoDumpBSON(t *testing.T) { Convey("using --query for all the collections in the database", func() { md.InputOptions.Query = string(jsonQueryBytes) - md.ToolOptions.Namespace.DB = testDB + md.ToolOptions.DB = testDB md.OutputOptions.Out = "dump" dumpDir := testQuery(md, session) @@ -882,7 +882,7 @@ func TestMongoDumpBSON(t *testing.T) { err = os.WriteFile("example.json", jsonQueryBytes, 0777) So(err, ShouldBeNil) md.InputOptions.QueryFile = "example.json" - md.ToolOptions.Namespace.DB = testDB + md.ToolOptions.DB = testDB md.OutputOptions.Out = "dump" dumpDir := testQuery(md, session) @@ -898,8 +898,8 @@ func TestMongoDumpBSON(t *testing.T) { Convey("using MongoDump against a collection that doesn't exist succeeds", func() { md := simpleMongoDumpInstance() - md.ToolOptions.Namespace.DB = "nonExistentDB" - md.ToolOptions.Namespace.Collection = "nonExistentColl" + md.ToolOptions.DB = "nonExistentDB" + md.ToolOptions.Collection = "nonExistentColl" err := md.Init() So(err, ShouldBeNil) @@ -945,7 +945,7 @@ func TestMongoDumpBSONLongCollectionName(t *testing.T) { //nolint:errcheck defer coll.Drop(context.Background()) - md.ToolOptions.Namespace.Collection = longCollectionName + md.ToolOptions.Collection = longCollectionName err = md.Init() So(err, ShouldBeNil) @@ -1038,8 +1038,8 @@ func TestDumpPreludeMetadataJson(t *testing.T) { Convey("when dumping all databases", func() { md := simpleMongoDumpInstance() - md.ToolOptions.Namespace.DB = "" - md.ToolOptions.Namespace.Collection = "" + md.ToolOptions.DB = "" + md.ToolOptions.Collection = "" Convey("when dumping to the default directory", func() { dumpDir := util.ToUniversalPath(filepath.Join(path, "dump")) @@ -1096,7 +1096,7 @@ func TestDumpPreludeMetadataJson(t *testing.T) { Convey("the dump does not fail and prelude.json should not be created", func() { md := simpleMongoDumpInstance() - md.ToolOptions.Namespace.DB = "nonExistentDB" + md.ToolOptions.DB = "nonExistentDB" err := md.Init() So(err, ShouldBeNil) @@ -1332,7 +1332,7 @@ func TestMongoDumpTOOLS2174(t *testing.T) { err = sessionProvider.Run(bson.D{{"drop", collName}}, &r1, dbName) if err != nil { var commandErr mongo.CommandError - if !(errors.As(err, &commandErr) && commandErr.Code == 26) { + if !errors.As(err, &commandErr) || commandErr.Code != 26 { t.Fatalf("Failed to run drop: %v", err) } } @@ -1349,8 +1349,8 @@ func TestMongoDumpTOOLS2174(t *testing.T) { Convey("testing dumping a capped, autoIndexId:false collection", t, func() { md := simpleMongoDumpInstance() - md.ToolOptions.Namespace.Collection = collName - md.ToolOptions.Namespace.DB = dbName + md.ToolOptions.Collection = collName + md.ToolOptions.DB = dbName md.OutputOptions.Out = "dump" err = md.Init() So(err, ShouldBeNil) @@ -1385,7 +1385,7 @@ func TestMongoDumpTOOLS1952(t *testing.T) { err = sessionProvider.Run(bson.D{{"drop", collName}}, &r1, dbName) if err != nil { var commandErr mongo.CommandError - if !(errors.As(err, &commandErr) && commandErr.Code == 26) { + if !errors.As(err, &commandErr) || commandErr.Code != 26 { t.Fatalf("Failed to run drop: %v", err) } } @@ -1408,8 +1408,8 @@ func TestMongoDumpTOOLS1952(t *testing.T) { Convey("testing dumping a collection query hints", t, func() { md := simpleMongoDumpInstance() - md.ToolOptions.Namespace.Collection = collName - md.ToolOptions.Namespace.DB = dbName + md.ToolOptions.Collection = collName + md.ToolOptions.DB = dbName md.OutputOptions.Out = "dump" err = md.Init() So(err, ShouldBeNil) @@ -1441,7 +1441,7 @@ func TestMongoDumpTOOLS2498(t *testing.T) { err = sessionProvider.Run(bson.D{{"drop", collName}}, &r1, dbName) if err != nil { var commandErr mongo.CommandError - if !(errors.As(err, &commandErr) && commandErr.Code == 26) { + if !errors.As(err, &commandErr) || commandErr.Code != 26 { t.Fatalf("Failed to run drop: %v", err) } } @@ -1457,8 +1457,8 @@ func TestMongoDumpTOOLS2498(t *testing.T) { Convey("failing to get collection info should error, but not panic", t, func() { md := simpleMongoDumpInstance() - md.ToolOptions.Namespace.Collection = collName - md.ToolOptions.Namespace.DB = dbName + md.ToolOptions.Collection = collName + md.ToolOptions.DB = dbName md.OutputOptions.Out = "dump" err = md.Init() So(err, ShouldBeNil) @@ -1503,8 +1503,8 @@ func TestMongoDumpOrderedQuery(t *testing.T) { md := simpleMongoDumpInstance() md.InputOptions.Query = `{"coords":{"x":0,"y":1}}` - md.ToolOptions.Namespace.Collection = testCollectionNames[0] - md.ToolOptions.Namespace.DB = testDB + md.ToolOptions.Collection = testCollectionNames[0] + md.ToolOptions.DB = testDB md.OutputOptions.Out = "dump" err = md.Init() So(err, ShouldBeNil) @@ -1559,7 +1559,7 @@ func TestMongoDumpViewsAsCollections(t *testing.T) { Convey("testing that the dumped directory contains information about metadata", func() { md := simpleMongoDumpInstance() - md.ToolOptions.Namespace.DB = testDB + md.ToolOptions.DB = testDB md.OutputOptions.Out = "dump" md.OutputOptions.ViewsAsCollections = true @@ -1630,7 +1630,7 @@ func TestMongoDumpViews(t *testing.T) { Convey("testing that the dumped directory contains information about metadata", func() { md := simpleMongoDumpInstance() - md.ToolOptions.Namespace.DB = testDB + md.ToolOptions.DB = testDB md.OutputOptions.Out = "dump" err = md.Init() @@ -1833,7 +1833,7 @@ func TestTimeseriesCollections(t *testing.T) { Convey("With a MongoDump instance", t, func() { md := simpleMongoDumpInstance() - md.ToolOptions.Namespace.DB = dbName + md.ToolOptions.DB = dbName md.OutputOptions.Out = "dump" Convey("a timeseries collection should produce a well-formatted dump", func() { @@ -2195,7 +2195,7 @@ func TestDumpTimeseriesCollectionsWithMixedSchema(t *testing.T) { require.NoError(t, setupTimeseriesWithMixedSchema(dbName, colName)) md := simpleMongoDumpInstance() - md.ToolOptions.Namespace.DB = dbName + md.ToolOptions.DB = dbName md.OutputOptions.Out = "dump" md.OutputOptions.Out = "" md.OutputOptions.Archive = "dump.archive" @@ -2460,7 +2460,7 @@ func TestOptionsOrderIsPreserved(t *testing.T) { func dumpAndCheckPipelineOrder(t *testing.T, collName string, pipeline bson.A) { md := simpleMongoDumpInstance() - md.ToolOptions.Namespace.DB = testDB + md.ToolOptions.DB = testDB md.OutputOptions.Out = "dump" require.NoError(t, md.Init()) diff --git a/mongodump/oplog_dump_test.go b/mongodump/oplog_dump_test.go index 2a6f6e2b0..5f9fc476b 100644 --- a/mongodump/oplog_dump_test.go +++ b/mongodump/oplog_dump_test.go @@ -61,7 +61,7 @@ func TestOplogDumpVectoredInsertsOplog(t *testing.T) { ctx := context.Background() md := simpleMongoDumpInstance() - md.ToolOptions.Namespace.DB = "" + md.ToolOptions.DB = "" md.OutputOptions.Oplog = true md.OutputOptions.Out = "vectored_inserts" diff --git a/mongodump/options_test.go b/mongodump/options_test.go index 4ae48e3e1..3be45d364 100644 --- a/mongodump/options_test.go +++ b/mongodump/options_test.go @@ -119,20 +119,21 @@ func TestPositionalArgumentParsing(t *testing.T) { } else { So(err, ShouldBeNil) So(opts.ConnectionString, ShouldEqual, tc.ExpectedOpts.ConnectionString) - if tc.AuthType == "aws" { - So(opts.Auth.Username, ShouldEqual, tc.ExpectedOpts.Auth.Username) - So(opts.Auth.Password, ShouldEqual, tc.ExpectedOpts.Auth.Password) - So(opts.Auth.Mechanism, ShouldEqual, tc.ExpectedOpts.Auth.Mechanism) - So(opts.Auth.AWSSessionToken, ShouldEqual, tc.ExpectedOpts.Auth.AWSSessionToken) - So(opts.URI.ConnString.AuthMechanismProperties["AWS_SESSION_TOKEN"], ShouldEqual, tc.ExpectedOpts.URI.ConnString.AuthMechanismProperties["AWS_SESSION_TOKEN"]) - } else if tc.AuthType == "kerberos" { - So(opts.Auth.Username, ShouldEqual, tc.ExpectedOpts.Auth.Username) - So(opts.Auth.Mechanism, ShouldEqual, tc.ExpectedOpts.Auth.Mechanism) - So(opts.Auth.Source, ShouldEqual, tc.ExpectedOpts.Auth.Source) - So(opts.URI.ConnString.AuthMechanismProperties["SERVICE_NAME"], ShouldEqual, tc.ExpectedOpts.URI.ConnString.AuthMechanismProperties["SERVICE_NAME"]) - So(opts.URI.ConnString.AuthMechanismProperties["CANONICALIZE_HOST_NAME"], ShouldEqual, tc.ExpectedOpts.URI.ConnString.AuthMechanismProperties["CANONICALIZE_HOST_NAME"]) - So(opts.URI.ConnString.AuthMechanismProperties["SERVICE_REALM"], ShouldEqual, tc.ExpectedOpts.URI.ConnString.AuthMechanismProperties["SERVICE_REALM"]) - So(opts.Kerberos.Service, ShouldEqual, tc.ExpectedOpts.Kerberos.Service) + switch tc.AuthType { + case "aws": + So(opts.Username, ShouldEqual, tc.ExpectedOpts.Username) + So(opts.Password, ShouldEqual, tc.ExpectedOpts.Password) + So(opts.Mechanism, ShouldEqual, tc.ExpectedOpts.Mechanism) + So(opts.AWSSessionToken, ShouldEqual, tc.ExpectedOpts.AWSSessionToken) + So(opts.ConnString.AuthMechanismProperties["AWS_SESSION_TOKEN"], ShouldEqual, tc.ExpectedOpts.ConnString.AuthMechanismProperties["AWS_SESSION_TOKEN"]) + case "kerberos": + So(opts.Username, ShouldEqual, tc.ExpectedOpts.Username) + So(opts.Mechanism, ShouldEqual, tc.ExpectedOpts.Mechanism) + So(opts.Source, ShouldEqual, tc.ExpectedOpts.Source) + So(opts.ConnString.AuthMechanismProperties["SERVICE_NAME"], ShouldEqual, tc.ExpectedOpts.ConnString.AuthMechanismProperties["SERVICE_NAME"]) + So(opts.ConnString.AuthMechanismProperties["CANONICALIZE_HOST_NAME"], ShouldEqual, tc.ExpectedOpts.ConnString.AuthMechanismProperties["CANONICALIZE_HOST_NAME"]) + So(opts.ConnString.AuthMechanismProperties["SERVICE_REALM"], ShouldEqual, tc.ExpectedOpts.ConnString.AuthMechanismProperties["SERVICE_REALM"]) + So(opts.Service, ShouldEqual, tc.ExpectedOpts.Service) } } } diff --git a/mongoexport/csv.go b/mongoexport/csv.go index c44e60952..0691779fe 100644 --- a/mongoexport/csv.go +++ b/mongoexport/csv.go @@ -61,7 +61,7 @@ func (csvExporter *CSVExportOutput) WriteHeader() error { } // WriteFooter is a no-op for CSV export formats. -func (_ *CSVExportOutput) WriteFooter() error { +func (*CSVExportOutput) WriteFooter() error { // no CSV footer return nil } @@ -110,7 +110,7 @@ func (csvExporter *CSVExportOutput) ExportDocument(document bson.D) error { // It will also handle dot-delimited field names for nested arrays or documents. func extractFieldByName(fieldName string, document interface{}) interface{} { dotParts := strings.Split(fieldName, ".") - var subdoc interface{} = document + var subdoc = document for _, path := range dotParts { docValue := reflect.ValueOf(subdoc) @@ -119,13 +119,14 @@ func extractFieldByName(fieldName string, document interface{}) interface{} { } docType := docValue.Type() docKind := docType.Kind() - if docKind == reflect.Map { + switch docKind { + case reflect.Map: subdocVal := docValue.MapIndex(reflect.ValueOf(path)) if subdocVal.Kind() == reflect.Invalid { return "" } subdoc = subdocVal.Interface() - } else if docKind == reflect.Slice { + case reflect.Slice: if docType == marshalDType { // dive into a D as a document //nolint:errcheck @@ -151,7 +152,7 @@ func extractFieldByName(fieldName string, document interface{}) interface{} { } subdoc = subdocVal.Interface() } - } else { + default: // trying to index into a non-compound type - just return blank. return "" } diff --git a/mongoexport/mongoexport.go b/mongoexport/mongoexport.go index 840aa5443..4d2833112 100644 --- a/mongoexport/mongoexport.go +++ b/mongoexport/mongoexport.go @@ -112,7 +112,7 @@ func New(opts Options) (*MongoExport, error) { return nil, util.SetupError{Err: err} } - log.Logvf(log.Always, "connected to: %v", util.SanitizeURI(opts.URI.ConnectionString)) + log.Logvf(log.Always, "connected to: %v", util.SanitizeURI(opts.ConnectionString)) isMongos, err := provider.IsMongos() if err != nil { @@ -152,18 +152,18 @@ func (exp *MongoExport) Close() { func (exp *MongoExport) validateSettings() error { // Namespace must have a valid database if none is specified, // use 'test' - if exp.ToolOptions.Namespace.DB == "" { - exp.ToolOptions.Namespace.DB = "test" + if exp.ToolOptions.DB == "" { + exp.ToolOptions.DB = "test" } - err := util.ValidateDBName(exp.ToolOptions.Namespace.DB) + err := util.ValidateDBName(exp.ToolOptions.DB) if err != nil { return err } - if exp.ToolOptions.Namespace.Collection == "" { + if exp.ToolOptions.Collection == "" { return fmt.Errorf("must specify a collection") } - if err = util.ValidateCollectionGrammar(exp.ToolOptions.Namespace.Collection); err != nil { + if err = util.ValidateCollectionGrammar(exp.ToolOptions.Collection); err != nil { return err } @@ -279,7 +279,7 @@ func (exp *MongoExport) getCount() (int64, error) { return 0, nil } coll := session.Database(exp.ToolOptions.Namespace.DB). - Collection(exp.ToolOptions.Namespace.Collection) + Collection(exp.ToolOptions.Collection) if exp.collInfo.IsView() { return 0, nil @@ -288,8 +288,8 @@ func (exp *MongoExport) getCount() (int64, error) { log.Logvf( log.DebugHigh, "Getting estimated count for %v.%v", - exp.ToolOptions.Namespace.DB, - exp.ToolOptions.Namespace.Collection, + exp.ToolOptions.DB, + exp.ToolOptions.Collection, ) c, err := coll.EstimatedDocumentCount(context.TODO()) if err != nil { @@ -340,10 +340,10 @@ func (exp *MongoExport) getCursor() (*mongo.Cursor, error) { if err != nil { return nil, err } - intendedDB := session.Database(exp.ToolOptions.Namespace.DB) + intendedDB := session.Database(exp.ToolOptions.DB) // noSorting is true if the user did not ask for sorting. - coll := intendedDB.Collection(exp.ToolOptions.Namespace.Collection) + coll := intendedDB.Collection(exp.ToolOptions.Collection) if exp.InputOpts != nil { findOpts.SetSkip(exp.InputOpts.Skip) @@ -368,7 +368,7 @@ func (exp *MongoExport) verifyCollectionExists() (bool, error) { } coll := session.Database(exp.ToolOptions.Namespace.DB). - Collection(exp.ToolOptions.Namespace.Collection) + Collection(exp.ToolOptions.Collection) exp.collInfo, err = db.GetCollectionInfo(coll) if err != nil { return false, err @@ -380,7 +380,7 @@ func (exp *MongoExport) verifyCollectionExists() (bool, error) { if exp.InputOpts.AssertExists { collInfoErr = fmt.Errorf( "collection '%s' does not exist", - exp.ToolOptions.Namespace.Collection, + exp.ToolOptions.Collection, ) } @@ -408,8 +408,8 @@ func (exp *MongoExport) exportInternal(out io.Writer) (int64, error) { if exp.ProgressManager != nil { name := fmt.Sprintf( "%v.%v", - exp.ToolOptions.Namespace.DB, - exp.ToolOptions.Namespace.Collection, + exp.ToolOptions.DB, + exp.ToolOptions.Collection, ) exp.ProgressManager.Attach(name, watchProgressor) defer exp.ProgressManager.Detach(name) diff --git a/mongoexport/mongoexport_test.go b/mongoexport/mongoexport_test.go index f67b72bc4..8d0e6104f 100644 --- a/mongoexport/mongoexport_test.go +++ b/mongoexport/mongoexport_test.go @@ -135,7 +135,7 @@ func TestMongoExportTOOLS2174(t *testing.T) { err = sessionProvider.Run(bson.D{{"drop", collName}}, &r1, dbName) if err != nil { var commandErr mongo.CommandError - if !(errors.As(err, &commandErr) && commandErr.Code == 26) { + if !errors.As(err, &commandErr) || commandErr.Code != 26 { t.Fatalf("Failed to run drop: %v", err) } } @@ -190,7 +190,7 @@ func TestMongoExportTOOLS1952(t *testing.T) { err = sessionProvider.Run(bson.D{{"drop", collName}}, &r1, dbName) if err != nil { var commandErr mongo.CommandError - if !(errors.As(err, &commandErr) && commandErr.Code == 26) { + if !errors.As(err, &commandErr) || commandErr.Code != 26 { t.Fatalf("Failed to run drop: %v", err) } } diff --git a/mongoexport/options.go b/mongoexport/options.go index abf75e5f0..130468838 100644 --- a/mongoexport/options.go +++ b/mongoexport/options.go @@ -125,7 +125,7 @@ func ParseOptions(rawArgs []string, versionStr, gitCommit string) (Options, erro log.SetVerbosity(opts.Verbosity) // verify URI options and log them - opts.URI.LogUnsupportedOptions() + opts.LogUnsupportedOptions() if inputOpts.SlaveOk { if inputOpts.ReadPreference != "" { @@ -143,7 +143,7 @@ func ParseOptions(rawArgs []string, versionStr, gitCommit string) (Options, erro opts.ReadPreference, err = db.NewReadPreference( inputOpts.ReadPreference, - opts.URI.ParsedConnString(), + opts.ParsedConnString(), ) if err != nil { return Options{}, fmt.Errorf("error parsing --readPreference: %v", err) diff --git a/mongoexport/options_test.go b/mongoexport/options_test.go index f45631c70..0ee60e26c 100644 --- a/mongoexport/options_test.go +++ b/mongoexport/options_test.go @@ -247,24 +247,37 @@ func TestPositionalArgumentParsing(t *testing.T) { So(err, ShouldBeNil) So(opts.ConnectionString, ShouldEqual, tc.ExpectedOpts.ConnectionString) } - if tc.AuthType == "aws" { - So(opts.Auth.Username, ShouldEqual, tc.ExpectedOpts.Auth.Username) - So(opts.Auth.Password, ShouldEqual, tc.ExpectedOpts.Auth.Password) - So(opts.Auth.Mechanism, ShouldEqual, tc.ExpectedOpts.Auth.Mechanism) - So(opts.Auth.AWSSessionToken, ShouldEqual, tc.ExpectedOpts.Auth.AWSSessionToken) + switch tc.AuthType { + case "aws": + So(opts.Username, ShouldEqual, tc.ExpectedOpts.Username) + So(opts.Password, ShouldEqual, tc.ExpectedOpts.Password) + So(opts.Mechanism, ShouldEqual, tc.ExpectedOpts.Mechanism) + So(opts.AWSSessionToken, ShouldEqual, tc.ExpectedOpts.AWSSessionToken) So( - opts.URI.ConnString.AuthMechanismProperties["AWS_SESSION_TOKEN"], + opts.ConnString.AuthMechanismProperties["AWS_SESSION_TOKEN"], ShouldEqual, - tc.ExpectedOpts.URI.ConnString.AuthMechanismProperties["AWS_SESSION_TOKEN"], + tc.ExpectedOpts.ConnString.AuthMechanismProperties["AWS_SESSION_TOKEN"], ) - } else if tc.AuthType == "kerberos" { - So(opts.Auth.Username, ShouldEqual, tc.ExpectedOpts.Auth.Username) - So(opts.Auth.Mechanism, ShouldEqual, tc.ExpectedOpts.Auth.Mechanism) - So(opts.Auth.Source, ShouldEqual, tc.ExpectedOpts.Auth.Source) - So(opts.URI.ConnString.AuthMechanismProperties["SERVICE_NAME"], ShouldEqual, tc.ExpectedOpts.URI.ConnString.AuthMechanismProperties["SERVICE_NAME"]) - So(opts.URI.ConnString.AuthMechanismProperties["CANONICALIZE_HOST_NAME"], ShouldEqual, tc.ExpectedOpts.URI.ConnString.AuthMechanismProperties["CANONICALIZE_HOST_NAME"]) - So(opts.URI.ConnString.AuthMechanismProperties["SERVICE_REALM"], ShouldEqual, tc.ExpectedOpts.URI.ConnString.AuthMechanismProperties["SERVICE_REALM"]) - So(opts.Kerberos.Service, ShouldEqual, tc.ExpectedOpts.Kerberos.Service) + case "kerberos": + So(opts.Username, ShouldEqual, tc.ExpectedOpts.Username) + So(opts.Mechanism, ShouldEqual, tc.ExpectedOpts.Mechanism) + So(opts.Source, ShouldEqual, tc.ExpectedOpts.Source) + So( + opts.ConnString.AuthMechanismProperties["SERVICE_NAME"], + ShouldEqual, + tc.ExpectedOpts.ConnString.AuthMechanismProperties["SERVICE_NAME"], + ) + So( + opts.ConnString.AuthMechanismProperties["CANONICALIZE_HOST_NAME"], + ShouldEqual, + tc.ExpectedOpts.ConnString.AuthMechanismProperties["CANONICALIZE_HOST_NAME"], + ) + So( + opts.ConnString.AuthMechanismProperties["SERVICE_REALM"], + ShouldEqual, + tc.ExpectedOpts.ConnString.AuthMechanismProperties["SERVICE_REALM"], + ) + So(opts.Service, ShouldEqual, tc.ExpectedOpts.Service) } } }) diff --git a/mongofiles/mongofiles.go b/mongofiles/mongofiles.go index 6e1966832..5d3cb0db4 100644 --- a/mongofiles/mongofiles.go +++ b/mongofiles/mongofiles.go @@ -506,7 +506,7 @@ func (mf *MongoFiles) Run(displayHost bool) (output string, finalErr error) { log.Logvf( log.Always, "connected to: %v", - util.SanitizeURI(mf.ToolOptions.URI.ConnectionString), + util.SanitizeURI(mf.ToolOptions.ConnectionString), ) } diff --git a/mongofiles/mongofiles_test.go b/mongofiles/mongofiles_test.go index 8aae27533..b3457fa78 100644 --- a/mongofiles/mongofiles_test.go +++ b/mongofiles/mongofiles_test.go @@ -209,7 +209,7 @@ func fileContentsCompare(file1, file2 *os.File, t *testing.T) (bool, error) { return false, err } - isContentSame := bytes.Compare(file1ContentsBytes, file2ContentsBytes) == 0 + isContentSame := bytes.Equal(file1ContentsBytes, file2ContentsBytes) return isContentSame, nil } diff --git a/mongofiles/options.go b/mongofiles/options.go index f4f2897fa..09a2ca215 100644 --- a/mongofiles/options.go +++ b/mongofiles/options.go @@ -60,13 +60,13 @@ func ParseOptions(rawArgs []string, versionStr, gitCommit string) (Options, erro log.SetVerbosity(opts.Verbosity) // verify uri options and log them - opts.URI.LogUnsupportedOptions() + opts.LogUnsupportedOptions() // add the specified database to the namespace options struct - opts.Namespace.DB = storageOpts.DB + opts.DB = storageOpts.DB // set WriteConcern - wc, err := db.NewMongoWriteConcern(storageOpts.WriteConcern, opts.URI.ParsedConnString()) + wc, err := db.NewMongoWriteConcern(storageOpts.WriteConcern, opts.ParsedConnString()) if err != nil { return Options{}, fmt.Errorf("error parsing --writeConcern: %v", err) } @@ -75,7 +75,7 @@ func ParseOptions(rawArgs []string, versionStr, gitCommit string) (Options, erro // set ReadPreference opts.ReadPreference, err = db.NewReadPreference( inputOpts.ReadPreference, - opts.URI.ParsedConnString(), + opts.ParsedConnString(), ) if err != nil { return Options{}, fmt.Errorf("error parsing --readPreference: %v", err) diff --git a/mongofiles/options_test.go b/mongofiles/options_test.go index 4d50c43a2..0c4f90f48 100644 --- a/mongofiles/options_test.go +++ b/mongofiles/options_test.go @@ -493,24 +493,37 @@ func TestPositionalArgumentParsing(t *testing.T) { So(mf.Id, ShouldEqual, tc.ExpectedMF.Id) So(opts.ConnectionString, ShouldEqual, tc.ExpectedOpts.ConnectionString) } - if tc.AuthType == "aws" { - So(opts.Auth.Username, ShouldEqual, tc.ExpectedOpts.Auth.Username) - So(opts.Auth.Password, ShouldEqual, tc.ExpectedOpts.Auth.Password) - So(opts.Auth.Mechanism, ShouldEqual, tc.ExpectedOpts.Auth.Mechanism) - So(opts.Auth.AWSSessionToken, ShouldEqual, tc.ExpectedOpts.Auth.AWSSessionToken) + switch tc.AuthType { + case "aws": + So(opts.Username, ShouldEqual, tc.ExpectedOpts.Username) + So(opts.Password, ShouldEqual, tc.ExpectedOpts.Password) + So(opts.Mechanism, ShouldEqual, tc.ExpectedOpts.Mechanism) + So(opts.AWSSessionToken, ShouldEqual, tc.ExpectedOpts.AWSSessionToken) So( - opts.URI.ConnString.AuthMechanismProperties["AWS_SESSION_TOKEN"], + opts.ConnString.AuthMechanismProperties["AWS_SESSION_TOKEN"], ShouldEqual, - tc.ExpectedOpts.URI.ConnString.AuthMechanismProperties["AWS_SESSION_TOKEN"], + tc.ExpectedOpts.ConnString.AuthMechanismProperties["AWS_SESSION_TOKEN"], ) - } else if tc.AuthType == "kerberos" { - So(opts.Auth.Username, ShouldEqual, tc.ExpectedOpts.Auth.Username) - So(opts.Auth.Mechanism, ShouldEqual, tc.ExpectedOpts.Auth.Mechanism) - So(opts.Auth.Source, ShouldEqual, tc.ExpectedOpts.Auth.Source) - So(opts.URI.ConnString.AuthMechanismProperties["SERVICE_NAME"], ShouldEqual, tc.ExpectedOpts.URI.ConnString.AuthMechanismProperties["SERVICE_NAME"]) - So(opts.URI.ConnString.AuthMechanismProperties["CANONICALIZE_HOST_NAME"], ShouldEqual, tc.ExpectedOpts.URI.ConnString.AuthMechanismProperties["CANONICALIZE_HOST_NAME"]) - So(opts.URI.ConnString.AuthMechanismProperties["SERVICE_REALM"], ShouldEqual, tc.ExpectedOpts.URI.ConnString.AuthMechanismProperties["SERVICE_REALM"]) - So(opts.Kerberos.Service, ShouldEqual, tc.ExpectedOpts.Kerberos.Service) + case "kerberos": + So(opts.Username, ShouldEqual, tc.ExpectedOpts.Username) + So(opts.Mechanism, ShouldEqual, tc.ExpectedOpts.Mechanism) + So(opts.Source, ShouldEqual, tc.ExpectedOpts.Source) + So( + opts.ConnString.AuthMechanismProperties["SERVICE_NAME"], + ShouldEqual, + tc.ExpectedOpts.ConnString.AuthMechanismProperties["SERVICE_NAME"], + ) + So( + opts.ConnString.AuthMechanismProperties["CANONICALIZE_HOST_NAME"], + ShouldEqual, + tc.ExpectedOpts.ConnString.AuthMechanismProperties["CANONICALIZE_HOST_NAME"], + ) + So( + opts.ConnString.AuthMechanismProperties["SERVICE_REALM"], + ShouldEqual, + tc.ExpectedOpts.ConnString.AuthMechanismProperties["SERVICE_REALM"], + ) + So(opts.Service, ShouldEqual, tc.ExpectedOpts.Service) } } }) diff --git a/mongoimport/common.go b/mongoimport/common.go index 245c7f6ed..a96f98fdf 100644 --- a/mongoimport/common.go +++ b/mongoimport/common.go @@ -227,14 +227,12 @@ func getUpsertValue(field string, document bson.D) interface{} { log.Logvf(log.DebugHigh, "no subdoc found for '%v'", left) return nil } - switch subDoc.(type) { + switch subDoc := subDoc.(type) { case bson.D: - //nolint:errcheck - subDocD := subDoc.(bson.D) + subDocD := subDoc return getUpsertValue(field[index+1:], subDocD) case *bson.D: - //nolint:errcheck - subDocD := subDoc.(*bson.D) + subDocD := subDoc return getUpsertValue(field[index+1:], *subDocD) default: log.Logvf(log.DebugHigh, "subdoc found for '%v', but couldn't coerce to bson.D", left) diff --git a/mongoimport/json.go b/mongoimport/json.go index b6d1cc43e..00b0a11ed 100644 --- a/mongoimport/json.go +++ b/mongoimport/json.go @@ -242,10 +242,10 @@ func (r *JSONInputReader) readJSONArraySeparator() error { // this will catch any invalid inter JSON object byte that occurs in the // input source - if !(readByte == json.ArraySep || - strings.TrimSpace(string(readByte)) == "" || - readByte == json.ArrayStart || - readByte == json.ArrayEnd) { + if readByte != json.ArraySep && + strings.TrimSpace(string(readByte)) != "" && + readByte != json.ArrayStart && + readByte != json.ArrayEnd { if r.expectedByte == json.ArrayStart { return ErrNoOpeningBracket } diff --git a/mongoimport/mongoimport.go b/mongoimport/mongoimport.go index 4e9a8c4ae..c3277f152 100644 --- a/mongoimport/mongoimport.go +++ b/mongoimport/mongoimport.go @@ -145,9 +145,9 @@ func (imp *MongoImport) validateSettings() error { if imp.InputOptions.Type == "" { imp.InputOptions.Type = JSON } else { - if !(imp.InputOptions.Type == TSV || - imp.InputOptions.Type == JSON || - imp.InputOptions.Type == CSV) { + if imp.InputOptions.Type != TSV && + imp.InputOptions.Type != JSON && + imp.InputOptions.Type != CSV { return fmt.Errorf("unknown type %v", imp.InputOptions.Type) } } @@ -205,15 +205,16 @@ func (imp *MongoImport) validateSettings() error { } // deprecated - if imp.IngestOptions.Upsert == true { + if imp.IngestOptions.Upsert { imp.IngestOptions.Mode = modeUpsert } // parse UpsertFields, may set default mode to modeUpsert if imp.IngestOptions.UpsertFields != "" { - if imp.IngestOptions.Mode == "" { + switch imp.IngestOptions.Mode { + case "": imp.IngestOptions.Mode = modeUpsert - } else if imp.IngestOptions.Mode == modeInsert { + case modeInsert: return fmt.Errorf("cannot use --upsertFields with --mode=insert") } imp.upsertFields = strings.Split(imp.IngestOptions.UpsertFields, ",") @@ -230,10 +231,10 @@ func (imp *MongoImport) validateSettings() error { } // double-check mode choices - if !(imp.IngestOptions.Mode == modeInsert || - imp.IngestOptions.Mode == modeUpsert || - imp.IngestOptions.Mode == modeDelete || - imp.IngestOptions.Mode == modeMerge) { + if imp.IngestOptions.Mode != modeInsert && + imp.IngestOptions.Mode != modeUpsert && + imp.IngestOptions.Mode != modeDelete && + imp.IngestOptions.Mode != modeMerge { return fmt.Errorf("invalid --mode argument: %v", imp.IngestOptions.Mode) } @@ -312,7 +313,7 @@ type fileSizeProgressor struct { } func (fsp *fileSizeProgressor) Progress() (int64, int64) { - return fsp.sizeTracker.Size(), fsp.max + return fsp.Size(), fsp.max } // ImportDocuments is used to write input data to the database. It returns the @@ -367,12 +368,12 @@ func (imp *MongoImport) importDocuments(inputReader InputReader) (uint64, uint64 log.Logvf( log.Always, "connected to: %v", - util.SanitizeURI(imp.ToolOptions.URI.ConnectionString), + util.SanitizeURI(imp.ToolOptions.ConnectionString), ) log.Logvf(log.Info, "ns: %v.%v", - imp.ToolOptions.Namespace.DB, - imp.ToolOptions.Namespace.Collection) + imp.ToolOptions.DB, + imp.ToolOptions.Collection) // check if the server is a replica set, mongos, or standalone imp.nodeType, err = imp.SessionProvider.GetNodeType() @@ -512,28 +513,33 @@ func (imp *MongoImport) importDocument(inserter *db.BufferedBulkInserter, docume selector := constructUpsertDocument(imp.upsertFields, document) - if imp.IngestOptions.Mode == modeInsert { + switch imp.IngestOptions.Mode { + case modeInsert: result, err = inserter.Insert(document) - } else if imp.IngestOptions.Mode == modeUpsert { + case modeUpsert: if selector == nil { result, err = imp.fallbackToInsert(inserter, document) } else { result, err = inserter.Replace(selector, document) } - } else if imp.IngestOptions.Mode == modeMerge { + case modeMerge: if selector == nil { result, err = imp.fallbackToInsert(inserter, document) } else { updateDoc := bson.D{{"$set", document}} result, err = inserter.Update(selector, updateDoc) } - } else if imp.IngestOptions.Mode == modeDelete { + case modeDelete: if selector == nil { - log.Logvf(log.Info, "Could not construct selector from %v, skipping document", imp.upsertFields) + log.Logvf( + log.Info, + "Could not construct selector from %v, skipping document", + imp.upsertFields, + ) } else { result, err = inserter.Delete(selector, document) } - } else { + default: err = fmt.Errorf("Invalid mode: %v", imp.IngestOptions.Mode) } @@ -608,7 +614,8 @@ func (imp *MongoImport) getInputReader(in io.Reader) (InputReader, error) { out := os.Stdout ignoreBlanks := imp.IngestOptions.IgnoreBlanks && imp.InputOptions.Type != JSON - if imp.InputOptions.Type == CSV { + switch imp.InputOptions.Type { + case CSV: return NewCSVInputReader( colSpecs, in, @@ -617,8 +624,15 @@ func (imp *MongoImport) getInputReader(in io.Reader) (InputReader, error) { ignoreBlanks, imp.InputOptions.UseArrayIndexFields, ), nil - } else if imp.InputOptions.Type == TSV { - return NewTSVInputReader(colSpecs, in, out, imp.IngestOptions.NumDecodingWorkers, ignoreBlanks, imp.InputOptions.UseArrayIndexFields), nil + case TSV: + return NewTSVInputReader( + colSpecs, + in, + out, + imp.IngestOptions.NumDecodingWorkers, + ignoreBlanks, + imp.InputOptions.UseArrayIndexFields, + ), nil } return NewJSONInputReader( imp.InputOptions.JSONArray, diff --git a/mongoimport/mongoimport_test.go b/mongoimport/mongoimport_test.go index 25b2266bb..c673b3aa5 100644 --- a/mongoimport/mongoimport_test.go +++ b/mongoimport/mongoimport_test.go @@ -154,9 +154,9 @@ func getImportWithArgs(additionalArgs ...string) (*MongoImport, error) { // Some OSes take longer than others. The test will time itself // out anyway, so we disable timeouts here. - if opts.ToolOptions.Timeout > 0 { - fmt.Printf("getImportWithArgs zeroing timeout (was %v)\n", opts.ToolOptions.Timeout) - opts.ToolOptions.Timeout = 0 + if opts.Timeout > 0 { + fmt.Printf("getImportWithArgs zeroing timeout (was %v)\n", opts.Timeout) + opts.Timeout = 0 } imp, err := New(opts) @@ -198,8 +198,8 @@ func TestMongoImportValidateSettings(t *testing.T) { Convey("Given a mongoimport instance for validation, ", t, func() { Convey("an error should be thrown if no collection is given", func() { imp := NewMockMongoImport() - imp.ToolOptions.Namespace.DB = "" - imp.ToolOptions.Namespace.Collection = "" + imp.ToolOptions.DB = "" + imp.ToolOptions.Collection = "" So(imp.validateSettings(), ShouldNotBeNil) }) @@ -389,7 +389,7 @@ func TestMongoImportValidateSettings(t *testing.T) { fieldFile := "test.csv" imp.InputOptions.FieldFile = &fieldFile imp.InputOptions.Type = CSV - imp.ToolOptions.Namespace.Collection = "" + imp.ToolOptions.Collection = "" So(imp.validateSettings(), ShouldNotBeNil) }) @@ -399,9 +399,9 @@ func TestMongoImportValidateSettings(t *testing.T) { imp.InputOptions.File = "input" imp.InputOptions.HeaderLine = true imp.InputOptions.Type = CSV - imp.ToolOptions.Namespace.Collection = "" + imp.ToolOptions.Collection = "" So(imp.validateSettings(), ShouldBeNil) - So(imp.ToolOptions.Namespace.Collection, ShouldEqual, + So(imp.ToolOptions.Collection, ShouldEqual, imp.InputOptions.File) }) @@ -411,9 +411,9 @@ func TestMongoImportValidateSettings(t *testing.T) { imp.InputOptions.File = "/path/to/input/file/dot/input.txt" imp.InputOptions.HeaderLine = true imp.InputOptions.Type = CSV - imp.ToolOptions.Namespace.Collection = "" + imp.ToolOptions.Collection = "" So(imp.validateSettings(), ShouldBeNil) - So(imp.ToolOptions.Namespace.Collection, ShouldEqual, "input") + So(imp.ToolOptions.Collection, ShouldEqual, "input") }) Convey( @@ -439,7 +439,7 @@ func TestGetSourceReader(t *testing.T) { imp := NewMockMongoImport() imp.InputOptions.File = "/path/to/input/file/dot/input.txt" imp.InputOptions.Type = CSV - imp.ToolOptions.Namespace.Collection = "" + imp.ToolOptions.Collection = "" _, _, err := imp.getSourceReader() So(err, ShouldNotBeNil) }) @@ -1377,20 +1377,20 @@ func generateTestData() error { // 10k unique _id's for i := 1; i < 10001; i++ { - _, err = w.WriteString(fmt.Sprintf("{\"_id\": %v }\n", i)) + _, err = fmt.Fprintf(w, "{\"_id\": %v }\n", i) if err != nil { return err } } // 1 duplicate _id - _, err = w.WriteString(fmt.Sprintf("{\"_id\": %v }\n", 5)) + _, err = fmt.Fprintf(w, "{\"_id\": %v }\n", 5) if err != nil { return err } // 10k unique _id's for i := 10001; i < 20001; i++ { - _, err = w.WriteString(fmt.Sprintf("{\"_id\": %v }\n", i)) + _, err = fmt.Fprintf(w, "{\"_id\": %v }\n", i) if err != nil { return err } diff --git a/mongoimport/options.go b/mongoimport/options.go index 40e3e219f..27a8c0ec9 100644 --- a/mongoimport/options.go +++ b/mongoimport/options.go @@ -55,7 +55,7 @@ type InputOptions struct { } // Name returns a description of the InputOptions struct. -func (_ *InputOptions) Name() string { +func (*InputOptions) Name() string { return "input" } @@ -107,7 +107,7 @@ type IngestOptions struct { } // Name returns a description of the IngestOptions struct. -func (_ *IngestOptions) Name() string { +func (*IngestOptions) Name() string { return "ingest" } @@ -141,9 +141,9 @@ func ParseOptions(rawArgs []string, versionStr, gitCommit string) (Options, erro } log.SetVerbosity(opts.Verbosity) - opts.URI.LogUnsupportedOptions() + opts.LogUnsupportedOptions() - wc, err := db.NewMongoWriteConcern(ingestOpts.WriteConcern, opts.URI.ParsedConnString()) + wc, err := db.NewMongoWriteConcern(ingestOpts.WriteConcern, opts.ParsedConnString()) if err != nil { return Options{}, fmt.Errorf("error constructing write concern: %v", err) } diff --git a/mongoimport/options_test.go b/mongoimport/options_test.go index 11d834f67..b0b60e520 100644 --- a/mongoimport/options_test.go +++ b/mongoimport/options_test.go @@ -285,24 +285,37 @@ func TestPositionalArgumentParsing(t *testing.T) { So(opts.File, ShouldEqual, tc.ExpectedOpts.File) So(opts.ConnectionString, ShouldEqual, tc.ExpectedOpts.ConnectionString) } - if tc.AuthType == "aws" { - So(opts.Auth.Username, ShouldEqual, tc.ExpectedOpts.Auth.Username) - So(opts.Auth.Password, ShouldEqual, tc.ExpectedOpts.Auth.Password) - So(opts.Auth.Mechanism, ShouldEqual, tc.ExpectedOpts.Auth.Mechanism) - So(opts.Auth.AWSSessionToken, ShouldEqual, tc.ExpectedOpts.Auth.AWSSessionToken) + switch tc.AuthType { + case "aws": + So(opts.Username, ShouldEqual, tc.ExpectedOpts.Username) + So(opts.Password, ShouldEqual, tc.ExpectedOpts.Password) + So(opts.Mechanism, ShouldEqual, tc.ExpectedOpts.Mechanism) + So(opts.AWSSessionToken, ShouldEqual, tc.ExpectedOpts.AWSSessionToken) So( - opts.URI.ConnString.AuthMechanismProperties["AWS_SESSION_TOKEN"], + opts.ConnString.AuthMechanismProperties["AWS_SESSION_TOKEN"], ShouldEqual, - tc.ExpectedOpts.URI.ConnString.AuthMechanismProperties["AWS_SESSION_TOKEN"], + tc.ExpectedOpts.ConnString.AuthMechanismProperties["AWS_SESSION_TOKEN"], ) - } else if tc.AuthType == "kerberos" { - So(opts.Auth.Username, ShouldEqual, tc.ExpectedOpts.Auth.Username) - So(opts.Auth.Mechanism, ShouldEqual, tc.ExpectedOpts.Auth.Mechanism) - So(opts.Auth.Source, ShouldEqual, tc.ExpectedOpts.Auth.Source) - So(opts.URI.ConnString.AuthMechanismProperties["SERVICE_NAME"], ShouldEqual, tc.ExpectedOpts.URI.ConnString.AuthMechanismProperties["SERVICE_NAME"]) - So(opts.URI.ConnString.AuthMechanismProperties["CANONICALIZE_HOST_NAME"], ShouldEqual, tc.ExpectedOpts.URI.ConnString.AuthMechanismProperties["CANONICALIZE_HOST_NAME"]) - So(opts.URI.ConnString.AuthMechanismProperties["SERVICE_REALM"], ShouldEqual, tc.ExpectedOpts.URI.ConnString.AuthMechanismProperties["SERVICE_REALM"]) - So(opts.Kerberos.Service, ShouldEqual, tc.ExpectedOpts.Kerberos.Service) + case "kerberos": + So(opts.Username, ShouldEqual, tc.ExpectedOpts.Username) + So(opts.Mechanism, ShouldEqual, tc.ExpectedOpts.Mechanism) + So(opts.Source, ShouldEqual, tc.ExpectedOpts.Source) + So( + opts.ConnString.AuthMechanismProperties["SERVICE_NAME"], + ShouldEqual, + tc.ExpectedOpts.ConnString.AuthMechanismProperties["SERVICE_NAME"], + ) + So( + opts.ConnString.AuthMechanismProperties["CANONICALIZE_HOST_NAME"], + ShouldEqual, + tc.ExpectedOpts.ConnString.AuthMechanismProperties["CANONICALIZE_HOST_NAME"], + ) + So( + opts.ConnString.AuthMechanismProperties["SERVICE_REALM"], + ShouldEqual, + tc.ExpectedOpts.ConnString.AuthMechanismProperties["SERVICE_REALM"], + ) + So(opts.Service, ShouldEqual, tc.ExpectedOpts.Service) } } }) diff --git a/mongorestore/empty_timestamp.go b/mongorestore/empty_timestamp.go index 207b15094..dc3fbd597 100644 --- a/mongorestore/empty_timestamp.go +++ b/mongorestore/empty_timestamp.go @@ -8,7 +8,7 @@ import ( "go.mongodb.org/mongo-driver/bson" ) -var nineNuls = make([]byte, 9, 9) +var nineNuls = make([]byte, 9) // FindZeroTimestamps returns all document paths (each represented as // a []string) that contain a zero-value timestamp. diff --git a/mongorestore/empty_timestamp_test.go b/mongorestore/empty_timestamp_test.go index 896d680d8..23d3659bf 100644 --- a/mongorestore/empty_timestamp_test.go +++ b/mongorestore/empty_timestamp_test.go @@ -80,7 +80,7 @@ func TestFindEmptyTimestampFields_ShouldNotFind(t *testing.T) { {{"faux", primitive.Binary{ Data: append( []byte{0x11, 0x42, 0x42, 0x00}, - make([]byte, 8, 8)..., + make([]byte, 8)..., ), }}}, } diff --git a/mongorestore/filepath.go b/mongorestore/filepath.go index 81e80fc31..56944a48f 100644 --- a/mongorestore/filepath.go +++ b/mongorestore/filepath.go @@ -443,7 +443,7 @@ func (restore *MongoRestore) CreateIntentsForDB(db string, dir archive.DirLike) // holds the users for a database that was dumped with --dumpDbUsersAndRoles enabled). // If these special files manage to be included in a dump directory during a full // (multi-db) restore, we should ignore them. - if restore.ToolOptions.Namespace != nil && restore.ToolOptions.Namespace.DB == "" && strings.HasPrefix(collection, "$") { + if restore.ToolOptions.Namespace != nil && restore.ToolOptions.DB == "" && strings.HasPrefix(collection, "$") { log.Logvf(log.DebugLow, "not restoring special collection %v.%v", db, collection) skip = true } @@ -708,7 +708,7 @@ func hasMetadataFiles(files []archive.DirLike) bool { func (restore *MongoRestore) handleBSONInsteadOfDirectory(path string) error { // we know we have been given a non-directory, so we should handle it // like a bson file and infer as much as we can - if restore.ToolOptions.Namespace.Collection == "" { + if restore.ToolOptions.Collection == "" { // if the user did not set -c, get the collection name from the bson file newCollectionName, fileType, err := restore.getInfoFromFile(path) if err != nil { @@ -718,14 +718,14 @@ func (restore *MongoRestore) handleBSONInsteadOfDirectory(path string) error { if fileType != BSONFileType { return fmt.Errorf("file %v does not have .bson extension", path) } - restore.ToolOptions.Namespace.Collection = newCollectionName + restore.ToolOptions.Collection = newCollectionName log.Logvf( log.DebugLow, "inferred collection '%v' from file", - restore.ToolOptions.Namespace.Collection, + restore.ToolOptions.Collection, ) } - if restore.ToolOptions.Namespace.DB == "" { + if restore.ToolOptions.DB == "" { // if the user did not set -d, use the directory containing the target // file as the db name (as it would be in a dump directory). If // we cannot determine the directory name, use "test" @@ -733,11 +733,11 @@ func (restore *MongoRestore) handleBSONInsteadOfDirectory(path string) error { if dirForFile == "." || dirForFile == ".." { dirForFile = "test" } - restore.ToolOptions.Namespace.DB = dirForFile + restore.ToolOptions.DB = dirForFile log.Logvf( log.DebugLow, "inferred db '%v' from the file's directory", - restore.ToolOptions.Namespace.DB, + restore.ToolOptions.DB, ) } return nil diff --git a/mongorestore/filepath_test.go b/mongorestore/filepath_test.go index 82aac35ef..c471f6dda 100644 --- a/mongorestore/filepath_test.go +++ b/mongorestore/filepath_test.go @@ -14,7 +14,6 @@ import ( "github.com/mongodb/mongo-tools/common/intents" "github.com/mongodb/mongo-tools/common/log" "github.com/mongodb/mongo-tools/common/options" - commonOpts "github.com/mongodb/mongo-tools/common/options" "github.com/mongodb/mongo-tools/common/testtype" "github.com/mongodb/mongo-tools/common/util" "github.com/mongodb/mongo-tools/mongorestore/ns" @@ -35,7 +34,7 @@ func newMongoRestore() *MongoRestore { return &MongoRestore{ manager: intents.NewIntentManager(), InputOptions: &InputOptions{}, - ToolOptions: &commonOpts.ToolOptions{}, + ToolOptions: &options.ToolOptions{}, NSOptions: &NSOptions{}, renamer: renamer, includer: includer, @@ -321,8 +320,8 @@ func TestHandlingBSON(t *testing.T) { So(err, ShouldBeNil) Convey("the proper DB and Coll should be inferred", func() { - So(mr.ToolOptions.Namespace.DB, ShouldEqual, "db1") - So(mr.ToolOptions.Namespace.Collection, ShouldEqual, "c2") + So(mr.ToolOptions.DB, ShouldEqual, "db1") + So(mr.ToolOptions.Collection, ShouldEqual, "c2") }) }) @@ -333,27 +332,27 @@ func TestHandlingBSON(t *testing.T) { So(err, ShouldBeNil) Convey("the proper DB and Coll should be inferred", func() { - So(mr.ToolOptions.Namespace.DB, ShouldEqual, "db1") - So(mr.ToolOptions.Namespace.Collection, ShouldEqual, longCollectionName) + So(mr.ToolOptions.DB, ShouldEqual, "db1") + So(mr.ToolOptions.Collection, ShouldEqual, longCollectionName) }) }) Convey("but pre-existing settings should not be overwritten", func() { - mr.ToolOptions.Namespace.DB = "a" + mr.ToolOptions.DB = "a" Convey("either collection settings", func() { - mr.ToolOptions.Namespace.Collection = "b" + mr.ToolOptions.Collection = "b" err := mr.handleBSONInsteadOfDirectory("testdata/testdirs/db1/c1.bson") So(err, ShouldBeNil) - So(mr.ToolOptions.Namespace.DB, ShouldEqual, "a") - So(mr.ToolOptions.Namespace.Collection, ShouldEqual, "b") + So(mr.ToolOptions.DB, ShouldEqual, "a") + So(mr.ToolOptions.Collection, ShouldEqual, "b") }) Convey("or db settings", func() { err := mr.handleBSONInsteadOfDirectory("testdata/testdirs/db1/c1.bson") So(err, ShouldBeNil) - So(mr.ToolOptions.Namespace.DB, ShouldEqual, "a") - So(mr.ToolOptions.Namespace.Collection, ShouldEqual, "c1") + So(mr.ToolOptions.DB, ShouldEqual, "a") + So(mr.ToolOptions.Collection, ShouldEqual, "c1") }) }) }) @@ -369,7 +368,7 @@ func TestCreateIntentsForCollection(t *testing.T) { buff = bytes.Buffer{} mr = &MongoRestore{ manager: intents.NewIntentManager(), - ToolOptions: &commonOpts.ToolOptions{}, + ToolOptions: &options.ToolOptions{}, InputOptions: &InputOptions{}, } log.SetWriter(&buff) @@ -469,7 +468,7 @@ func TestCreateIntentForCollectionTimeSeries(t *testing.T) { buff = bytes.Buffer{} mr = &MongoRestore{ manager: intents.NewIntentManager(), - ToolOptions: &commonOpts.ToolOptions{}, + ToolOptions: &options.ToolOptions{}, InputOptions: &InputOptions{}, } log.SetWriter(&buff) @@ -483,17 +482,17 @@ func TestCreateIntentForCollectionTimeSeries(t *testing.T) { ), ) So(err, ShouldBeNil) - mr.ToolOptions.Namespace = &commonOpts.Namespace{} + mr.ToolOptions.Namespace = &options.Namespace{} err = mr.handleBSONInsteadOfDirectory(ddl.Path()) So(err, ShouldBeNil) - So(mr.ToolOptions.Namespace.DB, ShouldEqual, "timeseries_test") - So(mr.ToolOptions.Namespace.Collection, ShouldEqual, "system.buckets.foo_ts") + So(mr.ToolOptions.DB, ShouldEqual, "timeseries_test") + So(mr.ToolOptions.Collection, ShouldEqual, "system.buckets.foo_ts") Convey("should create one intent with inferred fields from BSON name", func() { err = mr.CreateIntentForCollection( - mr.ToolOptions.Namespace.DB, - mr.ToolOptions.Namespace.Collection, + mr.ToolOptions.DB, + mr.ToolOptions.Collection, ddl, ) mr.manager.Finalize(intents.Legacy) @@ -501,7 +500,7 @@ func TestCreateIntentForCollectionTimeSeries(t *testing.T) { i0 := mr.manager.Pop() So(i0, ShouldNotBeNil) - So(i0.DB, ShouldEqual, mr.ToolOptions.Namespace.DB) + So(i0.DB, ShouldEqual, mr.ToolOptions.DB) So(i0.C, ShouldEqual, "foo_ts") So(i0.Location, ShouldEqual, util.ToUniversalPath(ddl.Path())) i1 := mr.manager.Pop() @@ -565,7 +564,7 @@ func TestCreateIntentsForLongCollectionName(t *testing.T) { buff = bytes.Buffer{} mr = &MongoRestore{ manager: intents.NewIntentManager(), - ToolOptions: &commonOpts.ToolOptions{}, + ToolOptions: &options.ToolOptions{}, InputOptions: &InputOptions{}, } log.SetWriter(&buff) diff --git a/mongorestore/metadata.go b/mongorestore/metadata.go index 02246db54..d619caf09 100644 --- a/mongorestore/metadata.go +++ b/mongorestore/metadata.go @@ -278,7 +278,7 @@ func (restore *MongoRestore) UpdateAutoIndexId(options bson.D) { if restore.serverVersion.GTE(db.Version{4, 0, 0}) { for i, elem := range options { if elem.Key == "autoIndexId" && elem.Value == false && - restore.ToolOptions.Namespace.DB != "local" { + restore.ToolOptions.DB != "local" { options[i].Value = true log.Logvf( log.Always, @@ -590,7 +590,7 @@ func (restore *MongoRestore) GetDumpAuthVersion() (int, error) { log.Logvf( log.Always, "no system.version bson file found in '%v' database dump", - restore.ToolOptions.Namespace.DB, + restore.ToolOptions.DB, ) log.Logv( log.Always, @@ -713,8 +713,8 @@ func (restore *MongoRestore) ShouldRestoreUsersAndRoles() bool { // then we check if users or roles BSON files actually exist in the dump // dir. If they do, return true. if (restore.InputOptions.RestoreDBUsersAndRoles || - restore.ToolOptions.Namespace.DB == "" || - restore.ToolOptions.Namespace.DB == "admin") && + restore.ToolOptions.DB == "" || + restore.ToolOptions.DB == "admin") && !restore.isAtlasProxy { if restore.manager.Users() != nil || restore.manager.Roles() != nil { return true diff --git a/mongorestore/mongorestore.go b/mongorestore/mongorestore.go index 7499dc6be..72952f9f4 100644 --- a/mongorestore/mongorestore.go +++ b/mongorestore/mongorestore.go @@ -43,7 +43,7 @@ const ( ) var ( - NoUsersOrRolesInDumpError = errors.New( + ErrNoUsersOrRolesInDump = errors.New( "No users or roles found in restore target. Please omit --restoreDbUsersAndRoles, or use a dump created with --dumpDbUsersAndRoles.", ) ) @@ -172,30 +172,30 @@ func (restore *MongoRestore) ParseAndValidateOptions() error { log.Logv(log.DebugHigh, "\tdumping with object check disabled") } - if restore.ToolOptions.Namespace.DB == "" && restore.ToolOptions.Namespace.Collection != "" { + if restore.ToolOptions.DB == "" && restore.ToolOptions.Collection != "" { return fmt.Errorf("cannot restore a collection without a specified database") } - if restore.ToolOptions.Namespace.DB != "" { - if err := util.ValidateDBName(restore.ToolOptions.Namespace.DB); err != nil { + if restore.ToolOptions.DB != "" { + if err := util.ValidateDBName(restore.ToolOptions.DB); err != nil { return fmt.Errorf("invalid db name: %v", err) } } - if restore.ToolOptions.Namespace.Collection != "" { - if err := util.ValidateCollectionGrammar(restore.ToolOptions.Namespace.Collection); err != nil { + if restore.ToolOptions.Collection != "" { + if err := util.ValidateCollectionGrammar(restore.ToolOptions.Collection); err != nil { return fmt.Errorf("invalid collection name: %v", err) } } - if restore.InputOptions.RestoreDBUsersAndRoles && restore.ToolOptions.Namespace.DB == "" { + if restore.InputOptions.RestoreDBUsersAndRoles && restore.ToolOptions.DB == "" { return fmt.Errorf("cannot use --restoreDbUsersAndRoles without a specified database") } - if restore.InputOptions.RestoreDBUsersAndRoles && restore.ToolOptions.Namespace.DB == "admin" { + if restore.InputOptions.RestoreDBUsersAndRoles && restore.ToolOptions.DB == "admin" { return fmt.Errorf("cannot use --restoreDbUsersAndRoles with the admin database") } if restore.isAtlasProxy { if restore.InputOptions.RestoreDBUsersAndRoles || - restore.ToolOptions.Namespace.DB == "admin" { + restore.ToolOptions.DB == "admin" { return fmt.Errorf( "cannot restore to the admin database when connected to a MongoDB Atlas free or shared cluster", ) @@ -231,7 +231,7 @@ func (restore *MongoRestore) ParseAndValidateOptions() error { log.Logvf(log.DebugLow, "connected to node type: %v", nodeType) // deprecations with --nsInclude --nsExclude - if restore.ToolOptions.Namespace.DB != "" || restore.ToolOptions.Namespace.Collection != "" { + if restore.ToolOptions.DB != "" || restore.ToolOptions.Collection != "" { if filepath.Ext(restore.TargetDirectory) != ".bson" { log.Logvf(log.Always, deprecatedDBAndCollectionsOptionsWarning) } @@ -242,7 +242,7 @@ func (restore *MongoRestore) ParseAndValidateOptions() error { "are deprecated and will not exist in the future; use --nsExclude instead") } if restore.InputOptions.OplogReplay { - if len(restore.NSOptions.NSInclude) > 0 || restore.ToolOptions.Namespace.DB != "" { + if len(restore.NSOptions.NSInclude) > 0 || restore.ToolOptions.DB != "" { return fmt.Errorf("cannot use --oplogReplay with includes specified") } if len(restore.NSOptions.NSExclude) > 0 || len(restore.NSOptions.ExcludedCollections) > 0 || @@ -255,11 +255,11 @@ func (restore *MongoRestore) ParseAndValidateOptions() error { } includes := restore.NSOptions.NSInclude - if restore.ToolOptions.Namespace.DB != "" && restore.ToolOptions.Namespace.Collection != "" { - includes = append(includes, ns.Escape(restore.ToolOptions.Namespace.DB)+"."+ - restore.ToolOptions.Namespace.Collection) - } else if restore.ToolOptions.Namespace.DB != "" { - includes = append(includes, ns.Escape(restore.ToolOptions.Namespace.DB)+".*") + if restore.ToolOptions.DB != "" && restore.ToolOptions.Collection != "" { + includes = append(includes, ns.Escape(restore.ToolOptions.DB)+"."+ + restore.ToolOptions.Collection) + } else if restore.ToolOptions.DB != "" { + includes = append(includes, ns.Escape(restore.ToolOptions.DB)+".*") } if len(includes) == 0 { includes = []string{"*"} @@ -270,11 +270,11 @@ func (restore *MongoRestore) ParseAndValidateOptions() error { } if len(restore.NSOptions.ExcludedCollections) > 0 && - restore.ToolOptions.Namespace.Collection != "" { + restore.ToolOptions.Collection != "" { return fmt.Errorf("--collection is not allowed when --excludeCollection is specified") } if len(restore.NSOptions.ExcludedCollectionPrefixes) > 0 && - restore.ToolOptions.Namespace.Collection != "" { + restore.ToolOptions.Collection != "" { return fmt.Errorf( "--collection is not allowed when --excludeCollectionsWithPrefix is specified", ) @@ -321,7 +321,7 @@ func (restore *MongoRestore) ParseAndValidateOptions() error { return fmt.Errorf( "cannot restore from \"-\" when --archive is specified") } - if restore.ToolOptions.Namespace.Collection == "" { + if restore.ToolOptions.Collection == "" { return fmt.Errorf("cannot restore from stdin without a specified collection") } } @@ -416,7 +416,7 @@ func (restore *MongoRestore) Restore() Result { log.Logv(log.DebugLow, "mongorestore target is a directory, not a file") } } - if restore.ToolOptions.Namespace.Collection != "" && + if restore.ToolOptions.Collection != "" && restore.OutputOptions.NumParallelCollections > 1 && restore.OutputOptions.NumInsertionWorkers == 1 && !restore.OutputOptions.MaintainInsertionOrder { @@ -456,25 +456,25 @@ func (restore *MongoRestore) Restore() Result { case restore.InputOptions.Archive != "": log.Logvf(log.Always, "preparing collections to restore from") err = restore.CreateAllIntents(target) - case restore.ToolOptions.Namespace.DB != "" && restore.ToolOptions.Namespace.Collection == "": + case restore.ToolOptions.DB != "" && restore.ToolOptions.Collection == "": log.Logvf(log.Always, "building a list of collections to restore from %v dir", target.Path()) err = restore.CreateIntentsForDB( - restore.ToolOptions.Namespace.DB, + restore.ToolOptions.DB, target, ) - case restore.ToolOptions.Namespace.DB != "" && restore.ToolOptions.Namespace.Collection != "" && restore.TargetDirectory == "-": + case restore.ToolOptions.DB != "" && restore.ToolOptions.Collection != "" && restore.TargetDirectory == "-": log.Logvf(log.Always, "setting up a collection to be read from standard input") err = restore.CreateStdinIntentForCollection( - restore.ToolOptions.Namespace.DB, - restore.ToolOptions.Namespace.Collection, + restore.ToolOptions.DB, + restore.ToolOptions.Collection, ) - case restore.ToolOptions.Namespace.DB != "" && restore.ToolOptions.Namespace.Collection != "": + case restore.ToolOptions.DB != "" && restore.ToolOptions.Collection != "": log.Logvf(log.Always, "checking for collection data in %v", target.Path()) err = restore.CreateIntentForCollection( - restore.ToolOptions.Namespace.DB, - restore.ToolOptions.Namespace.Collection, + restore.ToolOptions.DB, + restore.ToolOptions.Collection, target, ) default: @@ -486,7 +486,7 @@ func (restore *MongoRestore) Restore() Result { } if restore.isMongos && restore.manager.HasConfigDBIntent() && - restore.ToolOptions.Namespace.DB == "" { + restore.ToolOptions.DB == "" { return Result{Err: fmt.Errorf("cannot do a full restore on a sharded system - " + "remove the 'config' directory from the dump directory first")} } @@ -494,10 +494,10 @@ func (restore *MongoRestore) Restore() Result { // if --restoreDbUsersAndRoles is used then db specific users and roles ($admin.system.users.bson / $admin.system.roles.bson) // should exist in target directory / archive if restore.InputOptions.RestoreDBUsersAndRoles && - restore.ToolOptions.Namespace.DB != "" && + restore.ToolOptions.DB != "" && (restore.manager.Users() == nil && restore.manager.Roles() == nil) { return Result{ - Err: NoUsersOrRolesInDumpError, + Err: ErrNoUsersOrRolesInDump, } } diff --git a/mongorestore/mongorestore_test.go b/mongorestore/mongorestore_test.go index 7488e28dc..e9242f86c 100644 --- a/mongorestore/mongorestore_test.go +++ b/mongorestore/mongorestore_test.go @@ -216,8 +216,8 @@ func TestMongorestore(t *testing.T) { bsonFile, err := os.Open("testdata/testdirs/db1/c1.bson") So(err, ShouldBeNil) - restore.ToolOptions.Namespace.Collection = "c1" - restore.ToolOptions.Namespace.DB = "db1" + restore.ToolOptions.Collection = "c1" + restore.ToolOptions.DB = "db1" restore.InputReader = bsonFile restore.TargetDirectory = "-" @@ -450,8 +450,8 @@ func TestMongorestoreLongCollectionName(t *testing.T) { longBsonFile, err := os.Open("testdata/longcollectionname/db1/" + longBsonName) So(err, ShouldBeNil) - restore.ToolOptions.Namespace.Collection = longCollectionName - restore.ToolOptions.Namespace.DB = "db1" + restore.ToolOptions.Collection = longCollectionName + restore.ToolOptions.DB = "db1" restore.InputReader = longBsonFile restore.TargetDirectory = "-" result := restore.Restore() @@ -1095,7 +1095,7 @@ func TestRestoreUsersOrRoles(t *testing.T) { defer restore.Close() result := restore.Restore() - So(errors.Is(result.Err, NoUsersOrRolesInDumpError), ShouldBeTrue) + So(errors.Is(result.Err, ErrNoUsersOrRolesInDump), ShouldBeTrue) }) Convey("Restoring from base dump directory should not be allowed", func() { @@ -1112,7 +1112,7 @@ func TestRestoreUsersOrRoles(t *testing.T) { defer restore.Close() result := restore.Restore() - So(errors.Is(result.Err, NoUsersOrRolesInDumpError), ShouldBeTrue) + So(errors.Is(result.Err, ErrNoUsersOrRolesInDump), ShouldBeTrue) }) Convey("Restoring from archive of entire dump should not be allowed", func() { @@ -1130,7 +1130,7 @@ func TestRestoreUsersOrRoles(t *testing.T) { defer restore.Close() result := restore.Restore() - So(errors.Is(result.Err, NoUsersOrRolesInDumpError), ShouldBeTrue) + So(errors.Is(result.Err, ErrNoUsersOrRolesInDump), ShouldBeTrue) }) }) @@ -1239,7 +1239,7 @@ func TestReadPreludeMetadata(t *testing.T) { "sets serverDumpVersion from prelude.json from the db's directory", func() { restore.TargetDirectory = "testdata/prelude_test/prelude_db_target/test" - restore.ToolOptions.Namespace.DB = "test" + restore.ToolOptions.DB = "test" result := restore.Restore() So(result.Err, ShouldBeNil) diff --git a/mongorestore/oplog.go b/mongorestore/oplog.go index 3a5f5c9c3..511768302 100644 --- a/mongorestore/oplog.go +++ b/mongorestore/oplog.go @@ -589,13 +589,14 @@ func extractIndexDocumentFromCommitIndexBuilds(op db.Oplog) (string, []*idx.Inde indexSpec.Options = bson.M{} //nolint:errcheck for _, elem := range index.(bson.D) { - if elem.Key == "key" { + switch elem.Key { + case "key": //nolint:errcheck indexSpec.Key = elem.Value.(bson.D) - } else if elem.Key == "partialFilterExpression" { + case "partialFilterExpression": //nolint:errcheck indexSpec.PartialFilterExpression = elem.Value.(bson.D) - } else { + default: indexSpec.Options[elem.Key] = elem.Value } } @@ -615,16 +616,17 @@ func extractIndexDocumentFromCreateIndexes(op db.Oplog) (string, *idx.IndexDocum collectionName := "" indexDocument := &idx.IndexDocument{Options: bson.M{}} for _, elem := range op.Object { - if elem.Key == "createIndexes" { + switch elem.Key { + case "createIndexes": //nolint:errcheck collectionName = elem.Value.(string) - } else if elem.Key == "key" { + case "key": //nolint:errcheck indexDocument.Key = elem.Value.(bson.D) - } else if elem.Key == "partialFilterExpression" { + case "partialFilterExpression": //nolint:errcheck indexDocument.PartialFilterExpression = elem.Value.(bson.D) - } else { + default: indexDocument.Options[elem.Key] = elem.Value } } diff --git a/mongorestore/options.go b/mongorestore/options.go index b26a08df0..33301cebd 100644 --- a/mongorestore/options.go +++ b/mongorestore/options.go @@ -169,7 +169,7 @@ func ParseOptions(rawArgs []string, versionStr, gitCommit string) (Options, erro log.SetVerbosity(opts.Verbosity) // verify uri options and log them - opts.URI.LogUnsupportedOptions() + opts.LogUnsupportedOptions() targetDir, err := getTargetDirFromArgs(extraArgs, inputOpts.Directory) if err != nil { @@ -177,7 +177,7 @@ func ParseOptions(rawArgs []string, versionStr, gitCommit string) (Options, erro } targetDir = util.ToUniversalPath(targetDir) - wc, err := db.NewMongoWriteConcern(outputOpts.WriteConcern, opts.URI.ParsedConnString()) + wc, err := db.NewMongoWriteConcern(outputOpts.WriteConcern, opts.ParsedConnString()) if err != nil { return Options{}, fmt.Errorf("error parsing write concern: %v", err) } diff --git a/mongorestore/options_test.go b/mongorestore/options_test.go index 9bf469e7e..fac8dadf4 100644 --- a/mongorestore/options_test.go +++ b/mongorestore/options_test.go @@ -87,7 +87,7 @@ func TestURIParsing(t *testing.T) { opts, err := ParseOptions(args, "", "") So(err, ShouldBeNil) - So(opts.ToolOptions.DB, ShouldEqual, "test") + So(opts.DB, ShouldEqual, "test") }) } @@ -263,24 +263,37 @@ func TestPositionalArgumentParsing(t *testing.T) { So(opts.TargetDirectory, ShouldEqual, tc.ExpectedOpts.TargetDirectory) So(opts.ConnectionString, ShouldEqual, tc.ExpectedOpts.ConnectionString) } - if tc.AuthType == "aws" { - So(opts.Auth.Username, ShouldEqual, tc.ExpectedOpts.Auth.Username) - So(opts.Auth.Password, ShouldEqual, tc.ExpectedOpts.Auth.Password) - So(opts.Auth.Mechanism, ShouldEqual, tc.ExpectedOpts.Auth.Mechanism) - So(opts.Auth.AWSSessionToken, ShouldEqual, tc.ExpectedOpts.Auth.AWSSessionToken) + switch tc.AuthType { + case "aws": + So(opts.Username, ShouldEqual, tc.ExpectedOpts.Username) + So(opts.Password, ShouldEqual, tc.ExpectedOpts.Password) + So(opts.Mechanism, ShouldEqual, tc.ExpectedOpts.Mechanism) + So(opts.AWSSessionToken, ShouldEqual, tc.ExpectedOpts.AWSSessionToken) So( - opts.URI.ConnString.AuthMechanismProperties["AWS_SESSION_TOKEN"], + opts.ConnString.AuthMechanismProperties["AWS_SESSION_TOKEN"], ShouldEqual, - tc.ExpectedOpts.URI.ConnString.AuthMechanismProperties["AWS_SESSION_TOKEN"], + tc.ExpectedOpts.ConnString.AuthMechanismProperties["AWS_SESSION_TOKEN"], ) - } else if tc.AuthType == "kerberos" { - So(opts.Auth.Username, ShouldEqual, tc.ExpectedOpts.Auth.Username) - So(opts.Auth.Mechanism, ShouldEqual, tc.ExpectedOpts.Auth.Mechanism) - So(opts.Auth.Source, ShouldEqual, tc.ExpectedOpts.Auth.Source) - So(opts.URI.ConnString.AuthMechanismProperties["SERVICE_NAME"], ShouldEqual, tc.ExpectedOpts.URI.ConnString.AuthMechanismProperties["SERVICE_NAME"]) - So(opts.URI.ConnString.AuthMechanismProperties["CANONICALIZE_HOST_NAME"], ShouldEqual, tc.ExpectedOpts.URI.ConnString.AuthMechanismProperties["CANONICALIZE_HOST_NAME"]) - So(opts.URI.ConnString.AuthMechanismProperties["SERVICE_REALM"], ShouldEqual, tc.ExpectedOpts.URI.ConnString.AuthMechanismProperties["SERVICE_REALM"]) - So(opts.Kerberos.Service, ShouldEqual, tc.ExpectedOpts.Kerberos.Service) + case "kerberos": + So(opts.Username, ShouldEqual, tc.ExpectedOpts.Username) + So(opts.Mechanism, ShouldEqual, tc.ExpectedOpts.Mechanism) + So(opts.Source, ShouldEqual, tc.ExpectedOpts.Source) + So( + opts.ConnString.AuthMechanismProperties["SERVICE_NAME"], + ShouldEqual, + tc.ExpectedOpts.ConnString.AuthMechanismProperties["SERVICE_NAME"], + ) + So( + opts.ConnString.AuthMechanismProperties["CANONICALIZE_HOST_NAME"], + ShouldEqual, + tc.ExpectedOpts.ConnString.AuthMechanismProperties["CANONICALIZE_HOST_NAME"], + ) + So( + opts.ConnString.AuthMechanismProperties["SERVICE_REALM"], + ShouldEqual, + tc.ExpectedOpts.ConnString.AuthMechanismProperties["SERVICE_REALM"], + ) + So(opts.Service, ShouldEqual, tc.ExpectedOpts.Service) } } }) diff --git a/mongorestore/restore.go b/mongorestore/restore.go index 7368cb522..26ccac66b 100644 --- a/mongorestore/restore.go +++ b/mongorestore/restore.go @@ -693,7 +693,6 @@ func (restore *MongoRestore) RestoreCollectionToDB( } result.combineWith(NewResultFromBulkResult(bwResult, bwErr)) resultChan <- result.withErr(db.FilterError(restore.OutputOptions.StopOnError, result.Err)) - return }() // sleep to prevent all threads from inserting at the same time at start diff --git a/mongostat/main/mongostat.go b/mongostat/main/mongostat.go index f5aa7248a..4efcbb7b0 100644 --- a/mongostat/main/mongostat.go +++ b/mongostat/main/mongostat.go @@ -77,12 +77,12 @@ func main() { } // verify uri options and log them - opts.URI.LogUnsupportedOptions() + opts.LogUnsupportedOptions() - if opts.Auth.Username != "" && opts.GetAuthenticationDatabase() == "" && - !opts.Auth.RequiresExternalDB() { + if opts.Username != "" && opts.GetAuthenticationDatabase() == "" && + !opts.RequiresExternalDB() { // add logic to have different error if using uri - if opts.URI != nil && opts.URI.ConnectionString != "" { + if opts.URI != nil && opts.ConnectionString != "" { log.Logvf( log.Always, "authSource is required when authenticating against a non $external database", @@ -128,7 +128,7 @@ func main() { log.Logvf(log.Always, "Failed: %v", err) os.Exit(util.ExitFailure) } - opts.Auth.Password = pass + opts.Password = pass } var factory stat_consumer.FormatterConstructor diff --git a/mongostat/mongostat.go b/mongostat/mongostat.go index 26c1626dd..29492220f 100644 --- a/mongostat/mongostat.go +++ b/mongostat/mongostat.go @@ -236,8 +236,8 @@ func (cluster *AsyncClusterMonitor) Monitor(sleep time.Duration) error { func NewNodeMonitor(opts options.ToolOptions, fullHost string) (*NodeMonitor, error) { optsCopy := opts host, port := parseHostPort(fullHost) - optsCopy.Connection.Host = host - optsCopy.Connection.Port = port + optsCopy.Host = host + optsCopy.Port = port uriCopy := *opts.URI newCS, err := rewriteURI(uriCopy.ConnectionString, fullHost) if err != nil { diff --git a/mongostat/options_test.go b/mongostat/options_test.go index b54dd5e06..d6a920260 100644 --- a/mongostat/options_test.go +++ b/mongostat/options_test.go @@ -173,24 +173,37 @@ func TestPositionalArgumentParsing(t *testing.T) { So(opts.SleepInterval, ShouldEqual, tc.ExpectedOpts.SleepInterval) So(opts.ConnectionString, ShouldEqual, tc.ExpectedOpts.ConnectionString) } - if tc.AuthType == "aws" { - So(opts.Auth.Username, ShouldEqual, tc.ExpectedOpts.Auth.Username) - So(opts.Auth.Password, ShouldEqual, tc.ExpectedOpts.Auth.Password) - So(opts.Auth.Mechanism, ShouldEqual, tc.ExpectedOpts.Auth.Mechanism) - So(opts.Auth.AWSSessionToken, ShouldEqual, tc.ExpectedOpts.Auth.AWSSessionToken) + switch tc.AuthType { + case "aws": + So(opts.Username, ShouldEqual, tc.ExpectedOpts.Username) + So(opts.Password, ShouldEqual, tc.ExpectedOpts.Password) + So(opts.Mechanism, ShouldEqual, tc.ExpectedOpts.Mechanism) + So(opts.AWSSessionToken, ShouldEqual, tc.ExpectedOpts.AWSSessionToken) So( - opts.URI.ConnString.AuthMechanismProperties["AWS_SESSION_TOKEN"], + opts.ConnString.AuthMechanismProperties["AWS_SESSION_TOKEN"], ShouldEqual, - tc.ExpectedOpts.URI.ConnString.AuthMechanismProperties["AWS_SESSION_TOKEN"], + tc.ExpectedOpts.ConnString.AuthMechanismProperties["AWS_SESSION_TOKEN"], ) - } else if tc.AuthType == "kerberos" { - So(opts.Auth.Username, ShouldEqual, tc.ExpectedOpts.Auth.Username) - So(opts.Auth.Mechanism, ShouldEqual, tc.ExpectedOpts.Auth.Mechanism) - So(opts.Auth.Source, ShouldEqual, tc.ExpectedOpts.Auth.Source) - So(opts.URI.ConnString.AuthMechanismProperties["SERVICE_NAME"], ShouldEqual, tc.ExpectedOpts.URI.ConnString.AuthMechanismProperties["SERVICE_NAME"]) - So(opts.URI.ConnString.AuthMechanismProperties["CANONICALIZE_HOST_NAME"], ShouldEqual, tc.ExpectedOpts.URI.ConnString.AuthMechanismProperties["CANONICALIZE_HOST_NAME"]) - So(opts.URI.ConnString.AuthMechanismProperties["SERVICE_REALM"], ShouldEqual, tc.ExpectedOpts.URI.ConnString.AuthMechanismProperties["SERVICE_REALM"]) - So(opts.Kerberos.Service, ShouldEqual, tc.ExpectedOpts.Kerberos.Service) + case "kerberos": + So(opts.Username, ShouldEqual, tc.ExpectedOpts.Username) + So(opts.Mechanism, ShouldEqual, tc.ExpectedOpts.Mechanism) + So(opts.Source, ShouldEqual, tc.ExpectedOpts.Source) + So( + opts.ConnString.AuthMechanismProperties["SERVICE_NAME"], + ShouldEqual, + tc.ExpectedOpts.ConnString.AuthMechanismProperties["SERVICE_NAME"], + ) + So( + opts.ConnString.AuthMechanismProperties["CANONICALIZE_HOST_NAME"], + ShouldEqual, + tc.ExpectedOpts.ConnString.AuthMechanismProperties["CANONICALIZE_HOST_NAME"], + ) + So( + opts.ConnString.AuthMechanismProperties["SERVICE_REALM"], + ShouldEqual, + tc.ExpectedOpts.ConnString.AuthMechanismProperties["SERVICE_REALM"], + ) + So(opts.Service, ShouldEqual, tc.ExpectedOpts.Service) } } }) diff --git a/mongotop/main/mongotop.go b/mongotop/main/mongotop.go index 336511da6..57923fba8 100644 --- a/mongotop/main/mongotop.go +++ b/mongotop/main/mongotop.go @@ -47,15 +47,15 @@ func main() { signals.Handle() // verify uri options and log them - opts.URI.LogUnsupportedOptions() + opts.LogUnsupportedOptions() if opts.RowCount < 0 { log.Logvf(log.Always, "invalid value for --rowcount: %v", opts.RowCount) os.Exit(util.ExitFailure) } - if opts.Auth.Username != "" && opts.Auth.Source == "" && !opts.Auth.RequiresExternalDB() { - if opts.URI != nil && opts.URI.ConnectionString != "" { + if opts.Username != "" && opts.Source == "" && !opts.RequiresExternalDB() { + if opts.URI != nil && opts.ConnectionString != "" { log.Logvf( log.Always, "authSource is required when authenticating against a non $external database", diff --git a/mongotop/mongotop.go b/mongotop/mongotop.go index 7568234bb..058ab0770 100644 --- a/mongotop/mongotop.go +++ b/mongotop/mongotop.go @@ -142,7 +142,7 @@ func (mt *MongoTop) Run() error { log.Logvf( log.Always, "connected to: %v\n", - util.SanitizeURI(mt.Options.URI.ConnectionString), + util.SanitizeURI(mt.Options.ConnectionString), ) } diff --git a/mongotop/options.go b/mongotop/options.go index 968e5844b..a6db7595e 100644 --- a/mongotop/options.go +++ b/mongotop/options.go @@ -35,7 +35,7 @@ type Output struct { } // Name returns a human-readable group name for output options. -func (_ *Output) Name() string { +func (*Output) Name() string { return "output" } diff --git a/mongotop/options_test.go b/mongotop/options_test.go index b36e63f63..edfa195db 100644 --- a/mongotop/options_test.go +++ b/mongotop/options_test.go @@ -173,24 +173,37 @@ func TestPositionalArgumentParsing(t *testing.T) { So(opts.SleepTime, ShouldEqual, tc.ExpectedOpts.SleepTime) So(opts.ConnectionString, ShouldEqual, tc.ExpectedOpts.ConnectionString) } - if tc.AuthType == "aws" { - So(opts.Auth.Username, ShouldEqual, tc.ExpectedOpts.Auth.Username) - So(opts.Auth.Password, ShouldEqual, tc.ExpectedOpts.Auth.Password) - So(opts.Auth.Mechanism, ShouldEqual, tc.ExpectedOpts.Auth.Mechanism) - So(opts.Auth.AWSSessionToken, ShouldEqual, tc.ExpectedOpts.Auth.AWSSessionToken) + switch tc.AuthType { + case "aws": + So(opts.Username, ShouldEqual, tc.ExpectedOpts.Username) + So(opts.Password, ShouldEqual, tc.ExpectedOpts.Password) + So(opts.Mechanism, ShouldEqual, tc.ExpectedOpts.Mechanism) + So(opts.AWSSessionToken, ShouldEqual, tc.ExpectedOpts.AWSSessionToken) So( - opts.URI.ConnString.AuthMechanismProperties["AWS_SESSION_TOKEN"], + opts.ConnString.AuthMechanismProperties["AWS_SESSION_TOKEN"], ShouldEqual, - tc.ExpectedOpts.URI.ConnString.AuthMechanismProperties["AWS_SESSION_TOKEN"], + tc.ExpectedOpts.ConnString.AuthMechanismProperties["AWS_SESSION_TOKEN"], ) - } else if tc.AuthType == "kerberos" { - So(opts.Auth.Username, ShouldEqual, tc.ExpectedOpts.Auth.Username) - So(opts.Auth.Mechanism, ShouldEqual, tc.ExpectedOpts.Auth.Mechanism) - So(opts.Auth.Source, ShouldEqual, tc.ExpectedOpts.Auth.Source) - So(opts.URI.ConnString.AuthMechanismProperties["SERVICE_NAME"], ShouldEqual, tc.ExpectedOpts.URI.ConnString.AuthMechanismProperties["SERVICE_NAME"]) - So(opts.URI.ConnString.AuthMechanismProperties["CANONICALIZE_HOST_NAME"], ShouldEqual, tc.ExpectedOpts.URI.ConnString.AuthMechanismProperties["CANONICALIZE_HOST_NAME"]) - So(opts.URI.ConnString.AuthMechanismProperties["SERVICE_REALM"], ShouldEqual, tc.ExpectedOpts.URI.ConnString.AuthMechanismProperties["SERVICE_REALM"]) - So(opts.Kerberos.Service, ShouldEqual, tc.ExpectedOpts.Kerberos.Service) + case "kerberos": + So(opts.Username, ShouldEqual, tc.ExpectedOpts.Username) + So(opts.Mechanism, ShouldEqual, tc.ExpectedOpts.Mechanism) + So(opts.Source, ShouldEqual, tc.ExpectedOpts.Source) + So( + opts.ConnString.AuthMechanismProperties["SERVICE_NAME"], + ShouldEqual, + tc.ExpectedOpts.ConnString.AuthMechanismProperties["SERVICE_NAME"], + ) + So( + opts.ConnString.AuthMechanismProperties["CANONICALIZE_HOST_NAME"], + ShouldEqual, + tc.ExpectedOpts.ConnString.AuthMechanismProperties["CANONICALIZE_HOST_NAME"], + ) + So( + opts.ConnString.AuthMechanismProperties["SERVICE_REALM"], + ShouldEqual, + tc.ExpectedOpts.ConnString.AuthMechanismProperties["SERVICE_REALM"], + ) + So(opts.Service, ShouldEqual, tc.ExpectedOpts.Service) } } }) diff --git a/precious.toml b/precious.toml index 746229f4c..b5b06abb2 100644 --- a/precious.toml +++ b/precious.toml @@ -21,7 +21,6 @@ cmd = [ "--allow-parallel-runners", "--build-tags", "failpoints", "--color", "always", - "--sort-results", "--timeout", "5m", ] tidy-flags = "--fix" @@ -67,12 +66,15 @@ path-args = "dir" # SARIF report in Evergreen but use the default format for linting. cmd = [ "$PRECIOUS_ROOT/etc/gosec-wrapper.sh", - # This rule complains about reading or writing to paths based on user input, - # but most of the tools exist for the purpose of reading and writing from/to - # user-provided paths. - "-exclude", "G304", "-severity", "high", "-terse", + + # G304 complains about reading or writing to paths based on user input, + # but most of the tools exist for the purpose of reading and writing from/to + # user-provided paths. + # + # G115 is integer-overflow errors. TODO: Actually fix these. + "-exclude", "G304,G115", ] ok_exit_codes = [0] lint_failure_exit_codes = [1] diff --git a/release/download/download_server.go b/release/download/download_server.go index 2cb54f2c1..6d62e680e 100644 --- a/release/download/download_server.go +++ b/release/download/download_server.go @@ -35,7 +35,7 @@ type ServerArchive struct { } var ( - ServerURLMissingError = fmt.Errorf( + ErrServerURLMissing = fmt.Errorf( "Unable to find download URL for the server in the json feed", ) ) @@ -103,5 +103,5 @@ func (f *ServerJSONFeed) FindURLHashAndVersion( } } - return "", "", versionGuess, ServerURLMissingError + return "", "", versionGuess, ErrServerURLMissing } diff --git a/release/platform/platform_test.go b/release/platform/platform_test.go index 593b155e9..db95c23ba 100644 --- a/release/platform/platform_test.go +++ b/release/platform/platform_test.go @@ -72,9 +72,7 @@ func TestPlatformsAreSorted(t *testing.T) { current := Platforms() var sorted []Platform - for _, p := range current { - sorted = append(sorted, p) - } + sorted = append(sorted, current...) sort.SliceStable(sorted, func(i, j int) bool { if sorted[i].Name != sorted[j].Name { return sorted[i].Name < sorted[j].Name diff --git a/release/release.go b/release/release.go index 7d9299633..8da9cf163 100644 --- a/release/release.go +++ b/release/release.go @@ -452,12 +452,12 @@ func buildRPM() { contentBytes, err := os.ReadFile(filepath.Join("..", "installer", "rpm", specFile)) content := string(contentBytes) check(err, "reading spec file content") - content = strings.Replace(content, "@TOOLS_VERSION@", rpmVersion, -1) - content = strings.Replace(content, "@TOOLS_RELEASE@", rpmRelease, -1) + content = strings.ReplaceAll(content, "@TOOLS_VERSION@", rpmVersion) + content = strings.ReplaceAll(content, "@TOOLS_RELEASE@", rpmRelease) static := getStaticFiles("..", rpmFilename) bomFilename := filepath.Base(static[len(static)-1]) - content = strings.Replace(content, "@TOOLS_BOM_FILE@", bomFilename, -1) - content = strings.Replace(content, "@ARCHITECTURE@", pf.RPMArch(), -1) + content = strings.ReplaceAll(content, "@TOOLS_BOM_FILE@", bomFilename) + content = strings.ReplaceAll(content, "@ARCHITECTURE@", pf.RPMArch()) _, err = f.WriteString(content) check(err, "write content to spec file") } @@ -563,7 +563,7 @@ func buildDeb() { contentBytes, err := os.ReadFile(filepath.Join("..", "installer", "deb", "control")) content := string(contentBytes) check(err, "reading control file content") - content = strings.Replace(content, "@TOOLS_VERSION@", v.String(), -1) + content = strings.ReplaceAll(content, "@TOOLS_VERSION@", v.String()) content = strings.Replace(content, "@ARCHITECTURE@", pf.DebianArch(), 1) _, err = f.WriteString(content) @@ -1438,7 +1438,7 @@ func downloadMongodAndShell(v string) { pf, "enterprise", ) - if err == download.ServerURLMissingError { + if err == download.ErrServerURLMissing { // If a server version is not found from JSON feed, handle this by downloading the artifacts from evergreen. fmt.Printf("warning: download a version not found in JSON feed\n") fmt.Printf("warning: using a guessed version (%s)\n", serverVersion)