hooks_config.cc 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. // Copyright (C) 2017 Internet Systems Consortium, Inc. ("ISC")
  2. //
  3. // This Source Code Form is subject to the terms of the Mozilla Public
  4. // License, v. 2.0. If a copy of the MPL was not distributed with this
  5. // file, You can obtain one at http://mozilla.org/MPL/2.0/.
  6. #include <config.h>
  7. #include <hooks/hooks_config.h>
  8. #include <hooks/hooks_manager.h>
  9. using namespace std;
  10. using namespace isc;
  11. using namespace isc::data;
  12. namespace isc {
  13. namespace hooks {
  14. void
  15. HooksConfig::verifyLibraries(const Element::Position& position) const {
  16. // The code used to follow this logic:
  17. //
  18. // Check if the list of libraries has changed. If not, nothing is done
  19. // - the command "DhcpN libreload" is required to reload the same
  20. // libraries (this prevents needless reloads when anything else in the
  21. // configuration is changed).
  22. //
  23. // We no longer rely on this. Parameters can change. And even if the
  24. // parameters stay the same, they could point to files that could
  25. // change. We can skip loading routines only if there were and there still
  26. // are no libraries specified.
  27. vector<string> current_libraries = HooksManager::getLibraryNames();
  28. if (current_libraries.empty() && libraries_.empty()) {
  29. return;
  30. }
  31. // Library list has changed, validate each of the libraries specified.
  32. vector<string> lib_names = isc::hooks::extractNames(libraries_);
  33. vector<string> error_libs = HooksManager::validateLibraries(lib_names);
  34. if (!error_libs.empty()) {
  35. // Construct the list of libraries in error for the message.
  36. string error_list = error_libs[0];
  37. for (size_t i = 1; i < error_libs.size(); ++i) {
  38. error_list += (string(", ") + error_libs[i]);
  39. }
  40. isc_throw(InvalidHooksLibraries,
  41. "hooks libraries failed to validate - "
  42. "library or libraries in error are: "
  43. << error_list << "(" << position << ")");
  44. }
  45. }
  46. void
  47. HooksConfig::loadLibraries() const {
  48. /// Commits the list of libraries to the configuration manager storage if
  49. /// the list of libraries has changed.
  50. /// @todo: Delete any stored CalloutHandles before reloading the
  51. /// libraries
  52. if (!HooksManager::loadLibraries(libraries_)) {
  53. isc_throw(InvalidHooksLibraries,
  54. "One or more hook libraries failed to load");
  55. }
  56. }
  57. bool
  58. HooksConfig::equal(const HooksConfig& other) const {
  59. /// @todo: This comparision assumes that the library order is not relevant,
  60. /// so [ lib1, lib2 ] is equal to [ lib2, lib1 ]. However, this is not strictly
  61. /// true, because callouts execution is called in other they're loaded. Therefore
  62. /// changing the libraries order may change the server behavior.
  63. ///
  64. /// We don't have any libraries that are interacting (or would change their behavior
  65. /// depending on the order in which their callouts are executed), so the code is
  66. /// ok for now.
  67. for (isc::hooks::HookLibsCollection::const_iterator this_it = libraries_.begin();
  68. this_it != libraries_.end(); ++this_it) {
  69. bool match = false;
  70. for (isc::hooks::HookLibsCollection::const_iterator other_it =
  71. other.libraries_.begin(); other_it != other.libraries_.end(); ++other_it) {
  72. if (this_it->first != other_it->first) {
  73. continue;
  74. }
  75. if (isNull(this_it->second) && isNull(other_it->second)) {
  76. match = true;
  77. break;
  78. }
  79. if (isNull(this_it->second) || isNull(other_it->second)) {
  80. continue;
  81. }
  82. if (this_it->second->equals(*other_it->second)) {
  83. match = true;
  84. break;
  85. }
  86. }
  87. // No match found for the particular hooks library so return false.
  88. if (!match) {
  89. return (false);
  90. }
  91. }
  92. return (true);
  93. }
  94. ElementPtr
  95. HooksConfig::toElement() const {
  96. // hooks-libraries is a list of maps
  97. ElementPtr result = Element::createList();
  98. // Iterate through libraries
  99. for (HookLibsCollection::const_iterator hl = libraries_.begin();
  100. hl != libraries_.end(); ++hl) {
  101. // Entries are maps
  102. ElementPtr map = Element::createMap();
  103. // Set the library name
  104. map->set("library", Element::create(hl->first));
  105. // Set parameters (not set vs set empty map)
  106. if (!isNull(hl->second)) {
  107. map->set("parameters", hl->second);
  108. }
  109. // Push to the list
  110. result->add(map);
  111. }
  112. return (result);
  113. }
  114. };
  115. };