diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b6d4b1e977..4a225c78911 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and since Bareos version 20 this project adheres to [Semantic Versioning](https: - when using PAM Bareos will now check authorization, too. If authorization is not configured, login will fail. See [updated documentation](https://docs.bareos.org/TasksAndConcepts/PAM.html#configuration) on how to proceed [PR #1115]. ### Added +- dird: add command line feature to print specific resources [PR #1153] - Python plugins: add default module_path to search path [PR #1038] - dird: extend the list command to be able to query volumes and pools by ID [PR #1041] - docs: Add chapter for mariabackup db plugin [PR #1016] @@ -152,5 +153,7 @@ and since Bareos version 20 this project adheres to [Semantic Versioning](https: [PR #1140]: https://github.com/bareos/bareos/pull/1140 [PR #1147]: https://github.com/bareos/bareos/pull/1147 [PR #1149]: https://github.com/bareos/bareos/pull/1149 +[PR #1152]: https://github.com/bareos/bareos/pull/1152 +[PR #1153]: https://github.com/bareos/bareos/pull/1153 [PR #1155]: https://github.com/bareos/bareos/pull/1155 [unreleased]: https://github.com/bareos/bareos/tree/master diff --git a/core/src/dird/dird.cc b/core/src/dird/dird.cc index d92ae2dc5cd..f629622a121 100644 --- a/core/src/dird/dird.cc +++ b/core/src/dird/dird.cc @@ -3,7 +3,7 @@ Copyright (C) 2000-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2016 Planets Communications B.V. - Copyright (C) 2013-2021 Bareos GmbH & Co. KG + Copyright (C) 2013-2022 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public @@ -183,24 +183,26 @@ static void usage() fprintf( stderr, _("Usage: bareos-dir [options]\n" - " -c use as configuration file or directory\n" - " -d set debug level to \n" - " -dt print timestamp in debug output\n" - " -f run in foreground (for debugging)\n" - " -g run as group \n" - " -m print kaboom output (for debugging)\n" + " -c use as configuration file or " + "directory\n" + " -d set debug level to \n" + " -dt print timestamp in debug output\n" + " -f run in foreground (for debugging)\n" + " -g run as group \n" + " -m print kaboom output (for debugging)\n" #if !defined(HAVE_WIN32) - " -p full path to pidfile (default: none)\n" + " -p full path to pidfile (default: none)\n" #endif - " -r run now\n" - " -s no signals (for debugging)\n" - " -t test - read configuration and exit\n" - " -u run as user \n" - " -v verbose user messages\n" - " -xc print configuration and exit\n" - " -xs print configuration file schema in JSON format " - "and exit\n" - " -? print this message.\n" + " -r run now\n" + " -s no signals (for debugging)\n" + " -t test - read configuration and exit\n" + " -u run as user \n" + " -v verbose user messages\n" + " -xc[resource[=]] print all or specific configuration " + "resources and exit\n" + " -xs print configuration schema in JSON " + "format and exit\n" + " -? print this message\n" "\n")); exit(1); @@ -222,6 +224,8 @@ int main(int argc, char* argv[]) cat_op mode; bool no_signals = false; bool export_config = false; + std::string export_config_resourcetype; + std::string export_config_resourcename; bool export_config_schema = false; char* uid = nullptr; char* gid = nullptr; @@ -303,6 +307,17 @@ int main(int argc, char* argv[]) export_config_schema = true; } else if (*optarg == 'c') { export_config = true; + // erase first char ('c') + std::string export_config_parameter = std::string(optarg).erase(0, 1); + size_t splitpos = export_config_parameter.find('='); + if (splitpos == export_config_parameter.npos) { + export_config_resourcetype = export_config_parameter; + } else { + export_config_resourcetype + = export_config_parameter.substr(0, splitpos); + export_config_resourcename + = export_config_parameter.substr(splitpos + 1); + } } else { usage(); } @@ -365,9 +380,13 @@ int main(int argc, char* argv[]) my_config->ParseConfig(); if (export_config) { - my_config->DumpResources(PrintMessage, nullptr); - - TerminateDird(0); + int rc = 0; + if (!my_config->DumpResources(PrintMessage, nullptr, + export_config_resourcetype, + export_config_resourcename)) { + rc = 1; + } + TerminateDird(rc); return 0; } diff --git a/core/src/lib/parse_conf.cc b/core/src/lib/parse_conf.cc index 7dc4d49ff84..467036e8e25 100644 --- a/core/src/lib/parse_conf.cc +++ b/core/src/lib/parse_conf.cc @@ -3,7 +3,7 @@ Copyright (C) 2000-2012 Free Software Foundation Europe e.V. Copyright (C) 2011-2012 Planets Communications B.V. - Copyright (C) 2013-2021 Bareos GmbH & Co. KG + Copyright (C) 2013-2022 Bareos GmbH & Co. KG This program is Free Software; you can redistribute it and/or modify it under the terms of version three of the GNU Affero General Public @@ -316,40 +316,31 @@ bool ConfigurationParser::AppendToResourcesChain(BareosResource* new_resource, return true; } -int ConfigurationParser::GetResourceTableIndex(int resource_type) +int ConfigurationParser::GetResourceTableIndex(const char* resource_type_name) { - int rindex = -1; - - if ((resource_type >= r_first_) && (resource_type <= r_last_)) { - rindex = resource_type = r_first_; + for (int i = 0; resources_[i].name; i++) { + if (Bstrcasecmp(resources_[i].name, resource_type_name)) { return i; } } - return rindex; + return -1; } -ResourceTable* ConfigurationParser::GetResourceTable(int resource_type) +int ConfigurationParser::GetResourceCode(const char* resource_type_name) { - ResourceTable* result = nullptr; - int rindex = GetResourceTableIndex(resource_type); - - if (rindex >= 0) { result = &resources_[rindex]; } + for (int i = 0; resources_[i].name; i++) { + if (Bstrcasecmp(resources_[i].name, resource_type_name)) { + return resources_[i].rcode; + } + } - return result; + return 0; } ResourceTable* ConfigurationParser::GetResourceTable( const char* resource_type_name) { - ResourceTable* result = nullptr; - int i; - - for (i = 0; resources_[i].name; i++) { - if (Bstrcasecmp(resources_[i].name, resource_type_name)) { - result = &resources_[i]; - } - } - - return result; + int res_table_index = GetResourceTableIndex(resource_type_name); + return &resources_[res_table_index]; } int ConfigurationParser::GetResourceItemIndex(ResourceItem* resource_items_, @@ -575,6 +566,37 @@ bool ConfigurationParser::RemoveResource(int rcode, const char* name) return false; } +bool ConfigurationParser::DumpResources(bool sendit(void* sock, + const char* fmt, + ...), + void* sock, + const std::string& res_type_name, + const std::string& res_name, + bool hide_sensitive_data) +{ + bool result = false; + if (res_type_name.empty()) { + DumpResources(sendit, sock, hide_sensitive_data); + result = true; + } else { + int res_type = GetResourceCode(res_type_name.c_str()); + if (res_type > 0) { + BareosResource* res = nullptr; + if (res_name.empty()) { + // No name, dump all resources of specified type + res = GetNextRes(res_type, nullptr); + } else { + // Dump a single resource with specified name + res = GetResWithName(res_type, res_name.c_str()); + res_type = -res_type; + } + if (res) { result = true; } + DumpResourceCb_(res_type, res, sendit, sock, hide_sensitive_data, false); + } + } + return result; +} + void ConfigurationParser::DumpResources(bool sendit(void* sock, const char* fmt, ...), diff --git a/core/src/lib/parse_conf.h b/core/src/lib/parse_conf.h index e977a14c787..7f49e400599 100644 --- a/core/src/lib/parse_conf.h +++ b/core/src/lib/parse_conf.h @@ -264,11 +264,15 @@ class ConfigurationParser { std::function ResourceSpecificInitializer); bool AppendToResourcesChain(BareosResource* new_resource, int rcode); bool RemoveResource(int rcode, const char* name); + bool DumpResources(bool sendit(void* sock, const char* fmt, ...), + void* sock, + const std::string& res_type_name, + const std::string& res_name, + bool hide_sensitive_data = false); void DumpResources(bool sendit(void* sock, const char* fmt, ...), void* sock, bool hide_sensitive_data = false); int GetResourceCode(const char* resource_type); - ResourceTable* GetResourceTable(int resource_type); ResourceTable* GetResourceTable(const char* resource_type_name); int GetResourceItemIndex(ResourceItem* res_table, const char* item); ResourceItem* GetResourceItem(ResourceItem* res_table, const char* item); @@ -354,7 +358,7 @@ class ConfigurationParser { const char* config_filename); bool GetConfigIncludePath(PoolMem& full_path, const char* config_dir); bool FindConfigPath(PoolMem& full_path); - int GetResourceTableIndex(int resource_type); + int GetResourceTableIndex(const char* resource_type_name); void StoreMsgs(LEX* lc, ResourceItem* item, int index, int pass); void StoreName(LEX* lc, ResourceItem* item, int index, int pass); void StoreStrname(LEX* lc, ResourceItem* item, int index, int pass); diff --git a/systemtests/tests/config-dump/etc/compare/Console-admin.conf b/systemtests/tests/config-dump/etc/compare/Console-admin.conf new file mode 100644 index 00000000000..c924840ff15 --- /dev/null +++ b/systemtests/tests/config-dump/etc/compare/Console-admin.conf @@ -0,0 +1,6 @@ +Console { + Name = "admin" + Password = "[md5]5ebe2294ecd0e0f08eab7690d2a6ee69" + Profile = "webui-admin" + TlsEnable = No +} diff --git a/systemtests/tests/config-dump/etc/compare/Console.conf b/systemtests/tests/config-dump/etc/compare/Console.conf new file mode 100644 index 00000000000..956db35d4bc --- /dev/null +++ b/systemtests/tests/config-dump/etc/compare/Console.conf @@ -0,0 +1,14 @@ +Console { + Name = "bareos-mon" + Description = "Restricted console used by tray-monitor to get the status of the director." + Password = "[md5]4cf5943929b8447731b086f0f43f7f99" + JobAcl = "*all*" + CommandAcl = "status", ".status" +} + +Console { + Name = "admin" + Password = "[md5]5ebe2294ecd0e0f08eab7690d2a6ee69" + Profile = "webui-admin" + TlsEnable = No +} diff --git a/systemtests/tests/config-dump/testrunner b/systemtests/tests/config-dump/testrunner index 38f29ef5e43..28bb55d491e 100755 --- a/systemtests/tests/config-dump/testrunner +++ b/systemtests/tests/config-dump/testrunner @@ -125,6 +125,50 @@ diff_files() fi } +compare_export_config() +{ + configfile="$1" + comparefile="$2" + directorparameter="$3" + + if ! [ -e "${configfile}" ]; then + set_error "Director config file \"${configfile}\" does not exist." + exit 1 + fi + + DESC="compare_export_config ${configfile} compare=${comparefile} parameter=${directorparameter}" + print_debug "*** start $DESC" + + "${BAREOS_DIRECTOR_BINARY}" -c "${configfile}" -xc"${directorparameter}" > $tmp/bareos-dir-xc-${directorparameter}.conf + + print_debug "*** end $DESC" + + diff_files "${comparefile}" "$tmp/bareos-dir-xc-${directorparameter}.conf" +} + +bareos_dir_failing() +{ + configfile="$1" + directorparameter="$2" + + if ! [ -e "${configfile}" ]; then + set_error "Director config file \"${configfile}\" does not exist." + exit 1 + fi + + DESC="bareos_dir_failing ${configfile} parameter=${directorparameter}" + print_debug "*** start $DESC" + + if OUT=$("${BAREOS_DIRECTOR_BINARY}" -c "${configfile}" -xc"${directorparameter}"); then + echo "${OUT}" + set_error "Starting Director with -xc"${directorparameter}" should fail." + exit 1 + fi + + print_debug "$OUT" + print_debug "*** end $DESC" +} + TestName="$(basename "$(pwd)")" export TestName @@ -176,4 +220,16 @@ diff_files "${tmp}/bareos-dir-show-full1.conf" "$tmp/bareos-dir-show-full2.conf" # Compare export and re-export from bareos-dir-full.conf(verbose versions). diff_files "${tmp}/bareos-dir-show-verbose-full1.conf" "$tmp/bareos-dir-show-verbose-full2.conf" + +# export all resources of a type +compare_export_config "${conf}/bareos-dir-19.2.7-xc.conf" "etc/compare/Console.conf" "console" +# export single resource +compare_export_config "${conf}/bareos-dir-19.2.7-xc.conf" "etc/compare/Console-admin.conf" "console=admin" +# try export non-existing resource +bareos_dir_failing "${conf}/bareos-dir-19.2.7-xc.conf" "console=DOESNOTEXIST" +# try export non-existing resource type +bareos_dir_failing "${conf}/bareos-dir-19.2.7-xc.conf" "DOESNOTEXIST" +# export unused (empty) resource type +bareos_dir_failing "${conf}/bareos-dir-19.2.7-xc.conf" "counter" + end_test