Kea 3.3.4
cb_cmds_impl.h
Go to the documentation of this file.
1// Copyright (C) 2026 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
7#ifndef CB_CMDS_IMPL_H
8#define CB_CMDS_IMPL_H
9
11#include <cc/data.h>
12#include <cc/simple_parser.h>
13#include <cc/stamped_value.h>
15#include <database/server.h>
18#include <dhcpsrv/cb_ctl_dhcp.h>
19#include <dhcpsrv/cfgmgr.h>
23#include <hooks/hooks.h>
24
25#include <cstdint>
26#include <sstream>
27
28#include <boost/noncopyable.hpp>
29#include <boost/shared_ptr.hpp>
30
31#include <cb_cmds/cb_parsers.h>
32#include <sys/socket.h>
33
34namespace isc {
35namespace cb {
36
40public:
41
55
61
67
149 template<typename ParserType, typename... ParserArgs, typename ElementType>
152 const std::string& list_name,
153 ParserArgs... parser_args,
154 ElementType& parsed_element,
155 db::BackendSelector& backend_selector,
156 db::ServerSelector& server_selector,
157 ServerTagsParse tags_parse,
158 data::Element::types sub_type = data::Element::map) const {
159 // Retrieve the command from the callout handle.
160 data::ConstElementPtr command;
161 callout_handle.getArgument("command", command);
162
163 // Expect that the command include arguments.
165 static_cast<void>(config::parseCommandWithArgs(args, command));
166
167 // Create backend selector from the received arguments. If the arguments
168 // do not include "remote" parameter, the default (unspecified) backend
169 // selector is created.
170 backend_selector = getBackendSelector(args);
171
172 // Create server selector from the received arguments.
173 server_selector = getServerSelector(args, tags_parse);
174
175 // Get the named list from the arguments.
176 data::ConstElementPtr element_list = args->get(list_name);
177 if (!element_list ||
178 (element_list->getType() != data::Element::list)) {
179 isc_throw(BadValue, "'" << list_name << "' parameter must be specified"
180 " and must be a list");
181
182 // We currently require exactly one argument in the list. In the future
183 // we may allow multiple elements.
184 } else if (element_list->size() != 1) {
185 isc_throw(BadValue, "'" << list_name << "' list must include exactly one element");
186 }
187
188 // Since we have already checked that there is one element in the list
189 // we can get it directly via index of 0.
190 data::ConstElementPtr element = element_list->get(0);
191
192 // It must be of the given type (default a map).
193 if (element->getType() != sub_type) {
194 isc_throw(BadValue, "'" << list_name << "' sub-element must be a "
195 << data::Element::typeToName(sub_type));
196 }
197
198 // Run the parser for this element and return it via the method's argument.
199 ParserType parser(parser_args...);
200 parsed_element = parser.parse(element);
201 return (args);
202 }
203
231 template<typename ParserType, typename... ParserArgs, typename ElementType>
234 const std::string& list_name,
235 ParserArgs... parser_args,
236 ElementType& parsed_element,
237 data::Element::types sub_type = data::Element::map) const {
238 // Retrieve the command from the callout handle.
239 data::ConstElementPtr command;
240 callout_handle.getArgument("command", command);
241
242 // Expect that the command include arguments.
244 static_cast<void>(config::parseCommandWithArgs(args, command));
245
246 // Skipped backend and server selectors.
247
248 // Get the named list from the arguments.
249 data::ConstElementPtr element_list = args->get(list_name);
250 if (!element_list ||
251 (element_list->getType() != data::Element::list)) {
252 isc_throw(BadValue, "'" << list_name << "' parameter must be specified"
253 " and must be a list");
254
255 // We currently require exactly one argument in the list. In the future
256 // we may allow multiple elements.
257 } else if (element_list->size() != 1) {
258 isc_throw(BadValue, "'" << list_name << "' list must include exactly one element");
259 }
260
261 // Since we have already checked that there is one element in the list
262 // we can get it directly via index of 0.
263 data::ConstElementPtr element = element_list->get(0);
264
265 // It must be of the given type (default a map).
266 if (element->getType() != sub_type) {
267 isc_throw(BadValue, "'" << list_name << "' sub-element must be a "
268 << data::Element::typeToName(sub_type));
269 }
270
271 // Run the parser for this element and return it via the method's argument.
272 ParserType parser(parser_args...);
273 parsed_element = parser.parse(element);
274 return (args);
275 }
276
329 template<typename ParserType, typename... ParserArgs, typename ElementType>
331 const std::string& map_name,
332 ParserArgs... parser_args,
333 ElementType& parsed_element,
334 db::BackendSelector& backend_selector,
335 db::ServerSelector& server_selector,
336 ServerTagsParse tags_parse) const {
337 // Retrieve the command from the callout handle.
338 data::ConstElementPtr command;
339 callout_handle.getArgument("command", command);
340
341 // Expect that the command include arguments.
343 static_cast<void>(config::parseCommandWithArgs(args, command));
344
345 // Create backend selector from the received arguments. If the arguments
346 // do not include "remote" parameter, the default (unspecified) backend
347 // selector is created.
348 backend_selector = getBackendSelector(args);
349
350 // Create server selector from the received arguments.
351 server_selector = getServerSelector(args, tags_parse);
352
353 // Get the named map from the arguments.
354 data::ConstElementPtr element_map = args->get(map_name);
355 if (!element_map || (element_map->getType() != data::Element::map)) {
356 isc_throw(BadValue, "'" << map_name << "' parameter must be specified"
357 " and must be a map");
358 }
359
360 // There must be at least one parameter in the map.
361 if (element_map->size() == 0) {
362 isc_throw(BadValue, "'" << map_name << "' map must not be empty");
363 }
364
365 // Run the parser for this element and return it via the method's argument.
366 ParserType parser(parser_args...);
367 parsed_element = parser.parse(element_map);
368 }
369
378 getBackendSelector(const data::ConstElementPtr& args) const;
379
400 ServerTagsParse tags_parse) const;
401
410
425 template<typename SubnetPtrType, typename KeyType>
427 const SubnetPtrType& subnet,
428 const uint16_t address_family,
429 const KeyType& key) {
430 int rcode;
431 std::ostringstream msg;
432 msg << (address_family == AF_INET ? "IPv4" : "IPv6")
433 << " subnet " << key << " ";
436 info->set("subnets", info_list);
437 if (subnet) {
439 data::ElementPtr subnet_element = subnet->toElement();
440
441 // Always include shared network name.
442 std::string sn_name = subnet->getSharedNetworkName();
443 if (!sn_name.empty()) {
444 subnet_element->set("shared-network-name",
445 data::Element::create(sn_name));
446
447 } else {
448 // Shared network name is null.
449 subnet_element->set("shared-network-name",
451 }
452
453 // Include metadata with the subnet.
454 subnet_element->set("metadata", subnet->getMetadata());
455
456 info_list->add(subnet_element);
457 msg << "found.";
458 } else {
460 msg << "not found.";
461 }
462 info->set("count", data::Element::create(subnet ? 1 : 0));
463
464 // Configuration backend didn't complain so let's return the success status.
465 data::ConstElementPtr response =
466 config::createAnswer(rcode, msg.str(), info);
467 callout_handle.setArgument("response", response);
468 }
469
479};
480
487public:
488
491
501 template <typename FunType>
503 const data::SimpleKeywords& keywords,
504 const data::SimpleKeywords& list_keywords,
505 const uint16_t address_family,
506 FunType create_update_fun) {
507 try {
508 // Parse the command and store the data in the stamped_values object.
509 data::StampedValueCollection stamped_values;
510 db::BackendSelector backend_selector;
512 parser_->parseInputMapElement
514 (callout_handle, "parameters", keywords, list_keywords,
515 stamped_values, backend_selector, server_selector,
517
518 // We allow exactly one server tag for the global parameter setting.
519 if (server_selector.getTags().size() != 1) {
521 "'server-tags' list must contain exactly one"
522 " server tag for the 'remote-global-parameter"
523 << (address_family == AF_INET ? "4" : "6") << "-set'"
524 " command");
525 }
526
527 uint64_t count = 0;
528 for (auto const& stamped_value : stamped_values) {
529 // Pass the received global parameter into the configuration backend.
530 create_update_fun(backend_selector, server_selector, stamped_value);
531 ++count;
532 }
533
534 // Build response.
536 for (auto const& stamped_value : stamped_values) {
537 std::string param_name;
538 std::string sub_param_name;
539 if (isc::dhcp::CBControlDHCP<bool>::translateName(stamped_value->getName(),
540 param_name, sub_param_name)) {
541 data::ElementPtr sub_param = boost::const_pointer_cast<data::Element>(parameters->get(param_name));
542 if (!sub_param) {
543 sub_param = data::Element::createMap();
544 parameters->set(param_name, sub_param);
545 }
546 sub_param->set(sub_param_name, stamped_value->getElementValue());
547 } else {
548 // Reuse name and value.
549 parameters->set(param_name, stamped_value->getElementValue());
550 }
551 }
552 data::ElementPtr response_arguments = data::Element::createMap();
553 response_arguments->set("parameters", parameters);
554 response_arguments->set("count",
555 data::Element::create(static_cast<long int>(count)));
556
557 // Configuration backend didn't complain so let's return the success status.
558 std::ostringstream msg;
559 msg << count << (address_family == AF_INET ? " DHCPv4" : " DHCPv6")
560 << " global parameter(s) successfully set.";
561 data::ConstElementPtr response =
563 msg.str(), response_arguments);
564 callout_handle.setArgument("response", response);
565
566 } catch (const std::exception& ex) {
567 // Something went wrong. Return an error response to the client.
568 data::ConstElementPtr response =
570 callout_handle.setArgument("response", response);
571 }
572 }
573
582 template <typename FunType>
584 const data::SimpleKeywords& keywords,
585 const uint16_t address_family,
586 FunType delete_fun) {
587 try {
588 std::string name;
589 db::BackendSelector backend_selector;
591 parser_->parseInputListElement
593 (callout_handle, "parameters", keywords, name,
594 backend_selector, server_selector,
597
598 // We allow exactly one server tag for the global parameter deleting..
599 if (server_selector.getTags().size() != 1) {
601 "'server-tags' list must contain exactly one"
602 " server tag for the 'remote-global-parameter"
603 << (address_family == AF_INET ? "4" : "6") << "-del'"
604 " command");
605 }
606
607 // Pass the received global parameter into the configuration backend.
608 uint64_t count = delete_fun(backend_selector, server_selector, name);
609
610 data::ElementPtr response_arguments = data::Element::createMap();
611 response_arguments->set("count",
612 data::Element::create(static_cast<long int>(count)));
613
614 // Configuration backend didn't complain so let's return the success status.
615 std::ostringstream msg;
616 msg << count << (address_family == AF_INET ? " DHCPv4" : " DHCPv6")
617 << " global parameter(s) deleted.";
618 int rcode =
620 data::ConstElementPtr response =
621 config::createAnswer(rcode, msg.str(), response_arguments);
622 callout_handle.setArgument("response", response);
623
624 } catch (const std::exception& ex) {
625 // Something went wrong. Return an error response to the client.
626 data::ConstElementPtr response =
628 callout_handle.setArgument("response", response);
629 }
630 }
631
640 template <typename FunType>
642 const data::SimpleKeywords& keywords,
643 const uint16_t address_family,
644 FunType get_fun) {
645 try {
646 std::string name;
647 db::BackendSelector backend_selector;
649 parser_->parseInputListElement
651 (callout_handle, "parameters", keywords, name,
652 backend_selector, server_selector,
655
656 // We allow exactly one server tag for the global parameter getting.
657 if (server_selector.getTags().size() != 1) {
659 "'server-tags' list must contain exactly one"
660 " server tag for the 'remote-global-parameter"
661 << (address_family == AF_INET ? "4" : "6") << "-get'"
662 " command");
663 }
664
665 // Get the global parameter from the configuration backend.
667 get_fun(backend_selector, server_selector, name);
668
669 int rcode;
670 std::ostringstream msg;
671 msg << "'" << name;
672 if (address_family == AF_INET) {
673 msg << "' DHCPv4";
674 } else {
675 msg << "' DHCPv6";
676 }
677 msg << " global parameter ";
680 info->set("parameters", info_map);
681 if (value) {
683 data::ConstElementPtr info_value = value->getElementValue();
684 if (!info_value) {
686 "StampedValue: attempt to get null value of the '"
687 << value->getName() << "' parameter");
688 }
689 auto const it = keywords.find(value->getName());
690 if (it == keywords.end()) {
691 isc_throw(BadValue, "unknown parameter '" << value->getName() << "'");
692 }
693 if (it->second == data::Element::list) {
694 info_value = data::Element::fromJSON(info_value->stringValue());
695 }
696 std::string param_name;
697 std::string sub_param_name;
699 param_name, sub_param_name)) {
701 sub_param->set(sub_param_name, info_value);
702 info_map->set(param_name, sub_param);
703 } else {
704 info_map->set(param_name, info_value);
705 }
706 info_map->set("metadata", value->getMetadata());
707 msg << "found.";
708 } else {
710 msg << "not found.";
711 }
712 info->set("count", data::Element::create(value ? 1 : 0));
713
714 // Configuration backend didn't complain so let's return the success status.
715
716 data::ConstElementPtr response =
717 config::createAnswer(rcode, msg.str(), info);
718 callout_handle.setArgument("response", response);
719
720 } catch (const std::exception& ex) {
721 // Something went wrong. Return an error response to the client.
722 data::ConstElementPtr response =
724 callout_handle.setArgument("response", response);
725 }
726 }
727
736 template <typename FunType>
738 const data::SimpleKeywords& keywords,
739 const uint16_t address_family,
740 FunType get_all_fun) {
741 try {
742 // Retrieve the command from the callout handle.
743 data::ConstElementPtr command;
744 callout_handle.getArgument("command", command);
745
746 // Get arguments.
748 static_cast<void>(config::parseCommandWithArgs(args, command));
749
750 // Create backend and server selectors from the received arguments.
751 // If the arguments do not include "remote" parameter, the default
752 // (unspecified) backend selector is created.
753 db::BackendSelector backend_selector;
754 backend_selector = parser_->getBackendSelector(args);
755
756 // The arguments must include "server-tags" parameter.
758 server_selector = parser_->getServerSelector(args,
760
761 // We allow exactly one server tag for the global parameter listing.
762 if (server_selector.getTags().size() != 1) {
764 "'server-tags' list must contain exactly one"
765 " server tag for the 'remote-global-parameter"
766 << (address_family == AF_INET ? "4" : "6") << "-get-all'"
767 " command");
768 }
769
770 // Get global parameters from the configuration backend.
772 get_all_fun(backend_selector, server_selector);
773
774 // Build response.
777 info->set("parameters", info_list);
778 for (auto const& value : values) {
779 data::ConstElementPtr info_value = value->getElementValue();
780 if (!info_value) {
782 "StampedValue: attempt to get null value of the '"
783 << value->getName() << "' parameter");
784 }
785 auto const it = keywords.find(value->getName());
786 if (it == keywords.end()) {
787 isc_throw(BadValue, "unknown parameter '" << value->getName() << "'");
788 }
789 if (it->second == data::Element::list) {
790 info_value = data::Element::fromJSON(info_value->stringValue());
791 }
793 std::string param_name;
794 std::string sub_param_name;
796 param_name, sub_param_name)) {
798 sub_param->set(sub_param_name, info_value);
799 param->set(param_name, sub_param);
800 } else {
801 param->set(param_name, info_value);
802 }
803 param->set("metadata", value->getMetadata());
804 info_list->add(param);
805 }
806 info->set("count",
807 data::Element::create(static_cast<long int>(values.size())));
808
809 // Configuration backend didn't complain so let's return the success status.
810
811 std::ostringstream msg;
812 msg << values.size()
813 << (address_family == AF_INET ? " DHCPv4" : " DHCPv6")
814 << " global parameter(s) found.";
815 int rcode =
817 data::ConstElementPtr response =
818 config::createAnswer(rcode, msg.str(), info);
819 callout_handle.setArgument("response", response);
820
821 } catch (const std::exception& ex) {
822 // Something went wrong. Return an error response to the client.
823 data::ConstElementPtr response =
825 callout_handle.setArgument("response", response);
826 }
827 }
828
839 template <typename SubnetPtrType, typename SubnetConfigParser, typename FunType>
840 void setSubnet(hooks::CalloutHandle& callout_handle,
841 const uint16_t address_family,
842 FunType create_update_fun) {
843 try {
844 // Parse the command and store the subnet data in the subnet object.
845 SubnetPtrType subnet;
846 db::BackendSelector backend_selector;
848 parser_->parseInputListElement<SubnetConfigParser, db::BackendSelector&,
850 (callout_handle, "subnets", backend_selector, server_selector,
851 subnet, backend_selector, server_selector,
853
854 // We allow one or more server tags for the subnet setting.
855 if (server_selector.hasNoTags()) {
857 "'server-tags' list must contain one or more"
858 " server tags for the 'remote-subnet"
859 << (address_family == AF_INET ? "4" : "6") << "-set'"
860 " command");
861 }
862
863 // Pass the received subnet into the configuration backend.
864 create_update_fun(backend_selector, server_selector, subnet);
865
866 // The response contains subnet prefix and subnet id.
868 subnet_info->set("id",
869 data::Element::create(static_cast<long int>(subnet->getID())));
870 subnet_info->set("subnet",
871 data::Element::create(subnet->toText()));
872
873 // The subnet information is encapsulated in a single element list.
875 subnets_list->add(subnet_info);
876
877 data::ElementPtr response_arguments = data::Element::createMap();
878 response_arguments->set("subnets", subnets_list);
879
880 // Configuration backend didn't complain so let's return the success status.
881 std::ostringstream msg;
882 msg << (address_family == AF_INET ? "IPv4" : "IPv6")
883 << " subnet successfully set.";
884 data::ConstElementPtr response =
886 msg.str(), response_arguments);
887 callout_handle.setArgument("response", response);
888
889 } catch (const std::exception& ex) {
890 // Something went wrong. Return an error response to the client.
891 data::ConstElementPtr response =
893 callout_handle.setArgument("response", response);
894 }
895 }
896
904 template <typename FunType>
905 void delSubnetId(hooks::CalloutHandle& callout_handle,
906 const uint16_t address_family,
907 FunType delete_fun) {
908 try {
909 dhcp::SubnetID subnet_id;
910 db::BackendSelector backend_selector;
912 parser_->parseInputListElement<CBSubnetIdParser>
913 (callout_handle, "subnets", subnet_id, backend_selector,
915
916 // Pass the received subnet into the configuration backend.
917 uint64_t count =
918 delete_fun(backend_selector, server_selector, subnet_id);
919
920 data::ElementPtr response_arguments = data::Element::createMap();
921 response_arguments->set("count",
922 data::Element::create(static_cast<long int>(count)));
923
924 // Configuration backend didn't complain so let's return the success status.
925 std::ostringstream msg;
926 msg << count << (address_family == AF_INET ? " IPv4" : " IPv6")
927 << " subnet(s) deleted.";
928 int rcode =
930 data::ConstElementPtr response =
931 config::createAnswer(rcode, msg.str(), response_arguments);
932 callout_handle.setArgument("response", response);
933
934 } catch (const std::exception& ex) {
935 // Something went wrong. Return an error response to the client.
936 data::ConstElementPtr response =
938 callout_handle.setArgument("response", response);
939 }
940 }
941
949 template <typename FunType>
951 const uint16_t address_family,
952 FunType delete_fun) {
953 try {
954 std::string prefix;
955 db::BackendSelector backend_selector;
957 parser_->parseInputListElement
958 <CBSubnetPrefixParser, uint16_t>
959 (callout_handle, "subnets", address_family,
960 prefix, backend_selector, server_selector,
962
963 // Pass the received subnet into the configuration backend.
964 uint64_t count =
965 delete_fun(backend_selector, server_selector, prefix);
966
967 data::ElementPtr response_arguments = data::Element::createMap();
968 response_arguments->set("count",
969 data::Element::create(static_cast<long int>(count)));
970
971 // Configuration backend didn't complain so let's return the success status.
972 std::ostringstream msg;
973 msg << count << (address_family == AF_INET ? " IPv4" : " IPv6")
974 << " subnet(s) deleted.";
975 int rcode =
977 data::ConstElementPtr response =
978 config::createAnswer(rcode, msg.str(), response_arguments);
979 callout_handle.setArgument("response", response);
980
981 } catch (const std::exception& ex) {
982 // Something went wrong. Return an error response to the client.
983 data::ConstElementPtr response =
985 callout_handle.setArgument("response", response);
986 }
987 }
988
998 template <typename SubnetPtrType, typename FunType>
999 void getSubnetId(hooks::CalloutHandle& callout_handle,
1000 const uint16_t address_family,
1001 FunType get_fun) {
1002 try {
1003 dhcp::SubnetID subnet_id;
1004 db::BackendSelector backend_selector;
1006 parser_->parseInputListElement<CBSubnetIdParser>
1007 (callout_handle, "subnets", subnet_id, backend_selector,
1009
1010 // Get the subnet from the configuration backend.
1011 SubnetPtrType subnet =
1012 get_fun(backend_selector, server_selector, subnet_id);
1013
1014 // Invoke common routine to prepare the appropriate response.
1015 parser_->getSubnetCommon(callout_handle, subnet, address_family, subnet_id);
1016
1017 } catch (const std::exception& ex) {
1018 // Something went wrong. Return an error response to the client.
1019 data::ConstElementPtr response =
1021 callout_handle.setArgument("response", response);
1022 }
1023 }
1024
1034 template <typename SubnetPtrType, typename FunType>
1036 const uint16_t address_family,
1037 FunType get_fun) {
1038 try {
1039 std::string prefix;
1040 db::BackendSelector backend_selector;
1042 parser_->parseInputListElement
1043 <CBSubnetPrefixParser, uint16_t>
1044 (callout_handle, "subnets", address_family,
1045 prefix, backend_selector, server_selector,
1047
1048 // Get the subnet from the configuration backend.
1049 SubnetPtrType subnet =
1050 get_fun(backend_selector, server_selector, prefix);
1051
1052 // Invoke common routine to prepare the appropriate response.
1053 parser_->getSubnetCommon(callout_handle, subnet,
1054 address_family, prefix);
1055
1056 } catch (const std::exception& ex) {
1057 // Something went wrong. Return an error response to the client.
1058 data::ConstElementPtr response =
1060 callout_handle.setArgument("response", response);
1061 }
1062 }
1063
1072 template <typename SubnetCollection, typename FunType>
1073 void listSubnets(hooks::CalloutHandle& callout_handle,
1074 const uint16_t address_family,
1075 FunType get_all_fun) {
1076 try {
1077 // Retrieve the command from the callout handle.
1078 data::ConstElementPtr command;
1079 callout_handle.getArgument("command", command);
1080
1081 // Get arguments.
1083 static_cast<void>(config::parseCommandWithArgs(args, command));
1084
1085 // Create backend selector from the received arguments.
1086 // If the arguments do not include "remote" parameter,
1087 // the default (unspecified) backend selector is created.
1088 db::BackendSelector backend_selector;
1089 backend_selector = parser_->getBackendSelector(args);
1090
1091 // The arguments must include "server-tags" parameter.
1093 server_selector = parser_->getServerSelector(args,
1095
1096 // Get the subnet list from the configuration backend.
1097 SubnetCollection subnets =
1098 get_all_fun(backend_selector, server_selector);
1099
1100 // Build response.
1103 info->set("subnets", info_list);
1104 for (auto const& subnet : subnets) {
1106 subnet_info->set("id",
1107 data::Element::create(static_cast<long int>(subnet->getID())));
1108 subnet_info->set("subnet",
1109 data::Element::create(subnet->toText()));
1110
1111 // Shared network name.
1112 std::string sn_name = subnet->getSharedNetworkName();
1113 if (!sn_name.empty()) {
1114 subnet_info->set("shared-network-name",
1115 data::Element::create(sn_name));
1116 } else {
1117 // Shared network name is null.
1118 subnet_info->set("shared-network-name",
1120 }
1121
1122 // Include metadata.
1123 subnet_info->set("metadata", subnet->getMetadata());
1124
1125 info_list->add(subnet_info);
1126 }
1127 info->set("count",
1128 data::Element::create(static_cast<long int>(subnets.size())));
1129
1130 // Configuration backend didn't complain so let's return the success status.
1131 std::ostringstream msg;
1132 msg << subnets.size()
1133 << (address_family == AF_INET ? " IPv4" : " IPv6")
1134 << " subnet(s) found.";
1135 int rcode =
1137 data::ConstElementPtr response =
1138 config::createAnswer(rcode, msg.str(), info);
1139 callout_handle.setArgument("response", response);
1140
1141 } catch (const std::exception& ex) {
1142 // Something went wrong. Return an error response to the client.
1143 data::ConstElementPtr response =
1145 callout_handle.setArgument("response", response);
1146 }
1147 }
1148
1159 template <typename SharedNetworkPtrType, typename SharedNetworkParser, typename FunType>
1161 const uint16_t address_family,
1162 FunType create_update_fun) {
1163 try {
1164 // Parse the command and store the shared network data in
1165 // the shared_network object.
1166 SharedNetworkPtrType shared_network;
1167 db::BackendSelector backend_selector;
1169 parser_->parseInputListElement<SharedNetworkParser, db::BackendSelector&,
1171 (callout_handle, "shared-networks", backend_selector, server_selector,
1172 shared_network, backend_selector,
1174
1175 // We allow one or more server tags for the shared network setting.
1176 if (server_selector.hasNoTags()) {
1178 "'server-tags' list must contain one or more"
1179 " server tags for the 'remote-network"
1180 << (address_family == AF_INET ? "4" : "6") << "-set'"
1181 " command");
1182 }
1183
1184 // Pass the received shared network into the configuration backend.
1185 create_update_fun(backend_selector, server_selector, shared_network);
1186
1187 // The response contains a network name.
1189 network_info->set("name",
1190 data::Element::create(shared_network->getName()));
1191
1192 // The network information is encapsulated in a single element list.
1194 response_list->add(network_info);
1195
1196 data::ElementPtr response_arguments = data::Element::createMap();
1197 response_arguments->set("shared-networks", response_list);
1198
1199 // Configuration backend didn't complain so let's return the success status.
1200 std::ostringstream msg;
1201 msg << (address_family == AF_INET ? "IPv4" : "IPv6");
1202 msg << " shared network successfully set.";
1203 data::ConstElementPtr response =
1205 msg.str(), response_arguments);
1206 callout_handle.setArgument("response", response);
1207
1208 } catch (const std::exception& ex) {
1209 // Something went wrong. Return an error response to the client.
1210 data::ConstElementPtr response =
1212 callout_handle.setArgument("response", response);
1213 }
1214 }
1215
1224 template <typename FunType, typename FunType2>
1226 const uint16_t address_family,
1227 FunType delete_fun, FunType2 delete_all_fun) {
1228 try {
1229 // Retrieve the command from the callout handle.
1230 data::ConstElementPtr command;
1231 callout_handle.getArgument("command", command);
1232
1233 // Get optional arguments.
1235
1236 // Create subnets action from the received arguments.
1237 // If the arguments do not include "subnets-action" parameter,
1238 // the default (keep) action is created.
1239 static_cast<void>(config::parseCommandWithArgs(args, command));
1240 auto subnets_action = parser_->getSubnetsAction(args);
1241
1242 std::string name;
1243 db::BackendSelector backend_selector;
1245 parser_->parseInputListElement<CBSharedNetworkNameParser>
1246 (callout_handle, "shared-networks", name, backend_selector,
1248
1249 // Delete subnets when wanted.
1250 if (subnets_action == ConfigCmdsParser::SubnetsAction::ACTION_DELETE) {
1251 delete_all_fun(backend_selector, server_selector, name);
1252 }
1253
1254 // Pass the received shared network into the configuration backend.
1255 uint64_t count = delete_fun(backend_selector, server_selector, name);
1256
1257 data::ElementPtr response_arguments = data::Element::createMap();
1258 response_arguments->set("count",
1259 data::Element::create(static_cast<long int>(count)));
1260
1261 // Configuration backend didn't complain so let's return the success status.
1262 std::ostringstream msg;
1263 msg << count << (address_family == AF_INET ? " IPv4" : " IPv6");
1264 msg << " shared network(s) deleted.";
1265 int rcode =
1267 data::ConstElementPtr response =
1268 config::createAnswer(rcode, msg.str(), response_arguments);
1269 callout_handle.setArgument("response", response);
1270
1271 } catch (const std::exception& ex) {
1272 // Something went wrong. Return an error response to the client.
1273 data::ConstElementPtr response =
1275 callout_handle.setArgument("response", response);
1276 }
1277 }
1278
1291 template <typename SharedNetworkPtrType, typename SubnetCollection,
1292 typename FunType, typename FunType2>
1294 const uint16_t address_family,
1295 FunType get_fun, FunType2 get_all) {
1296 try {
1297 std::string name;
1298 db::BackendSelector backend_selector;
1300 auto args =
1301 parser_->parseInputListElement<CBSharedNetworkNameParser>
1302 (callout_handle, "shared-networks", name, backend_selector,
1304
1305 // Get the flag which denotes whether we should include subnets
1306 // in the response or not.
1307 auto subnets_include = parser_->getSubnetsInclude(args);
1308
1309 // Get the shared network from the configuration backend.
1310 SharedNetworkPtrType network =
1311 get_fun(backend_selector, server_selector, name);
1312
1313 // Get all subnets belonging to the shared network
1314 // when none was returned from the database.
1315 if ((subnets_include == ConfigCmdsParser::SubnetsInclude::INCLUDE_FULL) &&
1316 network && network->getAllSubnets()->empty()) {
1317 SubnetCollection subnets =
1318 get_all(backend_selector, server_selector, name);
1319 for (auto const& subnet : subnets) {
1320 network->add(subnet);
1321 }
1322 }
1323
1324 int rcode;
1327 info->set("shared-networks", info_list);;
1328 std::ostringstream msg;
1329 msg << (address_family == AF_INET ? "IPv4" : "IPv6");
1330 msg << " shared network '" << name << "' ";
1331 if (network) {
1333
1334 // If we're not supposed to include subnets in the response,
1335 // remove them. In case the backend returned them.
1336 data::ElementPtr network_element = network->toElement();
1337 if (subnets_include == ConfigCmdsParser::SubnetsInclude::INCLUDE_NO) {
1338 if (address_family == AF_INET) {
1339 network_element->remove("subnet4");
1340 } else {
1341 network_element->remove("subnet6");
1342 }
1343 }
1344
1345 // Include metadata.
1346 network_element->set("metadata", network->getMetadata());
1347
1348 info_list->add(network_element);
1349 msg << "found.";
1350 } else {
1352 msg << "not found.";
1353 }
1354 info->set("count", data::Element::create(network ? 1 : 0));
1355
1356 // Configuration backend didn't complain so let's return the success status.
1357 data::ConstElementPtr response =
1358 config::createAnswer(rcode, msg.str(), info);
1359 callout_handle.setArgument("response", response);
1360
1361 } catch (const std::exception& ex) {
1362 // Something went wrong. Return an error response to the client.
1363 data::ConstElementPtr response =
1365 callout_handle.setArgument("response", response);
1366 }
1367 }
1368
1378 template <typename SharedNetworkCollection, typename FunType>
1380 const uint16_t address_family,
1381 FunType get_all) {
1382 try {
1383 // Retrieve the command from the callout handle.
1384 data::ConstElementPtr command;
1385 callout_handle.getArgument("command", command);
1386
1387 // Expect that the command include arguments.
1389 static_cast<void>(config::parseCommandWithArgs(args, command));
1390
1391 // Create backend selector from the received arguments.
1392 // If the arguments do not include "remote" parameter,
1393 // the default (unspecified) backend selector is created.
1394 db::BackendSelector backend_selector;
1395 backend_selector = parser_->getBackendSelector(args);
1396
1397 // The arguments must include "server-tags" parameter.
1399 server_selector = parser_->getServerSelector(args,
1401
1402 // Get shared networks from the configuration backend.
1403 SharedNetworkCollection networks =
1404 get_all(backend_selector, server_selector);
1405
1406 // Build response.
1409 info->set("shared-networks", info_list);
1410 for (auto const& network : networks) {
1412 network_map->set("name",
1413 data::Element::create(network->getName()));
1414 network_map->set("metadata", network->getMetadata());
1415 info_list->add(network_map);
1416 }
1417 info->set("count",
1418 data::Element::create(static_cast<long int>(networks.size())));
1419
1420 // Configuration backend didn't complain so let's return the success status.
1421
1422 std::ostringstream msg;
1423 msg << networks.size();
1424 msg << (address_family == AF_INET ? " IPv4" : " IPv6");
1425 msg << " shared network(s) found.";
1426 int rcode =
1428 data::ConstElementPtr response =
1429 config::createAnswer(rcode, msg.str(), info);
1430 callout_handle.setArgument("response", response);
1431
1432 } catch (const std::exception& ex) {
1433 // Something went wrong. Return an error response to the client.
1434 data::ConstElementPtr response =
1436 callout_handle.setArgument("response", response);
1437 }
1438 }
1439
1446 template <typename FunType>
1448 const uint16_t address_family,
1449 FunType create_update_fun) {
1450 try {
1451 std::pair<dhcp::ClientClassDefPtr, std::string> class_pair;
1452 db::BackendSelector backend_selector;
1454 parser_->parseInputListElement<CBClientClassParser, uint16_t, dhcp::CfgOptionDefPtr,
1456 (callout_handle, "client-classes", address_family, CfgOptionDefPtr(),
1457 backend_selector, server_selector,
1458 class_pair, backend_selector, server_selector,
1460
1461 // We allow one or more server tags for the client class setting.
1462 if (server_selector.hasNoTags()) {
1464 "'server-tags' list must contain one or more"
1465 " server tags for the 'remote-class"
1466 << (address_family == AF_INET ? "4" : "6") << "-set'"
1467 " command");
1468 }
1469
1470 // Pass the received shared network into the configuration backend.
1471 create_update_fun(backend_selector, server_selector, class_pair.first,
1472 class_pair.second);
1473
1474 // The response contains a network name.
1475 data::ElementPtr client_class_info = data::Element::createMap();
1476 client_class_info->set("name",
1477 data::Element::create(class_pair.first->getName()));
1478
1479 // The client class information is encapsulated in a single element list.
1481 response_list->add(client_class_info);
1482
1483 data::ElementPtr response_arguments = data::Element::createMap();
1484 response_arguments->set("client-classes", response_list);
1485
1486 // Configuration backend didn't complain so let's return the success status.
1487 std::ostringstream msg;
1488 msg << (address_family == AF_INET ? "DHCPv4" : "DHCPv6");
1489 msg << " client class successfully set.";
1490 data::ConstElementPtr response =
1492 msg.str(), response_arguments);
1493 callout_handle.setArgument("response", response);
1494
1495 } catch (const std::exception& ex) {
1496 // Something went wrong. Return an error response to the client.
1497 data::ConstElementPtr response =
1499 callout_handle.setArgument("response", response);
1500 }
1501 }
1502
1509 template <typename FunType>
1511 const uint16_t address_family,
1512 FunType delete_fun) {
1513 try {
1514 // Retrieve the command from the callout handle.
1515 data::ConstElementPtr command;
1516 callout_handle.getArgument("command", command);
1517
1518 std::string name;
1519 db::BackendSelector backend_selector;
1521 parser_->parseInputListElement<CBClientClassNameParser>
1522 (callout_handle, "client-classes", name, backend_selector,
1524
1525 // Pass the received client class into the configuration backend.
1526 uint64_t count = delete_fun(backend_selector, server_selector, name);
1527
1528 data::ElementPtr response_arguments = data::Element::createMap();
1529 response_arguments->set("count",
1530 data::Element::create(static_cast<long int>(count)));
1531
1532 // Configuration backend didn't complain so let's return the success status.
1533 std::ostringstream msg;
1534 msg << count << (address_family == AF_INET ? " DHCPv4" : " DHCPv6");
1535 msg << " client class(es) deleted.";
1536 int rcode =
1538 data::ConstElementPtr response =
1539 config::createAnswer(rcode, msg.str(), response_arguments);
1540 callout_handle.setArgument("response", response);
1541
1542 } catch (const std::exception& ex) {
1543 // Something went wrong. Return an error response to the client.
1544 data::ConstElementPtr response =
1546 callout_handle.setArgument("response", response);
1547 }
1548 }
1549
1556 template <typename FunType>
1558 const uint16_t address_family,
1559 FunType get_fun) {
1560 try {
1561 std::string name;
1562 db::BackendSelector backend_selector;
1564 auto args =
1565 parser_->parseInputListElement<CBClientClassNameParser>
1566 (callout_handle, "client-classes", name, backend_selector,
1568
1569 // Get the client class from the configuration backend.
1570 ClientClassDefPtr client_class = get_fun(backend_selector, server_selector, name);
1571
1572 int rcode;
1575 info->set("client-classes", info_list);;
1576 std::ostringstream msg;
1577 msg << (address_family == AF_INET ? "DHCPv4" : "DHCPv6");
1578 msg << " client class '" << name << "' ";
1579 if (client_class) {
1581
1582 data::ElementPtr client_class_element = client_class->toElement();
1583
1584 // Include metadata.
1585 client_class_element->set("metadata", client_class->getMetadata());
1586
1587 info_list->add(client_class_element);
1588 msg << "found.";
1589 } else {
1591 msg << "not found.";
1592 }
1593 info->set("count", data::Element::create(client_class ? 1 : 0));
1594
1595 // Configuration backend didn't complain so let's return the success status.
1596 data::ConstElementPtr response =
1597 config::createAnswer(rcode, msg.str(), info);
1598 callout_handle.setArgument("response", response);
1599
1600 } catch (const std::exception& ex) {
1601 // Something went wrong. Return an error response to the client.
1602 data::ConstElementPtr response =
1604 callout_handle.setArgument("response", response);
1605 }
1606 }
1607
1614 template <typename FunType>
1616 const uint16_t address_family,
1617 FunType get_all) {
1618 try {
1619 // Retrieve the command from the callout handle.
1620 data::ConstElementPtr command;
1621 callout_handle.getArgument("command", command);
1622
1623 // Expect that the command includes arguments.
1625 static_cast<void>(config::parseCommandWithArgs(args, command));
1626
1627 // Create backend selector from the received arguments.
1628 // If the arguments do not include "remote" parameter,
1629 // the default (unspecified) backend selector is created.
1630 db::BackendSelector backend_selector;
1631 backend_selector = parser_->getBackendSelector(args);
1632
1633 // The arguments must include "server-tags" parameter.
1635 server_selector = parser_->getServerSelector(args,
1637
1638 // Get client classes from the configuration backend.
1639 ClientClassDictionary client_classes = get_all(backend_selector, server_selector);
1640
1641 // Build response.
1644 info->set("client-classes", info_list);
1645 for (auto const& client_class : *client_classes.getClasses()) {
1646 data::ElementPtr client_class_map = client_class->toElement();
1647 client_class_map->set("metadata", client_class->getMetadata());
1648 info_list->add(client_class_map);
1649 }
1650 info->set("count",
1651 data::Element::create(static_cast<long int>(client_classes.getClasses()->size())));
1652
1653 // Configuration backend didn't complain so let's return the success status.
1654
1655 std::ostringstream msg;
1656 msg << client_classes.getClasses()->size();
1657 msg << (address_family == AF_INET ? " DHCPv4" : " DHCPv6");
1658 msg << " client class(es) found.";
1659 int rcode =
1661 data::ConstElementPtr response =
1662 config::createAnswer(rcode, msg.str(), info);
1663 callout_handle.setArgument("response", response);
1664
1665 } catch (const std::exception& ex) {
1666 // Something went wrong. Return an error response to the client.
1667 data::ConstElementPtr response =
1669 callout_handle.setArgument("response", response);
1670 }
1671 }
1672
1679 template <typename FunType>
1681 const uint16_t address_family,
1682 FunType create_update_fun) {
1683 try {
1684 // Parse the command and store the option definition data
1685 // in the option_def object.
1686 dhcp::OptionDefinitionPtr option_def;
1687 db::BackendSelector backend_selector;
1689 parser_->parseInputListElement<CBOptionDefParser, uint16_t>
1690 (callout_handle, "option-defs", address_family,
1691 option_def, backend_selector, server_selector,
1693
1694 // We allow exactly one server tag for the option definition setting.
1695 if (server_selector.getTags().size() != 1) {
1697 "'server-tags' list must contain exactly one"
1698 " server tag for the 'remote-option-def"
1699 << (address_family == AF_INET ? "4" : "6") << "-set'"
1700 " command");
1701 }
1702
1703 // Pass the received option definition into the configuration backend.
1704 create_update_fun(backend_selector, server_selector, option_def);
1705
1706 // The response contains option code, space, and client classes.
1707 auto option_def_info = makeOptionInfoElement(*option_def);
1708
1709 // The option definition information is encapsulated in a single element list.
1711 response_list->add(option_def_info);
1712
1713 data::ElementPtr response_arguments = data::Element::createMap();
1714 response_arguments->set("option-defs", response_list);
1715
1716 // Configuration backend didn't complain so let's return the success status.
1717 std::ostringstream msg;
1718 msg << (address_family == AF_INET ? "DHCPv4" : "DHCPv6")
1719 << " option definition successfully set.";
1720 data::ConstElementPtr response =
1722 msg.str(), response_arguments);
1723 callout_handle.setArgument("response", response);
1724
1725 } catch (const std::exception& ex) {
1726 // Something went wrong. Return an error response to the client.
1727 data::ConstElementPtr response =
1729 callout_handle.setArgument("response", response);
1730 }
1731 }
1732
1739 template <typename FunType>
1741 const uint16_t address_family,
1742 FunType delete_fun) {
1743 try {
1744 CBOptionDefDelete option_def_delete;
1745 db::BackendSelector backend_selector;
1747 parser_->parseInputListElement<CBOptionDefDeleteParser, uint16_t>
1748 (callout_handle, "option-defs", address_family,
1749 option_def_delete, backend_selector, server_selector,
1751
1752 // We allow exactly one server tag for the option definition deleting.
1753 if (server_selector.getTags().size() != 1) {
1755 "'server-tags' list must contain exactly one"
1756 " server tag for the 'remote-option-def"
1757 << (address_family == AF_INET ? "4" : "6") << "-del'"
1758 " command");
1759 }
1760
1761 // Pass the received option definition into the configuration backend.
1762 uint64_t count =
1763 delete_fun(backend_selector, server_selector,
1764 std::get<0>(option_def_delete),
1765 std::get<1>(option_def_delete),
1766 std::get<2>(option_def_delete));
1767
1768 data::ElementPtr response_arguments = data::Element::createMap();
1769 response_arguments->set("count",
1770 data::Element::create(static_cast<long int>(count)));
1771
1772 // Configuration backend didn't complain so let's return the success status.
1773 std::ostringstream msg;
1774 msg << count << (address_family == AF_INET ? " DHCPv4" : " DHCPv6")
1775 << " option definition(s) deleted.";
1776 int rcode =
1778 data::ConstElementPtr response =
1779 config::createAnswer(rcode, msg.str(), response_arguments);
1780 callout_handle.setArgument("response", response);
1781
1782 } catch (const std::exception& ex) {
1783 // Something went wrong. Return an error response to the client.
1784 data::ConstElementPtr response =
1786 callout_handle.setArgument("response", response);
1787 }
1788 }
1789
1796 template <typename FunType>
1798 const uint16_t address_family,
1799 FunType get_fun) {
1800 try {
1801 std::pair<uint16_t, std::string> option_def_pair;
1802 db::BackendSelector backend_selector;
1804 parser_->parseInputListElement<CBOptionPairParser, uint16_t>
1805 (callout_handle, "option-defs", address_family,
1806 option_def_pair, backend_selector, server_selector,
1808
1809 // We allow exactly one server tag for the option definition getting.
1810 if (server_selector.getTags().size() != 1) {
1812 "'server-tags' list must contain exactly one"
1813 " server tag for the 'remote-option-def"
1814 << (address_family == AF_INET ? "4" : "6") << "-get'"
1815 " command");
1816 }
1817
1818 // Get the option definition from the configuration backend.
1820 get_fun(backend_selector, server_selector,
1821 option_def_pair.first, option_def_pair.second);
1822
1823 int rcode;
1824 std::ostringstream msg;
1825 msg << (address_family == AF_INET ? "DHCPv4" : "DHCPv6")
1826 << " option definition " << option_def_pair.first
1827 << " in '" << option_def_pair.second << "' ";
1829 if (def) {
1832 defs->add(def);
1833 info->set("option-defs", defs->toElementWithMetadata(true));
1834 msg << "found.";
1835 } else {
1838 info->set("option-defs", info_list);
1839 msg << "not found.";
1840 }
1841 info->set("count", data::Element::create(def ? 1 : 0));
1842
1843 // Configuration backend didn't complain so let's return the success status.
1844 data::ConstElementPtr response =
1845 config::createAnswer(rcode, msg.str(), info);
1846 callout_handle.setArgument("response", response);
1847
1848 } catch (const std::exception& ex) {
1849 // Something went wrong. Return an error response to the client.
1850 data::ConstElementPtr response =
1852 callout_handle.setArgument("response", response);
1853 }
1854 }
1855
1862 template <typename FunType>
1864 const uint16_t address_family,
1865 FunType get_all_fun) {
1866 try {
1867 // Retrieve the command from the callout handle.
1868 data::ConstElementPtr command;
1869 callout_handle.getArgument("command", command);
1870
1871 // Get arguments.
1873 static_cast<void>(config::parseCommandWithArgs(args, command));
1874
1875 // Create backend selector from the received arguments.
1876 // If the arguments do not include "remote" parameter,
1877 // the default (unspecified) backend selector is created.
1878 db::BackendSelector backend_selector;
1879 backend_selector = parser_->getBackendSelector(args);
1880
1881 // The arguments must include "server-tags" parameter.
1883 server_selector = parser_->getServerSelector(args,
1885
1886 // We allow exactly one server tag for the option definition listing.
1887 if (server_selector.getTags().size() != 1) {
1889 "'server-tags' list must contain exactly one"
1890 " server tag for the 'remote-option-def"
1891 << (address_family == AF_INET ? "4" : "6") << "-get-all'"
1892 " command");
1893 }
1894
1895 // Get option definitions from the configuration backend.
1897 get_all_fun(backend_selector, server_selector);
1898
1899 // Build response.
1902 for (auto const& def : defs) {
1903 cfg_defs->add(def);
1904 }
1905 info->set("option-defs", cfg_defs->toElementWithMetadata(true));
1906 info->set("count",
1907 data::Element::create(static_cast<long int>(defs.size())));
1908
1909 // Configuration backend didn't complain so let's return the success status.
1910 std::ostringstream msg;
1911 msg << defs.size()
1912 << (address_family == AF_INET ? " DHCPv4" : " DHCPv6")
1913 << " option definition(s) found.";
1914 int rcode =
1916 data::ConstElementPtr response =
1917 config::createAnswer(rcode, msg.str(), info);
1918 callout_handle.setArgument("response", response);
1919
1920 } catch (const std::exception& ex) {
1921 // Something went wrong. Return an error response to the client.
1922 data::ConstElementPtr response =
1924 callout_handle.setArgument("response", response);
1925 }
1926 }
1927
1934 template <typename FunType>
1936 const uint16_t address_family,
1937 FunType create_update_fun) {
1938 try {
1939 // Parse the command and store the option data in
1940 // the option_pair object.
1941 std::pair<dhcp::OptionDescriptor, std::string> option_pair =
1942 std::make_pair(dhcp::OptionDescriptor(false, false), "");
1943 db::BackendSelector backend_selector;
1945 parser_->parseInputListElement
1948 (callout_handle, "options", address_family, CfgOptionDefPtr(),
1949 backend_selector, server_selector,
1950 option_pair, backend_selector, server_selector,
1952
1953 // We allow exactly one server tag for the option setting.
1954 if (server_selector.getTags().size() != 1) {
1956 "'server-tags' list must contain exactly one"
1957 " server tag for the 'remote-option"
1958 << (address_family == AF_INET ? "4" : "6")
1959 << "-global-set' command");
1960 }
1961
1962 auto option_descriptor = option_pair.first;
1963 option_descriptor.space_name_ = option_pair.second;
1964
1965 // Pass the received option into the configuration backend.
1966 create_update_fun(backend_selector, server_selector, option_descriptor);
1967
1968 // The response contains option code, space, and client classes.
1969 auto option_info = makeOptionInfoElement(option_descriptor);
1970
1971 // The option information is encapsulated in a single element list.
1973 response_list->add(option_info);
1974
1975 data::ElementPtr response_arguments = data::Element::createMap();
1976 response_arguments->set("options", response_list);
1977
1978 // Configuration backend didn't complain so let's return the success status.
1979 std::ostringstream msg;
1980 msg << (address_family == AF_INET ? "DHCPv4" : "DHCPv6")
1981 << " option successfully set.";
1982 data::ConstElementPtr response =
1984 msg.str(), response_arguments);
1985 callout_handle.setArgument("response", response);
1986
1987 } catch (const std::exception& ex) {
1988 // Something went wrong. Return an error response to the client.
1989 data::ConstElementPtr response =
1991 callout_handle.setArgument("response", response);
1992 }
1993 }
1994
2001 template <typename FunType>
2003 const uint16_t address_family,
2004 FunType delete_fun) {
2005 try {
2006 CBOptionTuple option_tuple;
2007 db::BackendSelector backend_selector;
2009 parser_->parseInputListElement<CBOptionTupleParser, uint16_t>
2010 (callout_handle, "options", address_family,
2011 option_tuple, backend_selector, server_selector,
2013
2014 // We allow exactly one server tag for the option deleting..
2015 if (server_selector.getTags().size() != 1) {
2017 "'server-tags' list must contain exactly one"
2018 " server tag for the 'remote-option"
2019 << (address_family == AF_INET ? "4" : "6")
2020 << "-global-del' command");
2021 }
2022
2023 // Pass the received option into the configuration backend.
2024 uint64_t count = delete_fun(backend_selector, server_selector,
2025 std::get<0>(option_tuple),
2026 std::get<1>(option_tuple),
2027 std::get<2>(option_tuple));
2028
2029 data::ElementPtr response_arguments = data::Element::createMap();
2030 response_arguments->set("count",
2031 data::Element::create(static_cast<long int>(count)));
2032
2033 // Configuration backend didn't complain so let's return the success status.
2034 std::ostringstream msg;
2035 msg << count << (address_family == AF_INET ? " DHCPv4" : " DHCPv6")
2036 << " option(s) deleted.";
2037 int rcode =
2039 data::ConstElementPtr response =
2040 config::createAnswer(rcode, msg.str(), response_arguments);
2041 callout_handle.setArgument("response", response);
2042
2043 } catch (const std::exception& ex) {
2044 // Something went wrong. Return an error response to the client.
2045 data::ConstElementPtr response =
2047 callout_handle.setArgument("response", response);
2048 }
2049 }
2050
2057 template <typename FunType>
2059 const uint16_t address_family,
2060 FunType get_fun) {
2061 try {
2062 CBOptionTuple option_tuple;
2063 db::BackendSelector backend_selector;
2065 parser_->parseInputListElement<CBOptionTupleParser, uint16_t>
2066 (callout_handle, "options", address_family,
2067 option_tuple, backend_selector, server_selector,
2069
2070 // We allow exactly one server tag for the option getting.
2071 if (server_selector.getTags().size() != 1) {
2073 "'server-tags' list must contain exactly one"
2074 " server tag for the 'remote-option"
2075 << (address_family == AF_INET ? "4" : "6")
2076 << "-global-get' command");
2077 }
2078
2079 // Get the option from the configuration backend.
2081 get_fun(backend_selector, server_selector,
2082 std::get<0>(option_tuple),
2083 std::get<1>(option_tuple),
2084 std::get<2>(option_tuple));
2085
2086 int rcode;
2087 std::ostringstream msg;
2088 msg << (address_family == AF_INET ? "DHCPv4" : "DHCPv6")
2089 << " option " << std::get<0>(option_tuple);
2090
2091 auto cclasses = std::get<2>(option_tuple);
2092 if (cclasses) {
2093 msg << " with client-classes = " << cclasses->toElement()->str();
2094 }
2095
2096 msg << " in '" << std::get<1>(option_tuple) << "' ";
2097
2099 if (option) {
2101 dhcp::CfgOptionPtr options(new dhcp::CfgOption());
2102 options->add(*option, std::get<1>(option_tuple));
2103 info->set("options", options->toElementWithMetadata(true));
2104 msg << "found.";
2105 } else {
2108 info->set("options", info_list);
2109 msg << "not found.";
2110 }
2111 info->set("count", data::Element::create(option ? 1 : 0));
2112
2113 // Configuration backend didn't complain so let's return the success status.
2114 data::ConstElementPtr response =
2115 config::createAnswer(rcode, msg.str(), info);
2116 callout_handle.setArgument("response", response);
2117
2118 } catch (const std::exception& ex) {
2119 // Something went wrong. Return an error response to the client.
2120 data::ConstElementPtr response =
2122 callout_handle.setArgument("response", response);
2123 }
2124 }
2125
2133 template <typename FunType>
2135 const uint16_t address_family,
2136 FunType get_all_fun) {
2137 try {
2138 // Retrieve the command from the callout handle.
2139 data::ConstElementPtr command;
2140 callout_handle.getArgument("command", command);
2141
2142 // Get arguments.
2144 static_cast<void>(config::parseCommandWithArgs(args, command));
2145
2146 // Create backend selector from the received arguments.
2147 // If the arguments do not include "remote" parameter,
2148 // the default (unspecified) backend selector is created.
2149 db::BackendSelector backend_selector;
2150 backend_selector = parser_->getBackendSelector(args);
2151
2152 // The arguments must include "server-tags" parameter.
2154 server_selector = parser_->getServerSelector(args,
2156
2157 // We allow exactly one server tag for the option listing.
2158 if (server_selector.getTags().size() != 1) {
2160 "'server-tags' list must contain exactly one"
2161 " server tag for the 'remote-option"
2162 << (address_family == AF_INET ? "4" : "6")
2163 << "-global-get-all' command");
2164 }
2165
2166 // Get options from the configuration backend.
2167 const dhcp::OptionContainer& options =
2168 get_all_fun(backend_selector, server_selector);
2169
2170 // Build response.
2172 dhcp::CfgOptionPtr cfg_options(new dhcp::CfgOption());
2173 for (auto const& option : options) {
2174 cfg_options->add(option, option.space_name_);
2175 }
2176 info->set("options", cfg_options->toElementWithMetadata(true));
2177 info->set("count",
2178 data::Element::create(static_cast<long int>(options.size())));
2179
2180 // Configuration backend didn't complain so let's return the success status.
2181 std::ostringstream msg;
2182 msg << options.size()
2183 << (address_family == AF_INET ? " DHCPv4" : " DHCPv6")
2184 << " option(s) found.";
2185 int rcode =
2187 data::ConstElementPtr response =
2188 config::createAnswer(rcode, msg.str(), info);
2189 callout_handle.setArgument("response", response);
2190
2191 } catch (const std::exception& ex) {
2192 // Something went wrong. Return an error response to the client.
2193 data::ConstElementPtr response =
2195 callout_handle.setArgument("response", response);
2196 }
2197 }
2198
2205 template <typename FunType>
2206 void setServer(hooks::CalloutHandle& callout_handle,
2207 const uint16_t address_family,
2208 FunType create_update_fun) {
2209 try {
2210 // Parse the command and store the server data in the server object.
2211 db::ServerPtr server;
2212 db::BackendSelector backend_selector;
2214 parser_->parseInputListElement<ServerConfigParser>
2215 (callout_handle, "servers", server,
2216 backend_selector, server_selector,
2218
2219 // Pass the received server into the configuration backend.
2220 create_update_fun(backend_selector, server);
2221
2222 // The server information is encapsulated in a single element list.
2224 response_list->add(server->toElement());
2225
2226 data::ElementPtr response_arguments = data::Element::createMap();
2227 response_arguments->set("servers", response_list);
2228
2229 // Configuration backend didn't complain so let's return the success status.
2230 std::ostringstream msg;
2231 msg << (address_family == AF_INET ? "DHCPv4" : "DHCPv6")
2232 << " server successfully set.";
2233 data::ConstElementPtr response =
2235 msg.str(), response_arguments);
2236 callout_handle.setArgument("response", response);
2237
2238 } catch (const std::exception& ex) {
2239 // Something went wrong. Return an error response to the client.
2240 data::ConstElementPtr response =
2242 callout_handle.setArgument("response", response);
2243 }
2244 }
2245
2252 template <typename FunType>
2253 void delServer(hooks::CalloutHandle& callout_handle,
2254 const uint16_t address_family,
2255 FunType delete_fun) {
2256 try {
2257 data::ServerTag server_tag;
2258 db::BackendSelector backend_selector;
2260 parser_->parseInputListElement<ServerTagParser>
2261 (callout_handle, "servers", server_tag,
2262 backend_selector, server_selector,
2264
2265 // Pass the received server tag into the configuration backend.
2266 uint64_t count = delete_fun(backend_selector, server_tag);
2267
2268 data::ElementPtr response_arguments = data::Element::createMap();
2269 response_arguments->set("count",
2270 data::Element::create(static_cast<long int>(count)));
2271
2272 // Configuration backend didn't complain so let's return the success status.
2273 std::ostringstream msg;
2274 msg << count << (address_family == AF_INET ? " DHCPv4" : " DHCPv6")
2275 << " server(s) deleted.";
2276 int rcode =
2278 data::ConstElementPtr response =
2279 config::createAnswer(rcode, msg.str(), response_arguments);
2280 callout_handle.setArgument("response", response);
2281
2282 } catch (const std::exception& ex) {
2283 // Something went wrong. Return an error response to the client.
2284 data::ConstElementPtr response =
2286 callout_handle.setArgument("response", response);
2287 }
2288 }
2289
2296 template <typename FunType>
2297 void getServer(hooks::CalloutHandle& callout_handle,
2298 const uint16_t address_family,
2299 FunType get_fun) {
2300 try {
2301 data::ServerTag server_tag;
2302 db::BackendSelector backend_selector;
2304 parser_->parseInputListElement<ServerTagParser>
2305 (callout_handle, "servers", server_tag,
2306 backend_selector, server_selector,
2308
2309 // Get the server from the configuration backend.
2310 db::ServerPtr server = get_fun(backend_selector, server_tag);
2311
2312 int rcode;
2313 std::ostringstream msg;
2314 msg << (address_family == AF_INET ? "DHCPv4" : "DHCPv6")
2315 << " server '" << server_tag.get() << "' ";
2318 info->set("servers", info_list);
2319 if (server) {
2321 msg << "found.";
2322
2323 info_list->add(server->toElement());
2324 } else {
2326 msg << "not found.";
2327 }
2328 info->set("count", data::Element::create(server ? 1 : 0));
2329
2330 // Configuration backend didn't complain so let's return the success status.
2331 data::ConstElementPtr response =
2332 config::createAnswer(rcode, msg.str(), info);
2333 callout_handle.setArgument("response", response);
2334
2335 } catch (const std::exception& ex) {
2336 // Something went wrong. Return an error response to the client.
2337 data::ConstElementPtr response =
2339 callout_handle.setArgument("response", response);
2340 }
2341 }
2342
2350 template <typename FunType>
2352 const uint16_t address_family,
2353 FunType get_all_fun) {
2354 try {
2355 // Retrieve the command from the callout handle.
2356 data::ConstElementPtr command;
2357 callout_handle.getArgument("command", command);
2358
2359 // Get arguments.
2361 static_cast<void>(config::parseCommand(args, command));
2362
2363 // Create backend selector from the received arguments.
2364 // If the arguments do not include "remote" parameter,
2365 // the default (unspecified) backend selector is created.
2366 db::BackendSelector backend_selector;
2367 if (args) {
2368 static_cast<void>(config::parseCommandWithArgs(args, command));
2369 backend_selector = parser_->getBackendSelector(args);
2370 }
2371
2372 // The arguments must not include "server-tags" parameter.
2374 if (args && args->contains("server-tags")) {
2375 isc_throw(BadValue, "'server-tags' is forbidden in this command");
2376 }
2377
2378 // Get servers from the configuration backend.
2379 db::ServerCollection servers = get_all_fun(backend_selector);
2380
2381 // Build response.
2384 info->set("servers", info_list);
2385 for (auto const& server : servers) {
2386 info_list->add(server->toElement());
2387 }
2388 info->set("count",
2389 data::Element::create(static_cast<long int>(servers.size())));
2390
2391 // Configuration backend didn't complain so let's return the success status.
2392 std::ostringstream msg;
2393 msg << servers.size()
2394 << (address_family == AF_INET ? " DHCPv4" : " DHCPv6")
2395 << " server(s) found.";
2396 int rcode =
2398 data::ConstElementPtr response =
2399 config::createAnswer(rcode, msg.str(), info);
2400 callout_handle.setArgument("response", response);
2401
2402 } catch (const std::exception& ex) {
2403 // Something went wrong. Return an error response to the client.
2404 data::ConstElementPtr response =
2406 callout_handle.setArgument("response", response);
2407 }
2408 }
2409
2416 template <typename FunType>
2418 const uint16_t address_family,
2419 FunType create_update_fun) {
2420 try {
2421 // Parse the command and store the shared network name.
2422 std::string name;
2423 db::BackendSelector backend_selector;
2425 parser_->parseInputListElement<CBSharedNetworkNameParser>
2426 (callout_handle, "shared-networks", name, backend_selector,
2428
2429 // Parse again the command and store the option data in
2430 // the option_pair object.
2431 std::pair<dhcp::OptionDescriptor, std::string> option_pair =
2432 std::make_pair(dhcp::OptionDescriptor(false, false), "");
2433 parser_->parseInputListElement
2436 (callout_handle, "options", address_family, CfgOptionDefPtr(),
2437 backend_selector, server_selector, option_pair);
2438
2439 auto option_descriptor = option_pair.first;
2440 option_descriptor.space_name_ = option_pair.second;
2441
2442 // Pass the received arguments into the configuration backend.
2443 create_update_fun(backend_selector, server_selector,
2444 name, option_descriptor);
2445
2446 auto option_info = makeOptionInfoElement(option_descriptor);
2447
2448 // The option information is encapsulated in a single element list.
2450 response_list->add(option_info);
2451
2452 data::ElementPtr response_arguments = data::Element::createMap();
2453 response_arguments->set("options", response_list);
2454
2455 // Configuration backend didn't complain so let's return the success status.
2456 std::ostringstream msg;
2457 msg << (address_family == AF_INET ? "DHCPv4" : "DHCPv6")
2458 << " option successfully set.";
2459 data::ConstElementPtr response =
2461 msg.str(), response_arguments);
2462 callout_handle.setArgument("response", response);
2463
2464 } catch (const std::exception& ex) {
2465 // Something went wrong. Return an error response to the client.
2466 data::ConstElementPtr response =
2468 callout_handle.setArgument("response", response);
2469 }
2470 }
2471
2478 template <typename FunType>
2480 const uint16_t address_family,
2481 FunType delete_fun) {
2482 try {
2483 // Parse the command and store the shared network name.
2484 std::string name;
2485 db::BackendSelector backend_selector;
2487 parser_->parseInputListElement<CBSharedNetworkNameParser>
2488 (callout_handle, "shared-networks", name, backend_selector,
2490
2491 // Parse again the command and store the option code/space/client classes tuple.
2492 CBOptionTuple option_tuple;
2493 parser_->parseInputListElement<CBOptionTupleParser, uint16_t>
2494 (callout_handle, "options", address_family, option_tuple);
2495
2496 // Pass the received arguments into the configuration backend.
2497 uint64_t count = delete_fun(backend_selector, server_selector,
2498 name,
2499 std::get<0>(option_tuple),
2500 std::get<1>(option_tuple),
2501 std::get<2>(option_tuple));
2502
2503 data::ElementPtr response_arguments = data::Element::createMap();
2504 response_arguments->set("count",
2505 data::Element::create(static_cast<long int>(count)));
2506
2507 // Configuration backend didn't complain so let's return the success status.
2508 std::ostringstream msg;
2509 msg << count << (address_family == AF_INET ? " DHCPv4" : " DHCPv6")
2510 << " option(s) deleted.";
2511 int rcode =
2513 data::ConstElementPtr response =
2514 config::createAnswer(rcode, msg.str(), response_arguments);
2515 callout_handle.setArgument("response", response);
2516
2517 } catch (const std::exception& ex) {
2518 // Something went wrong. Return an error response to the client.
2519 data::ConstElementPtr response =
2521 callout_handle.setArgument("response", response);
2522 }
2523 }
2524
2531 template <typename FunType>
2533 const uint16_t address_family,
2534 FunType create_update_fun) {
2535 try {
2536 // Parse the command and store the subnet id.
2537 dhcp::SubnetID subnet_id;
2538 db::BackendSelector backend_selector;
2540 parser_->parseInputListElement<CBSubnetIdParser>
2541 (callout_handle, "subnets", subnet_id, backend_selector,
2543
2544 // Parse again the command and store the option data in
2545 // the option_pair object.
2546 std::pair<dhcp::OptionDescriptor, std::string> option_pair =
2547 std::make_pair(dhcp::OptionDescriptor(false, false), "");
2548 parser_->parseInputListElement
2551 (callout_handle, "options", address_family, CfgOptionDefPtr(),
2552 backend_selector, server_selector, option_pair);
2553
2554 auto option_descriptor = option_pair.first;
2555 option_descriptor.space_name_ = option_pair.second;
2556
2557 // Pass the received arguments into the configuration backend.
2558 create_update_fun(backend_selector, server_selector,
2559 subnet_id, option_descriptor);
2560
2561 // The response contains option code, space, and client classes.
2562 auto option_info = makeOptionInfoElement(option_descriptor);
2563
2564 // The option information is encapsulated in a single element list.
2566 response_list->add(option_info);
2567
2568 data::ElementPtr response_arguments = data::Element::createMap();
2569 response_arguments->set("options", response_list);
2570
2571 // Configuration backend didn't complain so let's return the success status.
2572 std::ostringstream msg;
2573 msg << (address_family == AF_INET ? "DHCPv4" : "DHCPv6")
2574 << " option successfully set.";
2575 data::ConstElementPtr response =
2577 msg.str(), response_arguments);
2578 callout_handle.setArgument("response", response);
2579
2580 } catch (const std::exception& ex) {
2581 // Something went wrong. Return an error response to the client.
2582 data::ConstElementPtr response =
2584 callout_handle.setArgument("response", response);
2585 }
2586 }
2587
2594 template <typename FunType>
2596 const uint16_t address_family,
2597 FunType delete_fun) {
2598 try {
2599 // Parse the command and store the subnet id.
2600 dhcp::SubnetID subnet_id;
2601 db::BackendSelector backend_selector;
2603 parser_->parseInputListElement<CBSubnetIdParser>
2604 (callout_handle, "subnets", subnet_id, backend_selector,
2606
2607 // Parse again the command and store the option code/space/client classes tuple.
2608 CBOptionTuple option_tuple;
2609 parser_->parseInputListElement<CBOptionTupleParser, uint16_t>
2610 (callout_handle, "options", address_family, option_tuple);
2611
2612 // Pass the received arguments into the configuration backend.
2613 uint64_t count = delete_fun(backend_selector, server_selector,
2614 subnet_id,
2615 std::get<0>(option_tuple),
2616 std::get<1>(option_tuple),
2617 std::get<2>(option_tuple));
2618
2619 data::ElementPtr response_arguments = data::Element::createMap();
2620 response_arguments->set("count",
2621 data::Element::create(static_cast<long int>(count)));
2622
2623 // Configuration backend didn't complain so let's return the success status.
2624 std::ostringstream msg;
2625 msg << count << (address_family == AF_INET ? " DHCPv4" : " DHCPv6")
2626 << " option(s) deleted.";
2627 int rcode =
2629 data::ConstElementPtr response =
2630 config::createAnswer(rcode, msg.str(), response_arguments);
2631 callout_handle.setArgument("response", response);
2632
2633 } catch (const std::exception& ex) {
2634 // Something went wrong. Return an error response to the client.
2635 data::ConstElementPtr response =
2637 callout_handle.setArgument("response", response);
2638 }
2639 }
2640
2647 template <typename FunType>
2649 const uint16_t address_family,
2650 FunType create_update_fun) {
2651 try {
2652 // Parse the command and store the pool range.
2653 std::pair<asiolink::IOAddress, asiolink::IOAddress> pool_range =
2654 (address_family == AF_INET ?
2659 db::BackendSelector backend_selector;
2661 parser_->parseInputListElement<CBPoolRangeParser, uint16_t>
2662 (callout_handle, "pools", address_family,
2663 pool_range, backend_selector, server_selector,
2665
2666 // Parse again the command and store the option data in
2667 // the option_pair object.
2668 std::pair<dhcp::OptionDescriptor, std::string> option_pair =
2669 std::make_pair(dhcp::OptionDescriptor(false, false), "");
2670 parser_->parseInputListElement<
2673 (callout_handle, "options", address_family, CfgOptionDefPtr(),
2674 backend_selector, server_selector, option_pair);
2675
2676 auto option_descriptor = option_pair.first;
2677 option_descriptor.space_name_ = option_pair.second;
2678
2679 // Pass the received arguments into the configuration backend.
2680 create_update_fun(backend_selector, server_selector,
2681 pool_range.first, pool_range.second,
2682 option_descriptor);
2683
2684 // The response contains option code, space, and client classes.
2685 auto option_info = makeOptionInfoElement(option_descriptor);
2686
2687 // The option information is encapsulated in a single element list.
2689 response_list->add(option_info);
2690
2691 data::ElementPtr response_arguments = data::Element::createMap();
2692 response_arguments->set("options", response_list);
2693
2694 // Configuration backend didn't complain so let's return the success status.
2695 std::ostringstream msg;
2696 msg << (address_family == AF_INET ? "DHCPv4" : "DHCPv6")
2697 << " option successfully set.";
2698 data::ConstElementPtr response =
2700 msg.str(), response_arguments);
2701 callout_handle.setArgument("response", response);
2702
2703 } catch (const std::exception& ex) {
2704 // Something went wrong. Return an error response to the client.
2705 data::ConstElementPtr response =
2707 callout_handle.setArgument("response", response);
2708 }
2709 }
2710
2717 template <typename FunType>
2719 const uint16_t address_family,
2720 FunType delete_fun) {
2721 try {
2722 // Parse the command and store the pool range.
2723 std::pair<asiolink::IOAddress, asiolink::IOAddress> pool_range =
2724 (address_family == AF_INET ?
2729 db::BackendSelector backend_selector;
2731 parser_->parseInputListElement<CBPoolRangeParser, uint16_t>
2732 (callout_handle, "pools", address_family,
2733 pool_range, backend_selector, server_selector,
2735
2736 // Parse again the command and store the option code/space/client classes tuple.
2737 CBOptionTuple option_tuple;
2738 parser_->parseInputListElement<CBOptionTupleParser, uint16_t>
2739 (callout_handle, "options", address_family, option_tuple);
2740
2741 // Pass the received arguments into the configuration backend.
2742 uint64_t count = delete_fun(backend_selector, server_selector,
2743 pool_range.first, pool_range.second,
2744 std::get<0>(option_tuple),
2745 std::get<1>(option_tuple),
2746 std::get<2>(option_tuple));
2747
2748 data::ElementPtr response_arguments = data::Element::createMap();
2749 response_arguments->set("count",
2750 data::Element::create(static_cast<long int>(count)));
2751
2752 // Configuration backend didn't complain so let's return the success status.
2753 std::ostringstream msg;
2754 msg << count << (address_family == AF_INET ? " DHCPv4" : " DHCPv6")
2755 << " option(s) deleted.";
2756 int rcode =
2758 data::ConstElementPtr response =
2759 config::createAnswer(rcode, msg.str(), response_arguments);
2760 callout_handle.setArgument("response", response);
2761
2762 } catch (const std::exception& ex) {
2763 // Something went wrong. Return an error response to the client.
2764 data::ConstElementPtr response =
2766 callout_handle.setArgument("response", response);
2767 }
2768 }
2769
2777 option_info->set("code",
2778 data::Element::create(static_cast<int64_t>
2779 (def.getCode())));
2780
2781 option_info->set("space", data::Element::create(def.getOptionSpaceName()));
2782 return (option_info);
2783 }
2784
2785
2794 option_info->set("code",
2795 data::Element::create(static_cast<int64_t>
2796 (desc.option_->getType())));
2797
2798 option_info->set("space", data::Element::create(desc.space_name_));
2799 if (!desc.client_classes_.empty()) {
2800 option_info->set("client-classes", desc.client_classes_.toElement());
2801 }
2802 return (option_info);
2803 }
2804
2805protected:
2807 boost::shared_ptr<ConfigCmdsParser> parser_;
2808};
2809
2810} // end of namespace isc::cb
2811} // end of namespace isc
2812
2813#endif // CB_CMDS_IMPL_H
Parsers for a subset of an object specification, e.g.
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
A generic exception that is thrown if a function is called in a prohibited way.
Implements a parser for a client class name.
Implements a parser for a DHCPv4 or DHCPv6 client class.
Definition cb_parsers.h:976
Overrides the default option data parser.
Definition cb_parsers.h:232
Implements a parser for parsing the option code, space, and force.
Definition cb_parsers.h:202
Implements a parser for option definitions with setting defaults.
Definition cb_parsers.h:94
Implements a parser for parsing the option code and space.
Definition cb_parsers.h:120
Implements a parser for parsing the option code and space and client-classes.
Definition cb_parsers.h:173
Implements a parser for an address pool range.
Definition cb_parsers.h:343
Implements a parser for a shared network name.
Definition cb_parsers.h:813
Implements a parser for a subnet id.
Definition cb_parsers.h:569
Implements a parser for a subnet prefix.
Definition cb_parsers.h:595
void setClientClass(hooks::CalloutHandle &callout_handle, const uint16_t address_family, FunType create_update_fun)
Implements handler for remote-class[46]-set command.
ConfigCmdsImpl()
Constructor.
void getSubnetId(hooks::CalloutHandle &callout_handle, const uint16_t address_family, FunType get_fun)
Implements handler for remote-subnet[46]-get-by-id command.
void getGlobalOption(hooks::CalloutHandle &callout_handle, const uint16_t address_family, FunType get_fun)
Implements handler for remote-option[46]-global-get command.
void delPoolOption(hooks::CalloutHandle &callout_handle, const uint16_t address_family, FunType delete_fun)
Implements handler for remote-option[46]-pool-del command.
void getClientClass(hooks::CalloutHandle &callout_handle, const uint16_t address_family, FunType get_fun)
Implements handler for remote-class[46]-get command.
void getSharedNetwork(hooks::CalloutHandle &callout_handle, const uint16_t address_family, FunType get_fun, FunType2 get_all)
Implements handler for remote-shared-network[46]-get command.
void setSharedNetworkOption(hooks::CalloutHandle &callout_handle, const uint16_t address_family, FunType create_update_fun)
Implements handler for remote-option[46]-network-set command.
data::ElementPtr makeOptionInfoElement(const OptionDefinition &def) const
Create an element map containing an OptionDef's code and space.
void setSubnetOption(hooks::CalloutHandle &callout_handle, const uint16_t address_family, FunType create_update_fun)
Implements handler for remote-option[46]-subnet-set command.
void getAllServers(hooks::CalloutHandle &callout_handle, const uint16_t address_family, FunType get_all_fun)
Implements handler for remote-server[46]-get-all command.
void setServer(hooks::CalloutHandle &callout_handle, const uint16_t address_family, FunType create_update_fun)
Implements handler for remote-server[46]-set command.
void delGlobalParameter(hooks::CalloutHandle &callout_handle, const data::SimpleKeywords &keywords, const uint16_t address_family, FunType delete_fun)
Implements handler for remote-global-parameter[46]-del command.
void delSharedNetwork(hooks::CalloutHandle &callout_handle, const uint16_t address_family, FunType delete_fun, FunType2 delete_all_fun)
Implements handler for remote-shared-network[46]-del command.
void getGlobalParameter(hooks::CalloutHandle &callout_handle, const data::SimpleKeywords &keywords, const uint16_t address_family, FunType get_fun)
Implements handler for remote-global-parameter[46]-get command.
void getServer(hooks::CalloutHandle &callout_handle, const uint16_t address_family, FunType get_fun)
Implements handler for remote-server[46]-get command.
void delSubnetOption(hooks::CalloutHandle &callout_handle, const uint16_t address_family, FunType delete_fun)
Implements handler for remote-option[46]-subnet-del command.
void getOptionDef(hooks::CalloutHandle &callout_handle, const uint16_t address_family, FunType get_fun)
Implements handler for remote-option-def[46]-get command.
void setGlobalOption(hooks::CalloutHandle &callout_handle, const uint16_t address_family, FunType create_update_fun)
Implements handler for remote-option[46]-global-set command.
void getAllGlobalParameters(hooks::CalloutHandle &callout_handle, const data::SimpleKeywords &keywords, const uint16_t address_family, FunType get_all_fun)
Implements handler for remote-global-parameter[46]-get-all command.
void delOptionDef(hooks::CalloutHandle &callout_handle, const uint16_t address_family, FunType delete_fun)
Implements handler for remote-option-def[46]-del command.
void delSubnetPrefix(hooks::CalloutHandle &callout_handle, const uint16_t address_family, FunType delete_fun)
Implements handler for remote-subnet[46]-del-by-prefix command.
void delSharedNetworkOption(hooks::CalloutHandle &callout_handle, const uint16_t address_family, FunType delete_fun)
Implements handler for remote-option[46]-network-del command.
void delClientClass(hooks::CalloutHandle &callout_handle, const uint16_t address_family, FunType delete_fun)
Implements handler for remote-class[46]-del command.
void getSubnetPrefix(hooks::CalloutHandle &callout_handle, const uint16_t address_family, FunType get_fun)
Implements handler for remote-subnet[46]-get-by-prefix command.
void setPoolOption(hooks::CalloutHandle &callout_handle, const uint16_t address_family, FunType create_update_fun)
Implements handler for remote-option[46]-pool-set command.
data::ElementPtr makeOptionInfoElement(const OptionDescriptor &desc) const
Create an element map containing an OptionDescriptor's code, space, and client classes.
void listSubnets(hooks::CalloutHandle &callout_handle, const uint16_t address_family, FunType get_all_fun)
Implements handler for remote-subnet[46]-list command.
void getAllClientClasses(hooks::CalloutHandle &callout_handle, const uint16_t address_family, FunType get_all)
Implements handler for remote-class[46]-get-all command.
void getAllOptionDefs(hooks::CalloutHandle &callout_handle, const uint16_t address_family, FunType get_all_fun)
Implements handler for remote-option-def[46]-get-all command.
void getAllGlobalOptions(hooks::CalloutHandle &callout_handle, const uint16_t address_family, FunType get_all_fun)
Implements handler for remote-option[46]-global-get-all command.
boost::shared_ptr< ConfigCmdsParser > parser_
Shared pointer to the commands parser.
void delGlobalOption(hooks::CalloutHandle &callout_handle, const uint16_t address_family, FunType delete_fun)
Implements handler for remote-option[46]-global-del command.
void delSubnetId(hooks::CalloutHandle &callout_handle, const uint16_t address_family, FunType delete_fun)
Implements handler for remote-subnet[46]-del-by-id command.
void setSharedNetwork(hooks::CalloutHandle &callout_handle, const uint16_t address_family, FunType create_update_fun)
Implements handler for remote-shared-network[46]-set command.
void delServer(hooks::CalloutHandle &callout_handle, const uint16_t address_family, FunType delete_fun)
Implements handler for remote-server[46]-del command.
void listSharedNetworks(hooks::CalloutHandle &callout_handle, const uint16_t address_family, FunType get_all)
Implements handler for remote-shared-network[46]-list command.
void setSubnet(hooks::CalloutHandle &callout_handle, const uint16_t address_family, FunType create_update_fun)
Implements handler for remote-subnet[46]-set command.
void setGlobalParameter(hooks::CalloutHandle &callout_handle, const data::SimpleKeywords &keywords, const data::SimpleKeywords &list_keywords, const uint16_t address_family, FunType create_update_fun)
Implements handler for remote-global-parameter[46]-set command.
void setOptionDef(hooks::CalloutHandle &callout_handle, const uint16_t address_family, FunType create_update_fun)
Implements handler for remote-option-def[46]-set command.
This parser class contains the common logic for various callouts to parse and validate the contents o...
ServerTagsParse
Server selector parsing.
@ TAGS_REQUIRED
server-tags is required
@ TAGS_FORBIDDEN
server-tags is not allowed
@ TAGS_OPTIONAL
server-tags entry is optional
SubnetsInclude
Subnets actions for shared network get command.
db::ServerSelector getServerSelector(const data::ConstElementPtr &args, ServerTagsParse tags_parse) const
Creates server selector from the command's arguments.
SubnetsAction
Subnets actions for shared network delete.
@ ACTION_KEEP
keep subnets (default)
@ ACTION_DELETE
delete subnets
void parseInputMapElement(hooks::CalloutHandle &callout_handle, const std::string &map_name, ParserArgs... parser_args, ElementType &parsed_element, db::BackendSelector &backend_selector, db::ServerSelector &server_selector, ServerTagsParse tags_parse) const
Parses a command containing a map of elements.
SubnetsAction getSubnetsAction(const data::ConstElementPtr &args) const
Creates subnets action from the command's arguments.
SubnetsInclude getSubnetsInclude(const data::ConstElementPtr &args) const
Creates SubnetsInclude from the command's arguments.
data::ConstElementPtr parseInputListElement(hooks::CalloutHandle &callout_handle, const std::string &list_name, ParserArgs... parser_args, ElementType &parsed_element, data::Element::types sub_type=data::Element::map) const
Parses a command containing a list of elements (second call).
void getSubnetCommon(hooks::CalloutHandle &callout_handle, const SubnetPtrType &subnet, const uint16_t address_family, const KeyType &key)
Common routine invoked when getting a subnet.
data::ConstElementPtr parseInputListElement(hooks::CalloutHandle &callout_handle, const std::string &list_name, ParserArgs... parser_args, ElementType &parsed_element, db::BackendSelector &backend_selector, db::ServerSelector &server_selector, ServerTagsParse tags_parse, data::Element::types sub_type=data::Element::map) const
Parses a command containing a list of elements.
db::BackendSelector getBackendSelector(const data::ConstElementPtr &args) const
Creates backend selector from the command's arguments.
Implements a parser for a global parameter name.
Definition cb_parsers.h:35
Implements a parser for global parameters.
Definition cb_parsers.h:60
Implements parser for a server configuration.
Implements parser for a server tag.
static ElementPtr create(const Position &pos=ZERO_POSITION())
Create a NullElement.
Definition data.cc:300
static std::string typeToName(Element::types type)
Returns the name of the given type as a string.
Definition data.cc:716
types
The types that an Element can hold.
Definition data.h:152
static ElementPtr fromJSON(const std::string &in, bool preproc=false)
These functions will parse the given string (JSON) representation of a compound element.
Definition data.cc:865
static ElementPtr createMap(const Position &pos=ZERO_POSITION())
Creates an empty MapElement type ElementPtr.
Definition data.cc:355
static ElementPtr createList(const Position &pos=ZERO_POSITION())
Creates an empty ListElement type ElementPtr.
Definition data.cc:350
Represents a server tag.
Definition server_tag.h:25
std::string get() const
Returns server tag as string.
Definition server_tag.h:51
Config Backend selector.
Server selector for associating objects in a database with specific servers.
std::set< data::ServerTag > getTags() const
Returns tags associated with the selector.
bool hasNoTags() const
Convenience method checking if the server selector has no tags.
static ServerSelector UNASSIGNED()
Factory returning "unassigned" server selector.
static bool translateName(std::string const &name, std::string &param_name, std::string &sub_param_name)
It translates the top level map parameters from flat naming format (e.g.
Definition cb_ctl_dhcp.h:46
Represents option definitions used by the DHCP server.
Represents option data configuration for the DHCP server.
Definition cfg_option.h:405
Maintains a list of ClientClassDef's.
bool empty() const
Checks if the class dictionary is empty.
const ClientClassDefListPtr & getClasses() const
Fetches the dictionary's list of classes.
bool empty() const
Check if classes is empty.
Definition classify.h:171
virtual isc::data::ElementPtr toElement() const
Returns all class names as an ElementPtr of type ListElement.
Definition classify.cc:92
Base class representing a DHCP option definition.
uint16_t getCode() const
Return option code.
std::string getOptionSpaceName() const
Returns option space name.
Option descriptor.
Definition cfg_option.h:50
OptionPtr option_
Option instance.
Definition cfg_option.h:53
std::string space_name_
Option space name.
Definition cfg_option.h:93
ClientClasses client_classes_
Collection of classes for the which option is allowed.
Definition cfg_option.h:97
this class parses a single subnet
Per-packet callout handle.
void getArgument(const std::string &name, T &value) const
Get argument.
void setArgument(const std::string &name, T value)
Set argument.
Defines classes for storing client class definitions.
Parsers for client class definitions.
This file contains several functions and constants that are used for handling commands and responses ...
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
int get_all(CalloutHandle &handle)
The gss-tsig-get-all command.
std::tuple< uint16_t, std::string, ClientClassesPtr > CBOptionTuple
Defines a tuple for the three values that may be used as a key for an option.
Definition cb_parsers.h:168
std::tuple< uint16_t, std::string, bool > CBOptionDefDelete
Defines a tuple of values for deleting an option definition: the option code, option space,...
Definition cb_parsers.h:165
const int CONTROL_RESULT_EMPTY
Status code indicating that the specified command was completed correctly, but failed to produce any ...
const int CONTROL_RESULT_ERROR
Status code indicating a general failure.
std::string parseCommand(ConstElementPtr &arg, ConstElementPtr command)
Parses the given command into a string containing the actual command and an ElementPtr containing the...
std::string parseCommandWithArgs(ConstElementPtr &arg, ConstElementPtr command)
Parses the given command into a string containing the command name and an ElementPtr containing the m...
ConstElementPtr createAnswer()
Creates a standard config/command level success answer message (i.e.
const int CONTROL_RESULT_SUCCESS
Status code indicating a successful operation.
boost::shared_ptr< StampedValue > StampedValuePtr
Pointer to the stamped value.
boost::multi_index_container< StampedValuePtr, boost::multi_index::indexed_by< boost::multi_index::hashed_non_unique< boost::multi_index::tag< StampedValueNameIndexTag >, boost::multi_index::const_mem_fun< StampedValue, std::string, &StampedValue::getName > >, boost::multi_index::ordered_non_unique< boost::multi_index::tag< StampedValueModificationTimeIndexTag >, boost::multi_index::const_mem_fun< BaseStampedElement, boost::posix_time::ptime, &BaseStampedElement::getModificationTime > > > > StampedValueCollection
Multi index container for StampedValue.
boost::shared_ptr< const Element > ConstElementPtr
Definition data.h:30
boost::shared_ptr< Element > ElementPtr
Definition data.h:29
std::map< std::string, isc::data::Element::types > SimpleKeywords
This specifies all accepted keywords with their types.
boost::shared_ptr< Server > ServerPtr
Shared pointer to the Server class.
Definition server.h:22
@ info
Definition db_log.h:129
boost::multi_index_container< ServerPtr, boost::multi_index::indexed_by< boost::multi_index::ordered_unique< boost::multi_index::tag< ServerTagIndexTag >, boost::multi_index::const_mem_fun< Server, std::string, &Server::getServerTagAsText > > > > ServerCollection
Multi index container for Server.
boost::multi_index_container< OptionDescriptor, boost::multi_index::indexed_by< boost::multi_index::sequenced<>, boost::multi_index::hashed_non_unique< KeyFromKeyExtractor< boost::multi_index::const_mem_fun< Option, uint16_t, &Option::getType >, boost::multi_index::member< OptionDescriptor, OptionPtr, &OptionDescriptor::option_ > > >, boost::multi_index::hashed_non_unique< boost::multi_index::member< OptionDescriptor, bool, &OptionDescriptor::persistent_ > >, boost::multi_index::ordered_non_unique< boost::multi_index::const_mem_fun< data::BaseStampedElement, boost::posix_time::ptime, &data::BaseStampedElement::getModificationTime > >, boost::multi_index::hashed_non_unique< boost::multi_index::tag< OptionIdIndexTag >, boost::multi_index::const_mem_fun< data::BaseStampedElement, uint64_t, &data::BaseStampedElement::getId > >, boost::multi_index::hashed_non_unique< boost::multi_index::member< OptionDescriptor, bool, &OptionDescriptor::cancelled_ > >, boost::multi_index::hashed_non_unique< boost::multi_index::composite_key< OptionDescriptor, KeyFromKeyExtractor< boost::multi_index::const_mem_fun< Option, uint16_t, &Option::getType >, boost::multi_index::member< OptionDescriptor, OptionPtr, &OptionDescriptor::option_ > >, boost::multi_index::member< OptionDescriptor, ClientClasses, &OptionDescriptor::client_classes_ > > > > > OptionContainer
Multi index container for DHCP option descriptors.
Definition cfg_option.h:348
boost::shared_ptr< CfgOption > CfgOptionPtr
Non-const pointer.
Definition cfg_option.h:983
boost::shared_ptr< CfgOptionDef > CfgOptionDefPtr
Non-const pointer.
boost::shared_ptr< ClientClassDef > ClientClassDefPtr
a pointer to an ClientClassDef
boost::shared_ptr< OptionDefinition > OptionDefinitionPtr
Pointer to option definition object.
boost::shared_ptr< OptionDescriptor > OptionDescriptorPtr
A pointer to option descriptor.
Definition cfg_option.h:39
uint32_t SubnetID
Defines unique IPv4 or IPv6 subnet identifier.
Definition subnet_id.h:25
boost::multi_index_container< OptionDefinitionPtr, boost::multi_index::indexed_by< boost::multi_index::sequenced<>, boost::multi_index::hashed_non_unique< boost::multi_index::const_mem_fun< OptionDefinition, uint16_t, &OptionDefinition::getCode > >, boost::multi_index::hashed_non_unique< boost::multi_index::const_mem_fun< OptionDefinition, std::string, &OptionDefinition::getName > >, boost::multi_index::ordered_non_unique< boost::multi_index::const_mem_fun< data::BaseStampedElement, boost::posix_time::ptime, &data::StampedElement::getModificationTime > >, boost::multi_index::hashed_non_unique< boost::multi_index::tag< OptionIdIndexTag >, boost::multi_index::const_mem_fun< data::BaseStampedElement, uint64_t, &data::BaseStampedElement::getId > > > > OptionDefContainer
Multi index container for DHCP option definitions.
Defines the logger used by the top-level component of kea-lfc.