1 // Copyright (C) 2018-2021 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 #include <config.h>
8
9 #include <database/database_connection.h>
10 #include <test_config_backend_dhcp4.h>
11 #include <list>
12
13 using namespace isc::data;
14 using namespace isc::db;
15
16 namespace isc {
17 namespace dhcp {
18 namespace test {
19
20 bool
registerBackendType(ConfigBackendDHCPv4Mgr & mgr,const std::string & db_type)21 TestConfigBackendDHCPv4::registerBackendType(ConfigBackendDHCPv4Mgr& mgr,
22 const std::string& db_type) {
23 return(mgr.registerBackendFactory(db_type,
24 [](const db::DatabaseConnection::ParameterMap& params)
25 -> dhcp::ConfigBackendDHCPv4Ptr {
26 return (TestConfigBackendDHCPv4Ptr(new TestConfigBackendDHCPv4(params)));
27 })
28 );
29 }
30
31 void
unregisterBackendType(ConfigBackendDHCPv4Mgr & mgr,const std::string & db_type)32 TestConfigBackendDHCPv4::unregisterBackendType(ConfigBackendDHCPv4Mgr& mgr,
33 const std::string& db_type) {
34 mgr.unregisterBackendFactory(db_type);
35 }
36
37 Subnet4Ptr
getSubnet4(const db::ServerSelector & server_selector,const std::string & subnet_prefix) const38 TestConfigBackendDHCPv4::getSubnet4(const db::ServerSelector& server_selector,
39 const std::string& subnet_prefix) const{
40 const auto& index = subnets_.get<SubnetPrefixIndexTag>();
41 auto subnet_it = index.find(subnet_prefix);
42 if (subnet_it == index.cend()) {
43 return (Subnet4Ptr());
44 }
45 Subnet4Ptr subnet = *subnet_it;
46 if (server_selector.amAny()) {
47 return (subnet);
48 }
49 if (server_selector.amUnassigned()) {
50 return (subnet->getServerTags().empty() ? subnet : Subnet4Ptr());
51 }
52 auto tags = server_selector.getTags();
53 for (auto tag : tags) {
54 if (subnet->hasServerTag(ServerTag(tag))) {
55 return (subnet);
56 }
57 }
58 return (subnet->hasAllServerTag() ? subnet : Subnet4Ptr());
59 }
60
61 Subnet4Ptr
getSubnet4(const db::ServerSelector & server_selector,const SubnetID & subnet_id) const62 TestConfigBackendDHCPv4::getSubnet4(const db::ServerSelector& server_selector,
63 const SubnetID& subnet_id) const {
64 const auto& index = subnets_.get<SubnetSubnetIdIndexTag>();
65 auto subnet_it = index.find(subnet_id);
66 if (subnet_it == index.cend()) {
67 return (Subnet4Ptr());
68 }
69 Subnet4Ptr subnet = *subnet_it;
70 if (server_selector.amAny()) {
71 return (subnet);
72 }
73 if (server_selector.amUnassigned()) {
74 return (subnet->getServerTags().empty() ? subnet : Subnet4Ptr());
75 }
76 auto tags = server_selector.getTags();
77 for (auto tag : tags) {
78 if (subnet->hasServerTag(ServerTag(tag))) {
79 return (subnet);
80 }
81 }
82 return (subnet->hasAllServerTag() ? subnet : Subnet4Ptr());
83 }
84
85 Subnet4Collection
getAllSubnets4(const db::ServerSelector & server_selector) const86 TestConfigBackendDHCPv4::getAllSubnets4(const db::ServerSelector& server_selector) const {
87 Subnet4Collection subnets;
88 for (auto subnet : subnets_) {
89 if (server_selector.amAny()) {
90 subnets.insert(subnet);
91 continue;
92 }
93 if (server_selector.amUnassigned()) {
94 if (subnet->getServerTags().empty()) {
95 subnets.insert(subnet);
96 }
97 continue;
98 }
99 bool got = false;
100 auto tags = server_selector.getTags();
101 for (auto tag : tags) {
102 if (subnet->hasServerTag(ServerTag(tag))) {
103 subnets.insert(subnet);
104 got = true;
105 break;
106 }
107 }
108 if (got) {
109 continue;
110 }
111 if (subnet->hasAllServerTag()) {
112 subnets.insert(subnet);
113 }
114 }
115 return (subnets);
116 }
117
118 Subnet4Collection
getModifiedSubnets4(const db::ServerSelector & server_selector,const boost::posix_time::ptime & modification_time) const119 TestConfigBackendDHCPv4::getModifiedSubnets4(const db::ServerSelector& server_selector,
120 const boost::posix_time::ptime& modification_time) const {
121 const auto& index = subnets_.get<SubnetModificationTimeIndexTag>();
122 Subnet4Collection subnets;
123 auto lb = index.lower_bound(modification_time);
124 for (auto subnet = lb; subnet != index.end(); ++subnet) {
125 if (server_selector.amAny()) {
126 subnets.insert(*subnet);
127 continue;
128 }
129 if (server_selector.amUnassigned()) {
130 if ((*subnet)->getServerTags().empty()) {
131 subnets.insert(*subnet);
132 }
133 continue;
134 }
135 bool got = false;
136 auto tags = server_selector.getTags();
137 for (auto tag : tags) {
138 if ((*subnet)->hasServerTag(ServerTag(tag))) {
139 subnets.insert(*subnet);
140 got = true;
141 break;
142 }
143 }
144 if (got) {
145 continue;
146 }
147 if ((*subnet)->hasAllServerTag()) {
148 subnets.insert(*subnet);
149 }
150 }
151 return (subnets);
152 }
153
154 Subnet4Collection
getSharedNetworkSubnets4(const db::ServerSelector & server_selector,const std::string & shared_network_name) const155 TestConfigBackendDHCPv4::getSharedNetworkSubnets4(const db::ServerSelector& server_selector,
156 const std::string& shared_network_name) const {
157 Subnet4Collection subnets;
158
159 // Subnet collection does not include the index by shared network name.
160 // We need to iterate over the subnets and pick those that are associated
161 // with a shared network.
162 for (auto subnet : subnets_) {
163 // Skip subnets which do not match the server selector.
164 if (server_selector.amUnassigned() &&
165 !subnet->getServerTags().empty()) {
166 continue;
167 }
168 if (!server_selector.amAny()) {
169 bool got = false;
170 auto tags = server_selector.getTags();
171 for (auto tag : tags) {
172 if (subnet->hasServerTag(ServerTag(tag))) {
173 got = true;
174 break;
175 }
176 }
177 if (!got && !subnet->hasAllServerTag()) {
178 continue;
179 }
180 }
181
182 // The subnet can be associated with a shared network instance or
183 // it may just point to the shared network name. The former is
184 // the case when the subnet belongs to the server configuration.
185 // The latter is the case when the subnet is fetched from the
186 // database.
187 SharedNetwork4Ptr network;
188 subnet->getSharedNetwork(network);
189 if (((network && (network->getName() == shared_network_name)) ||
190 (subnet->getSharedNetworkName() == shared_network_name))) {
191 subnets.insert(subnet);
192 }
193 }
194 return (subnets);
195 }
196
197 SharedNetwork4Ptr
getSharedNetwork4(const db::ServerSelector & server_selector,const std::string & name) const198 TestConfigBackendDHCPv4::getSharedNetwork4(const db::ServerSelector& server_selector,
199 const std::string& name) const {
200 const auto& index = shared_networks_.get<SharedNetworkNameIndexTag>();
201 auto network_it = index.find(name);
202 if (network_it == index.cend()) {
203 return (SharedNetwork4Ptr());
204 }
205 SharedNetwork4Ptr network = *network_it;
206 if (server_selector.amAny()) {
207 return (network);
208 }
209 if (server_selector.amUnassigned()) {
210 return (network->getServerTags().empty() ? network : SharedNetwork4Ptr());
211 }
212 auto tags = server_selector.getTags();
213 for (auto tag : tags) {
214 if (network->hasServerTag(ServerTag(tag))) {
215 return (network);
216 }
217 }
218 return (network->hasAllServerTag() ? network : SharedNetwork4Ptr());
219 }
220
221 SharedNetwork4Collection
getAllSharedNetworks4(const db::ServerSelector & server_selector) const222 TestConfigBackendDHCPv4::getAllSharedNetworks4(const db::ServerSelector& server_selector) const{
223 SharedNetwork4Collection shared_networks;
224 for (auto shared_network : shared_networks_) {
225 if (server_selector.amAny()) {
226 shared_networks.push_back(shared_network);
227 continue;
228 }
229 if (server_selector.amUnassigned()) {
230 if (shared_network->getServerTags().empty()) {
231 shared_networks.push_back(shared_network);
232 }
233 continue;
234 }
235 bool got = false;
236 auto tags = server_selector.getTags();
237 for (auto tag : tags) {
238 if (shared_network->hasServerTag(ServerTag(tag))) {
239 shared_networks.push_back(shared_network);
240 got = true;
241 break;
242 }
243 }
244 if (got) {
245 continue;
246 }
247 if (shared_network->hasAllServerTag()) {
248 shared_networks.push_back(shared_network);
249 }
250 }
251 return (shared_networks);
252 }
253
254 SharedNetwork4Collection
getModifiedSharedNetworks4(const db::ServerSelector & server_selector,const boost::posix_time::ptime & modification_time) const255 TestConfigBackendDHCPv4::getModifiedSharedNetworks4(const db::ServerSelector& server_selector,
256 const boost::posix_time::ptime& modification_time) const {
257 const auto& index = shared_networks_.get<SharedNetworkModificationTimeIndexTag>();
258 SharedNetwork4Collection shared_networks;
259 auto lb = index.lower_bound(modification_time);
260 for (auto shared_network = lb; shared_network != index.end(); ++shared_network) {
261 if (server_selector.amAny()) {
262 shared_networks.push_back(*shared_network);
263 continue;
264 }
265 if (server_selector.amUnassigned()) {
266 if ((*shared_network)->getServerTags().empty()) {
267 shared_networks.push_back(*shared_network);
268 }
269 continue;
270 }
271 bool got = false;
272 auto tags = server_selector.getTags();
273 for (auto tag : tags) {
274 if ((*shared_network)->hasServerTag(ServerTag(tag))) {
275 shared_networks.push_back(*shared_network);
276 got = true;
277 break;
278 }
279 }
280 if (got) {
281 continue;
282 }
283 if ((*shared_network)->hasAllServerTag()) {
284 shared_networks.push_back(*shared_network);
285 }
286 }
287 return (shared_networks);
288 }
289
290 OptionDefinitionPtr
getOptionDef4(const db::ServerSelector & server_selector,const uint16_t code,const std::string & space) const291 TestConfigBackendDHCPv4::getOptionDef4(const db::ServerSelector& server_selector,
292 const uint16_t code,
293 const std::string& space) const {
294 auto tags = server_selector.getTags();
295 auto candidate = OptionDefinitionPtr();
296 const auto& index = option_defs_.get<1>();
297 auto option_def_it_pair = index.equal_range(code);
298
299 for (auto option_def_it = option_def_it_pair.first;
300 option_def_it != option_def_it_pair.second;
301 ++option_def_it) {
302 if ((*option_def_it)->getOptionSpaceName() == space) {
303 for (auto tag : tags) {
304 if ((*option_def_it)->hasServerTag(ServerTag(tag))) {
305 return (*option_def_it);
306 }
307 }
308 if ((*option_def_it)->hasAllServerTag()) {
309 candidate = *option_def_it;
310 }
311 }
312 }
313 return (candidate);
314 }
315
316 OptionDefContainer
getAllOptionDefs4(const db::ServerSelector & server_selector) const317 TestConfigBackendDHCPv4::getAllOptionDefs4(const db::ServerSelector& server_selector) const {
318 auto tags = server_selector.getTags();
319 OptionDefContainer option_defs;
320 for (auto option_def : option_defs_) {
321 bool got = false;
322 if (server_selector.amUnassigned()) {
323 if (option_def->getServerTags().empty()) {
324 option_defs.push_back(option_def);
325 got = true;
326 }
327 } else {
328 for (auto tag : tags) {
329 if (option_def->hasServerTag(ServerTag(tag))) {
330 option_defs.push_back(option_def);
331 got = true;
332 break;
333 }
334 }
335 }
336 if (got) {
337 continue;
338 }
339 if (option_def->hasAllServerTag() && !server_selector.amUnassigned()) {
340 option_defs.push_back(option_def);
341 }
342 }
343 return (option_defs);
344 }
345
346 OptionDefContainer
getModifiedOptionDefs4(const db::ServerSelector & server_selector,const boost::posix_time::ptime & modification_time) const347 TestConfigBackendDHCPv4::getModifiedOptionDefs4(const db::ServerSelector& server_selector,
348 const boost::posix_time::ptime& modification_time) const {
349 auto tags = server_selector.getTags();
350 OptionDefContainer option_defs;
351 const auto& index = option_defs_.get<3>();
352 auto lb = index.lower_bound(modification_time);
353 for (auto option_def = lb; option_def != index.end(); ++option_def) {
354 bool got = false;
355 for (auto tag : tags) {
356 if ((*option_def)->hasServerTag(ServerTag(tag))) {
357 option_defs.push_back(*option_def);
358 got = true;
359 break;
360 }
361 }
362 if (got) {
363 continue;
364 }
365 if ((*option_def)->hasAllServerTag()) {
366 option_defs.push_back(*option_def);
367 }
368 }
369 return (option_defs);
370 }
371
372 OptionDescriptorPtr
getOption4(const db::ServerSelector & server_selector,const uint16_t code,const std::string & space) const373 TestConfigBackendDHCPv4::getOption4(const db::ServerSelector& server_selector,
374 const uint16_t code,
375 const std::string& space) const {
376 auto tags = server_selector.getTags();
377 auto candidate = OptionDescriptorPtr();
378 const auto& index = options_.get<1>();
379 auto option_it_pair = index.equal_range(code);
380
381 for (auto option_it = option_it_pair.first; option_it != option_it_pair.second;
382 ++option_it) {
383 if (option_it->space_name_ == space) {
384 for (auto tag : tags) {
385 if (option_it->hasServerTag(ServerTag(tag))) {
386 return (OptionDescriptorPtr(new OptionDescriptor(*option_it)));
387 }
388 }
389 if (option_it->hasAllServerTag()) {
390 candidate = OptionDescriptorPtr(new OptionDescriptor(*option_it));
391 }
392 }
393 }
394
395 return (candidate);
396 }
397
398 OptionContainer
getAllOptions4(const db::ServerSelector & server_selector) const399 TestConfigBackendDHCPv4::getAllOptions4(const db::ServerSelector& server_selector) const {
400 auto tags = server_selector.getTags();
401 OptionContainer options;
402 for (auto option : options_) {
403 bool got = false;
404 for (auto tag : tags) {
405 if (option.hasServerTag(ServerTag(tag))) {
406 options.push_back(option);
407 got = true;
408 break;
409 }
410 }
411 if (got) {
412 continue;
413 }
414 if (option.hasAllServerTag()) {
415 options.push_back(option);
416 }
417 }
418 return (options);
419 }
420
421 OptionContainer
getModifiedOptions4(const db::ServerSelector & server_selector,const boost::posix_time::ptime & modification_time) const422 TestConfigBackendDHCPv4::getModifiedOptions4(const db::ServerSelector& server_selector,
423 const boost::posix_time::ptime& modification_time) const {
424 auto tags = server_selector.getTags();
425 OptionContainer options;
426 const auto& index = options_.get<3>();
427 auto lb = index.lower_bound(modification_time);
428 for (auto option = lb; option != index.end(); ++option) {
429 bool got = false;
430 for (auto tag : tags) {
431 if (option->hasServerTag(ServerTag(tag))) {
432 options.push_back(*option);
433 got = true;
434 break;
435 }
436 }
437 if (got) {
438 continue;
439 }
440 if (option->hasAllServerTag()) {
441 options.push_back(*option);
442 }
443 }
444 return (options);
445 }
446
447 StampedValuePtr
getGlobalParameter4(const db::ServerSelector & server_selector,const std::string & name) const448 TestConfigBackendDHCPv4::getGlobalParameter4(const db::ServerSelector& server_selector,
449 const std::string& name) const {
450 auto tags = server_selector.getTags();
451 auto candidate = StampedValuePtr();
452 const auto& index = globals_.get<StampedValueNameIndexTag>();
453 auto global_range = index.equal_range(name);
454 for (auto global_it = global_range.first; global_it != global_range.second;
455 ++global_it) {
456 for (auto tag : tags) {
457 if ((*global_it)->hasServerTag(ServerTag(tag))) {
458 return (*global_it);
459 }
460 }
461 if ((*global_it)->hasAllServerTag()) {
462 candidate = *global_it;
463 }
464 }
465
466 return (candidate);
467 }
468
469
470 StampedValueCollection
getAllGlobalParameters4(const db::ServerSelector & server_selector) const471 TestConfigBackendDHCPv4::getAllGlobalParameters4(const db::ServerSelector& server_selector) const {
472 auto tags = server_selector.getTags();
473 StampedValueCollection globals;
474 for (auto global : globals_) {
475 bool got = false;
476 for (auto tag : tags) {
477 if (global->hasServerTag(ServerTag(tag))) {
478 globals.insert(global);
479 got = true;
480 break;
481 }
482 }
483 if (got) {
484 continue;
485 }
486 if (global->hasAllServerTag()) {
487 globals.insert(global);
488 }
489 }
490 return (globals);
491 }
492
493 StampedValueCollection
getModifiedGlobalParameters4(const db::ServerSelector & server_selector,const boost::posix_time::ptime & modification_time) const494 TestConfigBackendDHCPv4::getModifiedGlobalParameters4(const db::ServerSelector& server_selector,
495 const boost::posix_time::ptime& modification_time) const {
496 auto tags = server_selector.getTags();
497 StampedValueCollection globals;
498 const auto& index = globals_.get<StampedValueModificationTimeIndexTag>();
499 auto lb = index.lower_bound(modification_time);
500 for (auto global = lb; global != index.end(); ++global) {
501 bool got = false;
502 for (auto tag : tags) {
503 if ((*global)->hasServerTag(ServerTag(tag))) {
504 globals.insert(*global);
505 got = true;
506 break;
507 }
508 }
509 if (got) {
510 continue;
511 }
512 if ((*global)->hasAllServerTag()) {
513 globals.insert(*global);
514 }
515 }
516 return (globals);
517 }
518
519 ClientClassDefPtr
getClientClass4(const db::ServerSelector & server_selector,const std::string & name) const520 TestConfigBackendDHCPv4::getClientClass4(const db::ServerSelector& server_selector,
521 const std::string& name) const {
522 ClientClassDefPtr client_class;
523 for (auto c : classes_) {
524 if (c->getName() == name) {
525 client_class = c;
526 break;
527 }
528 }
529 if (!client_class || server_selector.amAny()) {
530 return (client_class);
531 }
532 if (server_selector.amUnassigned()) {
533 return (client_class->getServerTags().empty() ? client_class : ClientClassDefPtr());
534 }
535 auto tags = server_selector.getTags();
536 for (auto tag : tags) {
537 if (client_class->hasServerTag(ServerTag(tag))) {
538 return (client_class);
539 }
540 }
541 return (client_class->hasAllServerTag() ? client_class : ClientClassDefPtr());
542 }
543
544 ClientClassDictionary
getAllClientClasses4(const db::ServerSelector & server_selector) const545 TestConfigBackendDHCPv4::getAllClientClasses4(const db::ServerSelector& server_selector) const {
546 auto tags = server_selector.getTags();
547 ClientClassDictionary all_classes;
548 for (auto client_class : classes_) {
549 if (server_selector.amAny()) {
550 all_classes.addClass(client_class);
551 continue;
552 }
553 if (server_selector.amUnassigned()) {
554 if (client_class->getServerTags().empty()) {
555 all_classes.addClass(client_class);
556 }
557 continue;
558 }
559 bool got = false;
560 for (auto tag : tags) {
561 if (client_class->hasServerTag(ServerTag(tag))) {
562 all_classes.addClass(client_class);
563 got = true;
564 break;
565 }
566 }
567 if (got) {
568 continue;
569 }
570 if (client_class->hasAllServerTag()) {
571 all_classes.addClass(client_class);
572 }
573 }
574 return (all_classes);
575 }
576
577 ClientClassDictionary
getModifiedClientClasses4(const db::ServerSelector & server_selector,const boost::posix_time::ptime & modification_time) const578 TestConfigBackendDHCPv4::getModifiedClientClasses4(const db::ServerSelector& server_selector,
579 const boost::posix_time::ptime& modification_time) const {
580 auto tags = server_selector.getTags();
581 ClientClassDictionary modified_classes;
582 for (auto client_class : classes_) {
583 if (client_class->getModificationTime() >= modification_time) {
584 bool got = false;
585 for (auto tag : tags) {
586 if (client_class->hasServerTag(ServerTag(tag))) {
587 modified_classes.addClass(client_class);
588 got = true;
589 break;
590 }
591 }
592 if (got) {
593 continue;
594 }
595 if (client_class->hasAllServerTag()) {
596 modified_classes.addClass(client_class);
597 }
598 }
599 }
600 return (modified_classes);
601 }
602
603 void
createUpdateClientClass4(const db::ServerSelector & server_selector,const ClientClassDefPtr & client_class,const std::string & follow_class_name)604 TestConfigBackendDHCPv4::createUpdateClientClass4(const db::ServerSelector& server_selector,
605 const ClientClassDefPtr& client_class,
606 const std::string& follow_class_name) {
607 int follow_class_index = -1;
608 if (!follow_class_name.empty()) {
609 for (auto i = 0; i < classes_.size(); ++i) {
610 if (classes_[i]->getName() == follow_class_name) {
611 follow_class_index = i;
612 break;
613 }
614 }
615 if (follow_class_index < 0) {
616 isc_throw(BadValue, "class " << follow_class_name << " does not exist");
617
618 }
619 }
620
621 mergeServerTags(client_class, server_selector);
622
623 int existing_class_index = -1;
624 for (auto i = 0; i < classes_.size(); ++i) {
625 if (classes_[i]->getName() == client_class->getName()) {
626 existing_class_index = i;
627 break;
628 }
629 }
630
631 if (follow_class_index < 0) {
632 if (existing_class_index >= 0) {
633 classes_[existing_class_index] = client_class;
634 } else {
635 classes_.push_back(client_class);
636 }
637 } else {
638 if (existing_class_index < 0) {
639 classes_.insert(classes_.begin() + follow_class_index + 1, client_class);
640 } else {
641 classes_.erase(classes_.begin() + existing_class_index);
642 classes_.insert(classes_.begin() + follow_class_index + 1, client_class);
643 }
644 }
645 }
646
647 AuditEntryCollection
getRecentAuditEntries(const db::ServerSelector &,const boost::posix_time::ptime &,const uint64_t &) const648 TestConfigBackendDHCPv4::getRecentAuditEntries(const db::ServerSelector&,
649 const boost::posix_time::ptime&,
650 const uint64_t&) const {
651 return (AuditEntryCollection());
652 }
653
654 ServerCollection
getAllServers4() const655 TestConfigBackendDHCPv4::getAllServers4() const {
656 return (servers_);
657 }
658
659 ServerPtr
getServer4(const ServerTag & server_tag) const660 TestConfigBackendDHCPv4::getServer4(const ServerTag& server_tag) const {
661 const auto& index = servers_.get<ServerTagIndexTag>();
662 auto server_it = index.find(server_tag.get());
663 return ((server_it != index.cend()) ? (*server_it) : ServerPtr());
664 }
665
666 void
createUpdateSubnet4(const db::ServerSelector & server_selector,const Subnet4Ptr & subnet)667 TestConfigBackendDHCPv4::createUpdateSubnet4(const db::ServerSelector& server_selector,
668 const Subnet4Ptr& subnet) {
669 auto& index = subnets_.get<SubnetSubnetIdIndexTag>();
670 auto subnet_it = index.find(subnet->getID());
671
672 mergeServerTags(subnet, server_selector);
673
674 if (subnet_it != index.cend()) {
675 index.replace(subnet_it, subnet);
676 } else {
677 index.insert(subnet);
678 }
679 }
680
681 void
createUpdateSharedNetwork4(const db::ServerSelector & server_selector,const SharedNetwork4Ptr & shared_network)682 TestConfigBackendDHCPv4::createUpdateSharedNetwork4(const db::ServerSelector& server_selector,
683 const SharedNetwork4Ptr& shared_network) {
684 auto& index = shared_networks_.get<SharedNetworkNameIndexTag>();
685 auto network_it = index.find(shared_network->getName());
686
687 mergeServerTags(shared_network, server_selector);
688
689 if (network_it != index.cend()) {
690 index.replace(network_it, shared_network);
691 } else {
692 index.insert(shared_network);
693 }
694 }
695
696 void
createUpdateOptionDef4(const db::ServerSelector & server_selector,const OptionDefinitionPtr & option_def)697 TestConfigBackendDHCPv4::createUpdateOptionDef4(const db::ServerSelector& server_selector,
698 const OptionDefinitionPtr& option_def) {
699 auto tag = getServerTag(server_selector);
700 option_def->setServerTag(tag);
701
702 // Index #1 is by option code.
703 auto& index1 = option_defs_.get<1>();
704 auto option_def_it_pair1 = index1.equal_range(option_def->getCode());
705
706 for (auto option_def_it = option_def_it_pair1.first;
707 option_def_it != option_def_it_pair1.second;
708 option_def_it++) {
709 auto existing_option_def = *option_def_it;
710 if ((existing_option_def->getOptionSpaceName() == option_def->getOptionSpaceName()) &&
711 (existing_option_def->hasServerTag(ServerTag(tag)))) {
712 index1.replace(option_def_it, option_def);
713 return;
714 }
715 }
716
717 // Index #2 is by option name.
718 auto& index2 = option_defs_.get<2>();
719 auto option_def_it_pair2 = index2.equal_range(option_def->getName());
720
721 for (auto option_def_it = option_def_it_pair2.first;
722 option_def_it != option_def_it_pair2.second;
723 option_def_it++) {
724 auto existing_option_def = *option_def_it;
725 if ((existing_option_def->getOptionSpaceName() == option_def->getOptionSpaceName()) &&
726 (existing_option_def->hasServerTag(ServerTag(tag)))) {
727 index2.replace(option_def_it, option_def);
728 return;
729 }
730 }
731
732 option_defs_.push_back(option_def);
733 }
734
735 void
createUpdateOption4(const db::ServerSelector & server_selector,const OptionDescriptorPtr & option)736 TestConfigBackendDHCPv4::createUpdateOption4(const db::ServerSelector& server_selector,
737 const OptionDescriptorPtr& option) {
738 auto tag = getServerTag(server_selector);
739 option->setServerTag(tag);
740
741 auto& index = options_.get<1>();
742 auto option_it_pair = index.equal_range(option->option_->getType());
743
744 for (auto option_it = option_it_pair.first;
745 option_it != option_it_pair.second;
746 ++option_it) {
747 if ((option_it->space_name_ == option->space_name_) &&
748 (option_it->hasServerTag(ServerTag(tag)))) {
749 index.replace(option_it, *option);
750 return;
751 }
752 }
753
754 options_.push_back(*option);
755 }
756
757 void
createUpdateOption4(const db::ServerSelector & server_selector,const std::string & shared_network_name,const OptionDescriptorPtr & option)758 TestConfigBackendDHCPv4::createUpdateOption4(const db::ServerSelector& server_selector,
759 const std::string& shared_network_name,
760 const OptionDescriptorPtr& option) {
761 auto& index = shared_networks_.get<SharedNetworkNameIndexTag>();
762 auto network_it = index.find(shared_network_name);
763
764 if (network_it == index.end()) {
765 isc_throw(BadValue, "attempted to create or update option in a non existing "
766 "shared network " << shared_network_name);
767 }
768
769 auto shared_network = *network_it;
770 bool found = false;
771 if (server_selector.amUnassigned()) {
772 if (shared_network->getServerTags().empty()) {
773 found = true;
774 }
775 } else if (server_selector.amAny()) {
776 found = true;
777 } else if (shared_network->hasAllServerTag()) {
778 found = true;
779 } else {
780 auto tags = server_selector.getTags();
781 for (auto tag : tags) {
782 if (shared_network->hasServerTag(ServerTag(tag))) {
783 found = true;
784 break;
785 }
786 }
787 }
788 if (!found) {
789 isc_throw(BadValue, "attempted to create or update option in a "
790 "shared network " << shared_network_name
791 << " not present in a selected server");
792 }
793
794 shared_network->getCfgOption()->del(option->space_name_, option->option_->getType());
795 shared_network->getCfgOption()->add(*option, option->space_name_);
796 }
797
798 void
createUpdateOption4(const db::ServerSelector & server_selector,const SubnetID & subnet_id,const OptionDescriptorPtr & option)799 TestConfigBackendDHCPv4::createUpdateOption4(const db::ServerSelector& server_selector,
800 const SubnetID& subnet_id,
801 const OptionDescriptorPtr& option) {
802 auto& index = subnets_.get<SubnetSubnetIdIndexTag>();
803 auto subnet_it = index.find(subnet_id);
804
805 if (subnet_it == index.cend()) {
806 isc_throw(BadValue, "attempted to create or update option in a non existing "
807 "subnet ID " << subnet_id);
808 }
809
810 auto subnet = *subnet_it;
811 bool found = false;
812 if (server_selector.amUnassigned()) {
813 if (subnet->getServerTags().empty()) {
814 found = true;
815 }
816 } else if (server_selector.amAny()) {
817 found = true;
818 } else if (subnet->hasAllServerTag()) {
819 found = true;
820 } else {
821 auto tags = server_selector.getTags();
822 for (auto tag : tags) {
823 if (subnet->hasServerTag(ServerTag(tag))) {
824 found = true;
825 break;
826 }
827 }
828 }
829 if (!found) {
830 isc_throw(BadValue, "attempted to create or update option in a "
831 "subnet ID " << subnet_id
832 << " not present in a selected server");
833 }
834
835 subnet->getCfgOption()->del(option->space_name_, option->option_->getType());
836 subnet->getCfgOption()->add(*option, option->space_name_);
837 }
838
839 void
createUpdateOption4(const db::ServerSelector & server_selector,const asiolink::IOAddress & pool_start_address,const asiolink::IOAddress & pool_end_address,const OptionDescriptorPtr & option)840 TestConfigBackendDHCPv4::createUpdateOption4(const db::ServerSelector& server_selector,
841 const asiolink::IOAddress& pool_start_address,
842 const asiolink::IOAddress& pool_end_address,
843 const OptionDescriptorPtr& option) {
844 auto not_in_selected_servers = false;
845 for (auto subnet : subnets_) {
846 // Get the pool: if it is not here we can directly go to the next subnet.
847 auto pool = subnet->getPool(Lease::TYPE_V4, pool_start_address);
848 if (!pool) {
849 continue;
850 }
851
852 // Verify the subnet is in a selected server.
853 if (server_selector.amUnassigned()) {
854 if (!subnet->getServerTags().empty()) {
855 not_in_selected_servers = true;
856 continue;
857 }
858 } else if (!server_selector.amAny() && !subnet->hasAllServerTag()) {
859 auto in_tags = false;
860 auto tags = server_selector.getTags();
861 for (auto tag : tags) {
862 if (subnet->hasServerTag(ServerTag(tag))) {
863 in_tags = true;
864 break;
865 }
866 }
867 if (!in_tags) {
868 // Records the fact a subnet was found but not in a server.
869 not_in_selected_servers = true;
870 continue;
871 }
872 }
873
874 // Update the option.
875 pool->getCfgOption()->del(option->space_name_, option->option_->getType());
876 pool->getCfgOption()->add(*option, option->space_name_);
877
878 return;
879 }
880
881 if (not_in_selected_servers) {
882 isc_throw(BadValue, "attempted to create or update option in "
883 "a pool " << pool_start_address
884 << " - " << pool_end_address
885 << " not present in a selected server");
886 } else {
887 isc_throw(BadValue, "attempted to create or update option in "
888 "a non existing pool " << pool_start_address
889 << " - " << pool_end_address);
890 }
891 }
892
893 void
createUpdateGlobalParameter4(const db::ServerSelector & server_selector,const data::StampedValuePtr & value)894 TestConfigBackendDHCPv4::createUpdateGlobalParameter4(const db::ServerSelector& server_selector,
895 const data::StampedValuePtr& value) {
896 auto tag = getServerTag(server_selector);
897 value->setServerTag(tag);
898
899 auto& index = globals_.get<StampedValueNameIndexTag>();
900 auto global_it_pair = index.equal_range(value->getName());
901
902 for (auto global_it = global_it_pair.first; global_it != global_it_pair.second;
903 ++global_it) {
904 auto existing_value = *global_it;
905 if (existing_value->hasServerTag(ServerTag(tag))) {
906 index.replace(global_it, value);
907 return;
908 }
909 }
910
911 index.insert(value);
912 }
913
914 void
createUpdateServer4(const db::ServerPtr & server)915 TestConfigBackendDHCPv4::createUpdateServer4(const db::ServerPtr& server) {
916 auto& index = servers_.get<ServerTagIndexTag>();
917 auto server_it = index.find(server->getServerTagAsText());
918
919 if (server_it != index.end()) {
920 index.replace(server_it, server);
921
922 } else {
923 index.insert(server);
924 }
925 }
926
927 uint64_t
deleteSubnet4(const db::ServerSelector & server_selector,const std::string & subnet_prefix)928 TestConfigBackendDHCPv4::deleteSubnet4(const db::ServerSelector& server_selector,
929 const std::string& subnet_prefix) {
930 auto& index = subnets_.get<SubnetPrefixIndexTag>();
931 auto subnet_it = index.find(subnet_prefix);
932 if (subnet_it == index.end()) {
933 return (0);
934 }
935 if ((server_selector.amUnassigned()) &&
936 !(*subnet_it)->getServerTags().empty()) {
937 return (0);
938 }
939 if (!server_selector.amAny()) {
940 bool got = false;
941 auto tags = server_selector.getTags();
942 for (auto tag : tags) {
943 if ((*subnet_it)->hasServerTag(ServerTag(tag))) {
944 got = true;
945 break;
946 }
947 }
948 if (!got && !(*subnet_it)->hasAllServerTag()) {
949 return (0);
950 }
951 }
952 return (index.erase(subnet_prefix));
953 }
954
955 uint64_t
deleteSubnet4(const db::ServerSelector & server_selector,const SubnetID & subnet_id)956 TestConfigBackendDHCPv4::deleteSubnet4(const db::ServerSelector& server_selector,
957 const SubnetID& subnet_id) {
958 auto& index = subnets_.get<SubnetSubnetIdIndexTag>();
959 auto subnet_it = index.find(subnet_id);
960 if (subnet_it == index.end()) {
961 return (0);
962 }
963 if ((server_selector.amUnassigned()) &&
964 !(*subnet_it)->getServerTags().empty()) {
965 return (0);
966 }
967 if (!server_selector.amAny()) {
968 bool got = false;
969 auto tags = server_selector.getTags();
970 for (auto tag : tags) {
971 if ((*subnet_it)->hasServerTag(ServerTag(tag))) {
972 got = true;
973 break;
974 }
975 }
976 if (!got && !(*subnet_it)->hasAllServerTag()) {
977 return (0);
978 }
979 }
980 return (index.erase(subnet_id));
981 }
982
983 uint64_t
deleteAllSubnets4(const db::ServerSelector & server_selector)984 TestConfigBackendDHCPv4::deleteAllSubnets4(const db::ServerSelector& server_selector) {
985 // Collect subnet to remove by ID.
986 std::list<SubnetID> ids;
987 for (auto subnet : subnets_) {
988 if (server_selector.amAny()) {
989 ids.push_back(subnet->getID());
990 continue;
991 }
992 if (server_selector.amUnassigned()) {
993 if (subnet->getServerTags().empty()) {
994 ids.push_back(subnet->getID());
995 }
996 continue;
997 }
998 bool got = false;
999 auto tags = server_selector.getTags();
1000 for (auto tag : tags) {
1001 if (subnet->hasServerTag(ServerTag(tag))) {
1002 ids.push_back(subnet->getID());
1003 got = true;
1004 break;
1005 }
1006 }
1007 if (got) {
1008 continue;
1009 }
1010 if (subnet->hasAllServerTag()) {
1011 ids.push_back(subnet->getID());
1012 }
1013 }
1014
1015 // Erase subnets.
1016 uint64_t erased = 0;
1017 auto& index = subnets_.get<SubnetSubnetIdIndexTag>();
1018 for (auto subnet_id : ids) {
1019 erased += index.erase(subnet_id);
1020 }
1021 return (erased);
1022 }
1023
1024 uint64_t
deleteSharedNetworkSubnets4(const db::ServerSelector & server_selector,const std::string & shared_network_name)1025 TestConfigBackendDHCPv4::deleteSharedNetworkSubnets4(const db::ServerSelector& server_selector,
1026 const std::string& shared_network_name) {
1027 uint64_t cnt = 0;
1028 for (auto subnet = subnets_.begin(); subnet != subnets_.end(); ) {
1029 // Skip subnets which do not match the server selector.
1030 if (server_selector.amUnassigned() &&
1031 !(*subnet)->getServerTags().empty()) {
1032 ++subnet;
1033 continue;
1034 }
1035 if (!server_selector.amAny()) {
1036 bool got = false;
1037 auto tags = server_selector.getTags();
1038 for (auto tag : tags) {
1039 if ((*subnet)->hasServerTag(ServerTag(tag))) {
1040 got = true;
1041 break;
1042 }
1043 }
1044 if (!got && !(*subnet)->hasAllServerTag()) {
1045 ++subnet;
1046 continue;
1047 }
1048 }
1049
1050 SharedNetwork4Ptr network;
1051 (*subnet)->getSharedNetwork(network);
1052 if (network && (network->getName() == shared_network_name)) {
1053 network->del((*subnet)->getID());
1054 }
1055
1056 if ((network && (network->getName() == shared_network_name)) ||
1057 ((*subnet)->getSharedNetworkName() == shared_network_name)) {
1058 subnet = subnets_.erase(subnet);
1059 ++cnt;
1060 } else {
1061 ++subnet;
1062 }
1063 }
1064 return (cnt);
1065 }
1066
1067 uint64_t
deleteSharedNetwork4(const db::ServerSelector & server_selector,const std::string & name)1068 TestConfigBackendDHCPv4::deleteSharedNetwork4(const db::ServerSelector& server_selector,
1069 const std::string& name) {
1070 auto& index = shared_networks_.get<SharedNetworkNameIndexTag>();
1071 auto network_it = index.find(name);
1072 if (network_it == index.end()) {
1073 return (0);
1074 }
1075 if ((server_selector.amUnassigned()) &&
1076 !(*network_it)->getServerTags().empty()) {
1077 return (0);
1078 }
1079 if (!server_selector.amAny()) {
1080 bool got = false;
1081 auto tags = server_selector.getTags();
1082 for (auto tag : tags) {
1083 if ((*network_it)->hasServerTag(ServerTag(tag))) {
1084 got = true;
1085 break;
1086 }
1087 }
1088 if (!got && !(*network_it)->hasAllServerTag()) {
1089 return (0);
1090 }
1091 }
1092
1093 // Remove this shared network.
1094 for (auto subnet = subnets_.begin(); subnet != subnets_.end(); ++subnet) {
1095 if ((*subnet)->getSharedNetworkName() == name) {
1096 (*subnet)->setSharedNetworkName("");
1097 }
1098 }
1099 (*network_it)->delAll();
1100 return (index.erase(name));
1101 }
1102
1103 uint64_t
deleteAllSharedNetworks4(const db::ServerSelector & server_selector)1104 TestConfigBackendDHCPv4::deleteAllSharedNetworks4(const db::ServerSelector& server_selector) {
1105 // Collect shared network to remove.
1106 std::list<std::string> names;
1107 for (auto shared_network : shared_networks_) {
1108 if (server_selector.amAny()) {
1109 names.push_back(shared_network->getName());
1110 continue;
1111 }
1112 if (server_selector.amUnassigned()) {
1113 if (shared_network->getServerTags().empty()) {
1114 names.push_back(shared_network->getName());
1115 }
1116 continue;
1117 }
1118 bool got = false;
1119 auto tags = server_selector.getTags();
1120 for (auto tag : tags) {
1121 if (shared_network->hasServerTag(ServerTag(tag))) {
1122 names.push_back(shared_network->getName());
1123 got = true;
1124 break;
1125 }
1126 }
1127 if (got) {
1128 continue;
1129 }
1130 if (shared_network->hasAllServerTag()) {
1131 names.push_back(shared_network->getName());
1132 }
1133 }
1134
1135 // Erase shared networks.
1136 uint64_t erased = 0;
1137 auto& index = shared_networks_.get<SharedNetworkNameIndexTag>();
1138 for (auto name : names) {
1139 erased += index.erase(name);
1140 }
1141 return (erased);
1142 }
1143
1144 uint64_t
deleteOptionDef4(const db::ServerSelector & server_selector,const uint16_t code,const std::string & space)1145 TestConfigBackendDHCPv4::deleteOptionDef4(const db::ServerSelector& server_selector,
1146 const uint16_t code,
1147 const std::string& space) {
1148 auto tag = getServerTag(server_selector);
1149 uint64_t erased = 0;
1150 for (auto option_def_it = option_defs_.begin(); option_def_it != option_defs_.end(); ) {
1151 if (((*option_def_it)->getCode() == code) &&
1152 ((*option_def_it)->getOptionSpaceName() == space) &&
1153 ((*option_def_it)->hasServerTag(ServerTag(tag)))) {
1154 option_def_it = option_defs_.erase(option_def_it);
1155 ++erased;
1156 } else {
1157 ++option_def_it;
1158 }
1159 }
1160 return (erased);
1161 }
1162
1163 uint64_t
deleteAllOptionDefs4(const db::ServerSelector & server_selector)1164 TestConfigBackendDHCPv4::deleteAllOptionDefs4(const db::ServerSelector& server_selector) {
1165 auto tag = getServerTag(server_selector);
1166 uint64_t erased = 0;
1167 for (auto option_def_it = option_defs_.begin(); option_def_it != option_defs_.end(); ) {
1168 if ((*option_def_it)->hasServerTag(ServerTag(tag))) {
1169 option_def_it = option_defs_.erase(option_def_it);
1170 ++erased;
1171 } else {
1172 ++option_def_it;
1173 }
1174 }
1175 return (erased);
1176 }
1177
1178 uint64_t
deleteOption4(const db::ServerSelector & server_selector,const uint16_t code,const std::string & space)1179 TestConfigBackendDHCPv4::deleteOption4(const db::ServerSelector& server_selector,
1180 const uint16_t code,
1181 const std::string& space) {
1182 auto tag = getServerTag(server_selector);
1183 uint64_t erased = 0;
1184 for (auto option_it = options_.begin(); option_it != options_.end(); ) {
1185 if ((option_it->option_->getType() == code) &&
1186 (option_it->space_name_ == space) &&
1187 (option_it->hasServerTag(ServerTag(tag)))) {
1188 option_it = options_.erase(option_it);
1189 ++erased;
1190 } else {
1191 ++option_it;
1192 }
1193 }
1194 return (erased);
1195 }
1196
1197 uint64_t
deleteOption4(const db::ServerSelector & server_selector,const std::string & shared_network_name,const uint16_t code,const std::string & space)1198 TestConfigBackendDHCPv4::deleteOption4(const db::ServerSelector& server_selector,
1199 const std::string& shared_network_name,
1200 const uint16_t code,
1201 const std::string& space) {
1202 auto& index = shared_networks_.get<SharedNetworkNameIndexTag>();
1203 auto network_it = index.find(shared_network_name);
1204
1205 if (network_it == index.end()) {
1206 isc_throw(BadValue, "attempted to delete an option in a non existing "
1207 "shared network " << shared_network_name);
1208 }
1209
1210 auto shared_network = *network_it;
1211 bool found = false;
1212 if (server_selector.amUnassigned()) {
1213 if (shared_network->getServerTags().empty()) {
1214 found = true;
1215 }
1216 } else if (server_selector.amAny()) {
1217 found = true;
1218 } else if (shared_network->hasAllServerTag()) {
1219 found = true;
1220 } else {
1221 auto tags = server_selector.getTags();
1222 for (auto tag : tags) {
1223 if (shared_network->hasServerTag(ServerTag(tag))) {
1224 found = true;
1225 break;
1226 }
1227 }
1228 }
1229 if (!found) {
1230 isc_throw(BadValue, "attempted to delete option in a "
1231 "shared network " << shared_network_name
1232 << " not present in a selected server");
1233 }
1234
1235 return (shared_network->getCfgOption()->del(space, code));
1236 }
1237
1238 uint64_t
deleteOption4(const db::ServerSelector & server_selector,const SubnetID & subnet_id,const uint16_t code,const std::string & space)1239 TestConfigBackendDHCPv4::deleteOption4(const db::ServerSelector& server_selector,
1240 const SubnetID& subnet_id,
1241 const uint16_t code,
1242 const std::string& space) {
1243 auto& index = subnets_.get<SubnetSubnetIdIndexTag>();
1244 auto subnet_it = index.find(subnet_id);
1245
1246 if (subnet_it == index.cend()) {
1247 isc_throw(BadValue, "attempted to delete an option in a non existing "
1248 "subnet ID " << subnet_id);
1249 }
1250
1251 auto subnet = *subnet_it;
1252 bool found = false;
1253 if (server_selector.amUnassigned()) {
1254 if (subnet->getServerTags().empty()) {
1255 found = true;
1256 }
1257 } else if (server_selector.amAny()) {
1258 found = true;
1259 } else if (subnet->hasAllServerTag()) {
1260 found = true;
1261 } else {
1262 auto tags = server_selector.getTags();
1263 for (auto tag : tags) {
1264 if (subnet->hasServerTag(ServerTag(tag))) {
1265 found = true;
1266 break;
1267 }
1268 }
1269 }
1270 if (!found) {
1271 isc_throw(BadValue, "attempted to delete option in a "
1272 "subnet ID " << subnet_id
1273 << " not present in a selected server");
1274 }
1275
1276 return (subnet->getCfgOption()->del(space, code));
1277 }
1278
1279 uint64_t
deleteOption4(const db::ServerSelector & server_selector,const asiolink::IOAddress & pool_start_address,const asiolink::IOAddress & pool_end_address,const uint16_t code,const std::string & space)1280 TestConfigBackendDHCPv4::deleteOption4(const db::ServerSelector& server_selector,
1281 const asiolink::IOAddress& pool_start_address,
1282 const asiolink::IOAddress& pool_end_address,
1283 const uint16_t code,
1284 const std::string& space) {
1285 auto not_in_selected_servers = false;
1286 for (auto subnet : subnets_) {
1287 // Get the pool: if it is not here we can directly go to the next subnet.
1288
1289 auto pool = subnet->getPool(Lease::TYPE_V4, pool_start_address);
1290 if (!pool) {
1291 continue;
1292 }
1293
1294 // Verify the subnet is in a selected server.
1295 if (server_selector.amUnassigned()) {
1296 if (!subnet->getServerTags().empty()) {
1297 not_in_selected_servers = true;
1298 continue;
1299 }
1300 } else if (!server_selector.amAny() && !subnet->hasAllServerTag()) {
1301 auto in_tags = false;
1302 auto tags = server_selector.getTags();
1303 for (auto tag : tags) {
1304 if (subnet->hasServerTag(ServerTag(tag))) {
1305 in_tags = true;
1306 break;
1307 }
1308 }
1309 if (!in_tags) {
1310 // Records the fact a subnet was found but not in a server.
1311 not_in_selected_servers = true;
1312 continue;
1313 }
1314 }
1315
1316 return (pool->getCfgOption()->del(space, code));
1317 }
1318
1319 if (not_in_selected_servers) {
1320 isc_throw(BadValue, "attempted to delete an option in a pool "
1321 << pool_start_address << " - " << pool_end_address
1322 << " not present in a selected server");
1323 } else {
1324 isc_throw(BadValue, "attempted to delete an option in a non existing "
1325 "pool " << pool_start_address << " - " << pool_end_address);
1326 }
1327 }
1328
1329 uint64_t
deleteGlobalParameter4(const db::ServerSelector & server_selector,const std::string & name)1330 TestConfigBackendDHCPv4::deleteGlobalParameter4(const db::ServerSelector& server_selector,
1331 const std::string& name) {
1332 auto tag = getServerTag(server_selector);
1333 auto& index = globals_.get<StampedValueNameIndexTag>();
1334 auto global_it_pair = index.equal_range(name);
1335
1336 for (auto global_it = global_it_pair.first; global_it != global_it_pair.second;
1337 ++global_it) {
1338 auto value = *global_it;
1339 if (value->hasServerTag(ServerTag(tag))) {
1340 index.erase(global_it);
1341 return (1);
1342 }
1343 }
1344 return (0);
1345 }
1346
1347 uint64_t
deleteAllGlobalParameters4(const db::ServerSelector & server_selector)1348 TestConfigBackendDHCPv4::deleteAllGlobalParameters4(const db::ServerSelector& server_selector) {
1349 auto tag = getServerTag(server_selector);
1350 uint64_t cnt = 0;
1351 for (auto global_it = globals_.begin(); global_it != globals_.end(); ) {
1352 auto value = *global_it;
1353 if (value->hasServerTag(ServerTag(tag))) {
1354 global_it = globals_.erase(global_it);
1355 cnt++;
1356 } else {
1357 ++global_it;
1358 }
1359 }
1360 return (cnt);
1361 }
1362
1363 uint64_t
deleteClientClass4(const db::ServerSelector & server_selector,const std::string & name)1364 TestConfigBackendDHCPv4::deleteClientClass4(const db::ServerSelector& server_selector,
1365 const std::string& name) {
1366 ClientClassDefPtr existing_class;
1367 auto c = classes_.begin();
1368 for (; c != classes_.end(); ++c) {
1369 if ((*c)->getName() == name) {
1370 existing_class = (*c);
1371 break;
1372 }
1373 }
1374 if (!existing_class) {
1375 return (0);
1376 }
1377 if ((server_selector.amUnassigned()) &&
1378 !existing_class->getServerTags().empty()) {
1379 return (0);
1380 }
1381 if (!server_selector.amAny()) {
1382 bool got = false;
1383 auto tags = server_selector.getTags();
1384 for (auto tag : tags) {
1385 if (existing_class->hasServerTag(ServerTag(tag))) {
1386 got = true;
1387 break;
1388 }
1389 }
1390 if (!got && !existing_class->hasAllServerTag()) {
1391 return (0);
1392 }
1393 }
1394 classes_.erase(c);
1395 return (1);
1396 }
1397
1398 uint64_t
deleteAllClientClasses4(const db::ServerSelector & server_selector)1399 TestConfigBackendDHCPv4::deleteAllClientClasses4(const db::ServerSelector& server_selector) {
1400 uint64_t count = 0;
1401 for (auto c = classes_.begin(); c != classes_.end(); ++c) {
1402 auto client_class = *c;
1403 if (server_selector.amAny()) {
1404 c = classes_.erase(c);
1405 ++count;
1406 continue;
1407 }
1408 if (server_selector.amUnassigned()) {
1409 if (client_class->getServerTags().empty()) {
1410 c = classes_.erase(c);
1411 ++count;
1412 }
1413 continue;
1414 }
1415 bool got = false;
1416 auto tags = server_selector.getTags();
1417 for (auto tag : tags) {
1418 if (client_class->hasServerTag(ServerTag(tag))) {
1419 c = classes_.erase(c);
1420 ++count;
1421 got = true;
1422 break;
1423 }
1424 }
1425 if (got) {
1426 continue;
1427 }
1428 if (client_class->hasAllServerTag()) {
1429 c = classes_.erase(c);
1430 ++count;
1431 }
1432 }
1433
1434 return (count);
1435 }
1436
1437 uint64_t
deleteServer4(const ServerTag & server_tag)1438 TestConfigBackendDHCPv4::deleteServer4(const ServerTag& server_tag) {
1439 auto& index = servers_.get<ServerTagIndexTag>();
1440 return (index.erase(server_tag.get()));
1441 }
1442
1443 uint64_t
deleteAllServers4()1444 TestConfigBackendDHCPv4::deleteAllServers4() {
1445 auto servers_size = servers_.size();
1446 servers_.clear();
1447 return (servers_size);
1448 }
1449
1450 } // namespace test
1451 } // namespace dhcp
1452 } // namespace isc
1453