func newMongoRestore() *MongoRestore { renamer, _ := ns.NewRenamer([]string{}, []string{}) includer, _ := ns.NewMatcher([]string{"*"}) excluder, _ := ns.NewMatcher([]string{}) return &MongoRestore{ manager: intents.NewIntentManager(), InputOptions: &InputOptions{}, ToolOptions: &commonOpts.ToolOptions{}, NSOptions: &NSOptions{}, renamer: renamer, includer: includer, excluder: excluder, } }
// ParseAndValidateOptions returns a non-nil error if user-supplied options are invalid. func (restore *MongoRestore) ParseAndValidateOptions() error { // Can't use option pkg defaults for --objcheck because it's two separate flags, // and we need to be able to see if they're both being used. We default to // true here and then see if noobjcheck is enabled. log.Logv(log.DebugHigh, "checking options") if restore.InputOptions.Objcheck { restore.objCheck = true log.Logv(log.DebugHigh, "\tdumping with object check enabled") } else { log.Logv(log.DebugHigh, "\tdumping with object check disabled") } if restore.NSOptions.DB == "" && restore.NSOptions.Collection != "" { return fmt.Errorf("cannot restore a collection without a specified database") } if restore.NSOptions.DB != "" { if err := util.ValidateDBName(restore.NSOptions.DB); err != nil { return fmt.Errorf("invalid db name: %v", err) } } if restore.NSOptions.Collection != "" { if err := util.ValidateCollectionGrammar(restore.NSOptions.Collection); err != nil { return fmt.Errorf("invalid collection name: %v", err) } } if restore.InputOptions.RestoreDBUsersAndRoles && restore.NSOptions.DB == "" { return fmt.Errorf("cannot use --restoreDbUsersAndRoles without a specified database") } if restore.InputOptions.RestoreDBUsersAndRoles && restore.NSOptions.DB == "admin" { return fmt.Errorf("cannot use --restoreDbUsersAndRoles with the admin database") } var err error restore.isMongos, err = restore.SessionProvider.IsMongos() if err != nil { return err } if restore.isMongos { log.Logv(log.DebugLow, "restoring to a sharded system") } if restore.InputOptions.OplogLimit != "" { if !restore.InputOptions.OplogReplay { return fmt.Errorf("cannot use --oplogLimit without --oplogReplay enabled") } restore.oplogLimit, err = ParseTimestampFlag(restore.InputOptions.OplogLimit) if err != nil { return fmt.Errorf("error parsing timestamp argument to --oplogLimit: %v", err) } } if restore.InputOptions.OplogFile != "" { if !restore.InputOptions.OplogReplay { return fmt.Errorf("cannot use --oplogFile without --oplogReplay enabled") } if restore.InputOptions.Archive != "" { return fmt.Errorf("cannot use --oplogFile with --archive specified") } } // check if we are using a replica set and fall back to w=1 if we aren't (for <= 2.4) nodeType, err := restore.SessionProvider.GetNodeType() if err != nil { return fmt.Errorf("error determining type of connected node: %v", err) } log.Logvf(log.DebugLow, "connected to node type: %v", nodeType) restore.safety, err = db.BuildWriteConcern(restore.OutputOptions.WriteConcern, nodeType) if err != nil { return fmt.Errorf("error parsing write concern: %v", err) } // deprecations with --nsInclude --nsExclude if restore.NSOptions.DB != "" || restore.NSOptions.Collection != "" { // these are only okay if restoring from a bson file _, fileType := restore.getInfoFromFilename(restore.TargetDirectory) if fileType != BSONFileType { log.Logvf(log.Always, "the --db and --collection args should only be used when "+ "restoring from a BSON file. Other uses are deprecated and will not exist "+ "in the future; use --nsInclude instead") } } if len(restore.NSOptions.ExcludedCollections) > 0 || len(restore.NSOptions.ExcludedCollectionPrefixes) > 0 { log.Logvf(log.Always, "the --excludeCollections and --excludeCollectionPrefixes options "+ "are deprecated and will not exist in the future; use --nsExclude instead") } if restore.InputOptions.OplogReplay { if len(restore.NSOptions.NSInclude) > 0 || restore.NSOptions.DB != "" { return fmt.Errorf("cannot use --oplogReplay with includes specified") } if len(restore.NSOptions.NSExclude) > 0 || len(restore.NSOptions.ExcludedCollections) > 0 || len(restore.NSOptions.ExcludedCollectionPrefixes) > 0 { return fmt.Errorf("cannot use --oplogReplay with excludes specified") } if len(restore.NSOptions.NSFrom) > 0 { return fmt.Errorf("cannot use --oplogReplay with namespace renames specified") } } includes := restore.NSOptions.NSInclude if restore.NSOptions.DB != "" && restore.NSOptions.Collection != "" { includes = append(includes, ns.Escape(restore.NSOptions.DB)+"."+ restore.NSOptions.Collection) } else if restore.NSOptions.DB != "" { includes = append(includes, ns.Escape(restore.NSOptions.DB)+".*") } if len(includes) == 0 { includes = []string{"*"} } restore.includer, err = ns.NewMatcher(includes) if err != nil { return fmt.Errorf("invalid includes: %v", err) } if len(restore.NSOptions.ExcludedCollections) > 0 && restore.NSOptions.Collection != "" { return fmt.Errorf("--collection is not allowed when --excludeCollection is specified") } if len(restore.NSOptions.ExcludedCollectionPrefixes) > 0 && restore.NSOptions.Collection != "" { return fmt.Errorf("--collection is not allowed when --excludeCollectionsWithPrefix is specified") } excludes := restore.NSOptions.NSExclude for _, col := range restore.NSOptions.ExcludedCollections { excludes = append(excludes, "*."+ns.Escape(col)) } for _, colPrefix := range restore.NSOptions.ExcludedCollectionPrefixes { excludes = append(excludes, "*."+ns.Escape(colPrefix)+"*") } restore.excluder, err = ns.NewMatcher(excludes) if err != nil { return fmt.Errorf("invalid excludes: %v", err) } if len(restore.NSOptions.NSFrom) != len(restore.NSOptions.NSTo) { return fmt.Errorf("--nsFrom and --nsTo arguments must be specified an equal number of times") } restore.renamer, err = ns.NewRenamer(restore.NSOptions.NSFrom, restore.NSOptions.NSTo) if err != nil { return fmt.Errorf("invalid renames: %v", err) } if restore.OutputOptions.NumInsertionWorkers < 0 { return fmt.Errorf( "cannot specify a negative number of insertion workers per collection") } // a single dash signals reading from stdin if restore.TargetDirectory == "-" { if restore.InputOptions.Archive != "" { return fmt.Errorf( "cannot restore from \"-\" when --archive is specified") } if restore.NSOptions.Collection == "" { return fmt.Errorf("cannot restore from stdin without a specified collection") } } if restore.stdin == nil { restore.stdin = os.Stdin } return nil }