summaryrefslogtreecommitdiff
path: root/src/mongo/util
diff options
context:
space:
mode:
authorShaun Verch <shaun.verch@10gen.com>2013-10-10 10:53:56 -0400
committerShaun Verch <shaun.verch@10gen.com>2013-10-23 19:41:30 -0400
commit4686f81fe1ad2dc700ab17748d96e9c24f824579 (patch)
treeb3d16f6d6f49622bcafb1513c31c4e52b95037ea /src/mongo/util
parent0f9712f7a666699b83cee27fa7136ea92aa9e555 (diff)
downloadmongo-4686f81fe1ad2dc700ab17748d96e9c24f824579.tar.gz
SERVER-11144 Add attribute to affect what sources an option can have
Diffstat (limited to 'src/mongo/util')
-rw-r--r--src/mongo/util/options_parser/option_description.cpp5
-rw-r--r--src/mongo/util/options_parser/option_description.h23
-rw-r--r--src/mongo/util/options_parser/option_section.cpp12
-rw-r--r--src/mongo/util/options_parser/option_section.h17
-rw-r--r--src/mongo/util/options_parser/options_parser.cpp6
-rw-r--r--src/mongo/util/options_parser/options_parser_test.cpp264
6 files changed, 315 insertions, 12 deletions
diff --git a/src/mongo/util/options_parser/option_description.cpp b/src/mongo/util/options_parser/option_description.cpp
index 6129d68597d..a98b33f1d6c 100644
--- a/src/mongo/util/options_parser/option_description.cpp
+++ b/src/mongo/util/options_parser/option_description.cpp
@@ -167,5 +167,10 @@ namespace optionenvironment {
return *this;
}
+ OptionDescription& OptionDescription::setSources(OptionSources sources) {
+ _sources = sources;
+ return *this;
+ }
+
} // namespace optionenvironment
} // namespace mongo
diff --git a/src/mongo/util/options_parser/option_description.h b/src/mongo/util/options_parser/option_description.h
index 56fadd93338..8068665b265 100644
--- a/src/mongo/util/options_parser/option_description.h
+++ b/src/mongo/util/options_parser/option_description.h
@@ -39,6 +39,18 @@ namespace optionenvironment {
};
/**
+ * An OptionSources is an enum representing where an option can come from
+ */
+ enum OptionSources {
+ SourceCommandLine = 1,
+ SourceINIConfig = 2,
+ SourceJSONConfig = 4,
+ SourceAllConfig = SourceINIConfig | SourceJSONConfig,
+ SourceAllLegacy = SourceINIConfig | SourceCommandLine,
+ SourceAll = SourceCommandLine | SourceINIConfig | SourceJSONConfig
+ };
+
+ /**
* The OptionDescription and PositionalOptionDescription classes are containers for information
* about the options we are expecting either on the command line or in config files. These
* should be registered in an OptionSection instance and passed to an OptionsParser.
@@ -56,7 +68,8 @@ namespace optionenvironment {
_isVisible(true),
_default(Value()),
_implicit(Value()),
- _isComposing(false) { }
+ _isComposing(false),
+ _sources(SourceAll) { }
/*
* The following functions are part of the chaining interface for option registration. See
@@ -95,6 +108,12 @@ namespace optionenvironment {
*/
OptionDescription& composing();
+ /*
+ * Specify the allowed sources for this option, such as CommandLine, JSONConfig, or
+ * INIConfig. The default is SourceAll which means the option can be present in any source
+ */
+ OptionDescription& setSources(OptionSources sources);
+
std::string _dottedName; // Used for JSON config and in Environment
std::string _singleName; // Used for boost command line and INI
OptionType _type; // Storage type of the argument value, or switch type (bool)
@@ -104,6 +123,8 @@ namespace optionenvironment {
Value _default; // Value if option is not specified
Value _implicit; // Value if option is specified with no argument
bool _isComposing; // Aggregate values from different sources instead of overriding
+ OptionSources _sources; // Places where an option can be specified (current sources are
+ // command line, json config, and ini config)
};
class PositionalOptionDescription {
diff --git a/src/mongo/util/options_parser/option_section.cpp b/src/mongo/util/options_parser/option_section.cpp
index bfd41d507b3..f6819549d9f 100644
--- a/src/mongo/util/options_parser/option_section.cpp
+++ b/src/mongo/util/options_parser/option_section.cpp
@@ -98,7 +98,9 @@ namespace optionenvironment {
try {
addOptionChaining(positionalOption._name, positionalOption._name,
- positionalOption._type, "hidden description").hidden();
+ positionalOption._type, "hidden description")
+ .hidden()
+ .setSources(SourceCommandLine);
}
catch (DBException &e) {
return e.toStatus();
@@ -370,11 +372,15 @@ namespace optionenvironment {
Status OptionSection::getBoostOptions(po::options_description* boostOptions,
bool visibleOnly,
- bool includeDefaults) const {
+ bool includeDefaults,
+ OptionSources sources) const {
std::list<OptionDescription>::const_iterator oditerator;
for (oditerator = _options.begin(); oditerator != _options.end(); oditerator++) {
- if (!visibleOnly || (oditerator->_isVisible)) {
+ // Only include this option if it matches the sources we specified and the option is
+ // either visible or we are requesting hidden options
+ if ((!visibleOnly || (oditerator->_isVisible)) &&
+ (oditerator->_sources & sources)) {
std::auto_ptr<po::value_semantic> boostType;
Status ret = typeToBoostType(&boostType,
oditerator->_type,
diff --git a/src/mongo/util/options_parser/option_section.h b/src/mongo/util/options_parser/option_section.h
index 05d3a807c0f..9dfcefd66ee 100644
--- a/src/mongo/util/options_parser/option_section.h
+++ b/src/mongo/util/options_parser/option_section.h
@@ -79,14 +79,20 @@ namespace optionenvironment {
* Add an option to this section, and returns a reference to an OptionDescription to allow
* for chaining.
*
- * Example:
+ * Examples:
*
* options.addOptionChaining("option", "option", moe::String, "Chaining Registration")
* .hidden().setDefault(moe::Value("default"))
- * .setImplicit(moe::Value("implicit")).composing();
+ * .setImplicit(moe::Value("implicit"));
*
- * This creates a hidden option that is composing and has default and implicit values. See
- * the OptionDescription class for details on these attributes.
+ * This creates a hidden option that has default and implicit values.
+ *
+ * options.addOptionChaining("name", "name", moe::String, "Composing Option")
+ * .composing().sources(SourceAllConfig);
+ *
+ * This creates an option that is composing and can be specified only in config files.
+ *
+ * See the OptionDescription class for details on the supported attributes.
*
* throws DBException on errors, such as attempting to register an option with the same name
* as another option. These represent programming errors that should not happen during
@@ -110,7 +116,8 @@ namespace optionenvironment {
// These functions are used by the OptionsParser to make calls into boost::program_options
Status getBoostOptions(po::options_description* boostOptions,
bool visibleOnly = false,
- bool includeDefaults = false) const;
+ bool includeDefaults = false,
+ OptionSources = SourceAll) const;
Status getBoostPositionalOptions(
po::positional_options_description* boostPositionalOptions) const;
diff --git a/src/mongo/util/options_parser/options_parser.cpp b/src/mongo/util/options_parser/options_parser.cpp
index 96bda76e445..3725d7a7ffc 100644
--- a/src/mongo/util/options_parser/options_parser.cpp
+++ b/src/mongo/util/options_parser/options_parser.cpp
@@ -167,7 +167,7 @@ namespace optionenvironment {
for(std::vector<OptionDescription>::const_iterator iterator = options_vector.begin();
iterator != options_vector.end(); iterator++) {
- if (key == iterator->_dottedName) {
+ if (key == iterator->_dottedName && (iterator->_sources & SourceJSONConfig)) {
return Status::OK();
}
}
@@ -463,7 +463,7 @@ namespace optionenvironment {
po::command_line_style::allow_long_disguise) ^
po::command_line_style::allow_sticky);
- Status ret = options.getBoostOptions(&boostOptions);
+ Status ret = options.getBoostOptions(&boostOptions, false, false, SourceCommandLine);
if (!ret.isOK()) {
return ret;
}
@@ -512,7 +512,7 @@ namespace optionenvironment {
po::options_description boostOptions;
po::variables_map vm;
- Status ret = options.getBoostOptions(&boostOptions);
+ Status ret = options.getBoostOptions(&boostOptions, false, false, SourceINIConfig);
if (!ret.isOK()) {
return ret;
}
diff --git a/src/mongo/util/options_parser/options_parser_test.cpp b/src/mongo/util/options_parser/options_parser_test.cpp
index 5171a33669e..1537c66f5c7 100644
--- a/src/mongo/util/options_parser/options_parser_test.cpp
+++ b/src/mongo/util/options_parser/options_parser_test.cpp
@@ -1867,4 +1867,268 @@ namespace {
}
}
+ TEST(OptionSources, SourceCommandLine) {
+ OptionsParserTester parser;
+ moe::Environment environment;
+ moe::Value value;
+ std::vector<std::string> argv;
+ std::map<std::string, std::string> env_map;
+ std::string parameter;
+
+ moe::OptionSection testOpts;
+ testOpts.addOptionChaining("config", "config", moe::String, "Config file to parse");
+ testOpts.addOptionChaining("parameter", "parameter", moe::String, "Parameter")
+ .setSources(moe::SourceCommandLine);
+
+ argv.clear();
+ argv.push_back("binaryname");
+ argv.push_back("--parameter");
+ argv.push_back("allowed");
+
+ ASSERT_OK(parser.run(testOpts, argv, env_map, &environment));
+ ASSERT_OK(environment.get(moe::Key("parameter"), &value));
+ ASSERT_OK(value.get(&parameter));
+ ASSERT_EQUALS(parameter, "allowed");
+
+ argv.clear();
+ argv.push_back("binaryname");
+ argv.push_back("--config");
+ argv.push_back("config.json");
+
+ parser.setConfig("config.json", "{ parameter : \"disallowed\" }");
+
+ ASSERT_NOT_OK(parser.run(testOpts, argv, env_map, &environment));
+
+ argv.clear();
+ argv.push_back("binaryname");
+ argv.push_back("--config");
+ argv.push_back("config.ini");
+
+ parser.setConfig("config.ini", "parameter=disallowed");
+
+ ASSERT_NOT_OK(parser.run(testOpts, argv, env_map, &environment));
+ }
+
+ TEST(OptionSources, SourceINIConfig) {
+ OptionsParserTester parser;
+ moe::Environment environment;
+ moe::Value value;
+ std::vector<std::string> argv;
+ std::map<std::string, std::string> env_map;
+ std::string parameter;
+
+ moe::OptionSection testOpts;
+ testOpts.addOptionChaining("config", "config", moe::String, "Config file to parse");
+ testOpts.addOptionChaining("parameter", "parameter", moe::String, "Parameter")
+ .setSources(moe::SourceINIConfig);
+
+ argv.clear();
+ argv.push_back("binaryname");
+ argv.push_back("--parameter");
+ argv.push_back("disallowed");
+
+ ASSERT_NOT_OK(parser.run(testOpts, argv, env_map, &environment));
+
+ argv.clear();
+ argv.push_back("binaryname");
+ argv.push_back("--config");
+ argv.push_back("config.json");
+
+ parser.setConfig("config.json", "{ parameter : \"disallowed\" }");
+
+ ASSERT_NOT_OK(parser.run(testOpts, argv, env_map, &environment));
+
+ argv.clear();
+ argv.push_back("binaryname");
+ argv.push_back("--config");
+ argv.push_back("config.ini");
+
+ parser.setConfig("config.ini", "parameter=allowed");
+
+ ASSERT_OK(parser.run(testOpts, argv, env_map, &environment));
+ ASSERT_OK(environment.get(moe::Key("parameter"), &value));
+ ASSERT_OK(value.get(&parameter));
+ ASSERT_EQUALS(parameter, "allowed");
+
+ }
+
+ TEST(OptionSources, SourceJSONConfig) {
+ OptionsParserTester parser;
+ moe::Environment environment;
+ moe::Value value;
+ std::vector<std::string> argv;
+ std::map<std::string, std::string> env_map;
+ std::string parameter;
+
+ moe::OptionSection testOpts;
+ testOpts.addOptionChaining("config", "config", moe::String, "Config file to parse");
+ testOpts.addOptionChaining("parameter", "parameter", moe::String, "Parameter")
+ .setSources(moe::SourceJSONConfig);
+
+ argv.clear();
+ argv.push_back("binaryname");
+ argv.push_back("--parameter");
+ argv.push_back("disallowed");
+
+ ASSERT_NOT_OK(parser.run(testOpts, argv, env_map, &environment));
+
+ argv.clear();
+ argv.push_back("binaryname");
+ argv.push_back("--config");
+ argv.push_back("config.json");
+
+ parser.setConfig("config.json", "{ parameter : \"allowed\" }");
+
+ ASSERT_OK(parser.run(testOpts, argv, env_map, &environment));
+ ASSERT_OK(environment.get(moe::Key("parameter"), &value));
+ ASSERT_OK(value.get(&parameter));
+ ASSERT_EQUALS(parameter, "allowed");
+
+ argv.clear();
+ argv.push_back("binaryname");
+ argv.push_back("--config");
+ argv.push_back("config.ini");
+
+ parser.setConfig("config.ini", "parameter=disallowed");
+
+ ASSERT_NOT_OK(parser.run(testOpts, argv, env_map, &environment));
+ }
+
+ TEST(OptionSources, SourceAllConfig) {
+ OptionsParserTester parser;
+ moe::Environment environment;
+ moe::Value value;
+ std::vector<std::string> argv;
+ std::map<std::string, std::string> env_map;
+ std::string parameter;
+
+ moe::OptionSection testOpts;
+ testOpts.addOptionChaining("config", "config", moe::String, "Config file to parse");
+ testOpts.addOptionChaining("parameter", "parameter", moe::String, "Parameter")
+ .setSources(moe::SourceAllConfig);
+
+ argv.clear();
+ argv.push_back("binaryname");
+ argv.push_back("--parameter");
+ argv.push_back("disallowed");
+
+ ASSERT_NOT_OK(parser.run(testOpts, argv, env_map, &environment));
+
+ argv.clear();
+ argv.push_back("binaryname");
+ argv.push_back("--config");
+ argv.push_back("config.json");
+
+ parser.setConfig("config.json", "{ parameter : \"allowed\" }");
+
+ ASSERT_OK(parser.run(testOpts, argv, env_map, &environment));
+ ASSERT_OK(environment.get(moe::Key("parameter"), &value));
+ ASSERT_OK(value.get(&parameter));
+ ASSERT_EQUALS(parameter, "allowed");
+
+ argv.clear();
+ argv.push_back("binaryname");
+ argv.push_back("--config");
+ argv.push_back("config.ini");
+
+ parser.setConfig("config.ini", "parameter=allowed");
+
+ ASSERT_OK(parser.run(testOpts, argv, env_map, &environment));
+ ASSERT_OK(environment.get(moe::Key("parameter"), &value));
+ ASSERT_OK(value.get(&parameter));
+ ASSERT_EQUALS(parameter, "allowed");
+ }
+
+ TEST(OptionSources, SourceAllLegacy) {
+ OptionsParserTester parser;
+ moe::Environment environment;
+ moe::Value value;
+ std::vector<std::string> argv;
+ std::map<std::string, std::string> env_map;
+ std::string parameter;
+
+ moe::OptionSection testOpts;
+ testOpts.addOptionChaining("config", "config", moe::String, "Config file to parse");
+ testOpts.addOptionChaining("parameter", "parameter", moe::String, "Parameter")
+ .setSources(moe::SourceAllLegacy);
+
+ argv.clear();
+ argv.push_back("binaryname");
+ argv.push_back("--parameter");
+ argv.push_back("allowed");
+
+ ASSERT_OK(parser.run(testOpts, argv, env_map, &environment));
+ ASSERT_OK(environment.get(moe::Key("parameter"), &value));
+ ASSERT_OK(value.get(&parameter));
+ ASSERT_EQUALS(parameter, "allowed");
+
+ argv.clear();
+ argv.push_back("binaryname");
+ argv.push_back("--config");
+ argv.push_back("config.json");
+
+ parser.setConfig("config.json", "{ parameter : \"disallowed\" }");
+
+ ASSERT_NOT_OK(parser.run(testOpts, argv, env_map, &environment));
+
+ argv.clear();
+ argv.push_back("binaryname");
+ argv.push_back("--config");
+ argv.push_back("config.ini");
+
+ parser.setConfig("config.ini", "parameter=allowed");
+
+ ASSERT_OK(parser.run(testOpts, argv, env_map, &environment));
+ ASSERT_OK(environment.get(moe::Key("parameter"), &value));
+ ASSERT_OK(value.get(&parameter));
+ ASSERT_EQUALS(parameter, "allowed");
+ }
+
+ TEST(OptionSources, SourceAll) {
+ OptionsParserTester parser;
+ moe::Environment environment;
+ moe::Value value;
+ std::vector<std::string> argv;
+ std::map<std::string, std::string> env_map;
+ std::string parameter;
+
+ moe::OptionSection testOpts;
+ testOpts.addOptionChaining("config", "config", moe::String, "Config file to parse");
+ testOpts.addOptionChaining("parameter", "parameter", moe::String, "Parameter")
+ .setSources(moe::SourceAll);
+
+ argv.clear();
+ argv.push_back("binaryname");
+ argv.push_back("--parameter");
+ argv.push_back("allowed");
+
+ ASSERT_OK(parser.run(testOpts, argv, env_map, &environment));
+ ASSERT_OK(environment.get(moe::Key("parameter"), &value));
+ ASSERT_OK(value.get(&parameter));
+ ASSERT_EQUALS(parameter, "allowed");
+
+ argv.clear();
+ argv.push_back("binaryname");
+ argv.push_back("--config");
+ argv.push_back("config.json");
+
+ parser.setConfig("config.json", "{ parameter : \"allowed\" }");
+
+ ASSERT_OK(parser.run(testOpts, argv, env_map, &environment));
+ ASSERT_OK(environment.get(moe::Key("parameter"), &value));
+ ASSERT_OK(value.get(&parameter));
+ ASSERT_EQUALS(parameter, "allowed");
+
+ argv.clear();
+ argv.push_back("binaryname");
+ argv.push_back("--config");
+ argv.push_back("config.ini");
+
+ parser.setConfig("config.ini", "parameter=allowed");
+
+ ASSERT_OK(parser.run(testOpts, argv, env_map, &environment));
+ ASSERT_OK(environment.get(moe::Key("parameter"), &value));
+ ASSERT_OK(value.get(&parameter));
+ ASSERT_EQUALS(parameter, "allowed");
+ }
} // unnamed namespace