From: Peter van Dijk Date: Thu, 13 Nov 2025 10:33:16 +0000 (+0100) Subject: pdnsutil: add rrset comment management X-Git-Tag: auth-5.1.0-beta1~10^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=df31063013b230d2dcb2feb28a7e717ae875f49a;p=thirdparty%2Fpdns.git pdnsutil: add rrset comment management Signed-off-by: Peter van Dijk --- diff --git a/pdns/pdnsutil.cc b/pdns/pdnsutil.cc index afbe28f3e9..c3cae5b75d 100644 --- a/pdns/pdnsutil.cc +++ b/pdns/pdnsutil.cc @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -86,6 +87,8 @@ static int activateTSIGKey(vector& cmds, std::string_view synopsis); static int activateZoneKey(vector& cmds, std::string_view synopsis); static int addAutoprimary(vector& cmds, std::string_view synopsis); static int addMeta(vector& cmds, std::string_view synopsis); +static int addComment(vector& cmds, std::string_view synopsis); +static int listComments(vector& cmds, std::string_view synopsis); static int addRecord(vector& cmds, std::string_view synopsis); static int addZoneKey(vector& cmds, std::string_view synopsis); static int backendCmd(vector& cmds, std::string_view synopsis); @@ -282,7 +285,13 @@ static const groupCommandDispatcher rrsetCommands{ "\tCalculate the NSEC3 hash for NAME in ZONE"}}, {"replace", {true, replaceRRSet, R"(ZONE NAME TYPE [TTL] "CONTENT" ["CONTENT"...])", - "\tReplace named rrset from ZONE"}}} + "\tReplace named rrset from ZONE"}}, + {"add-comment", {true, addComment, + "ZONE NAME TYPE COMMENT [ACCOUNT]", + "\tAdd a comment"}}, + {"list-comments", {true, listComments, + "ZONE", + "\tList comments for a zone"}}} }; // TSIG-KEY / TSIGKEY @@ -1878,6 +1887,30 @@ static int listZone(const ZoneName &zone) { return EXIT_SUCCESS; } +static int listComments(const ZoneName &zone) { + UtilBackend B; //NOLINT(readability-identifier-length) + DomainInfo di; //NOLINT(readability-identifier-length) + + if (! B.getDomainInfo(zone, di)) { + cerr << "Zone '" << zone << "' not found!" << endl; + return EXIT_FAILURE; + } + if ((di.backend->getCapabilities() & DNSBackend::CAP_COMMENTS) == 0) { + cerr << "Backend for zone '" << zone << "' does not support listing its comments." << endl; + return EXIT_FAILURE; + } + + Comment comment; + + di.backend->listComments(di.id); + while(di.backend->getComment(comment)) { + cout<& cmds, const std::string_vi } } +static int addComment(vector& cmds, const std::string_view synopsis) +{ + if(cmds.size() < 4) { + return usage(synopsis); + } + + UtilBackend B; //NOLINT(readability-identifier-length) + DomainInfo di; //NOLINT(readability-identifier-length) + ZoneName zone(cmds.at(0)); + if (!B.getDomainInfo(zone, di)) { + cerr << "Zone '" << zone << "' doesn't exist" << endl; + return EXIT_FAILURE; + } + + Comment comment; + + comment.domain_id = di.id; + comment.qname = DNSName(cmds.at(1)); + comment.qtype = cmds.at(2); + comment.content = cmds.at(3); + if(cmds.size() > 4) { + comment.account = cmds.at(4); + } + comment.modified_at = time(nullptr); + + if (!comment.qname.isPartOf(zone)) { + cerr << "Name \"" << comment.qname.toString() << "\" to add comment to is not part of zone \"" << zone.toString() << "\"." << endl; + return EXIT_FAILURE; + } + + di.backend->startTransaction(zone, UnknownDomainID); + if (!di.backend->feedComment(comment)) { + cerr << "Backend does not support comments" << endl; + di.backend->abortTransaction(); + return EXIT_FAILURE; + } + + di.backend->commitTransaction(); + return EXIT_SUCCESS; +} + +static int listComments(vector& cmds, const std::string_view synopsis) +{ + if(cmds.size() != 1) { + return usage(synopsis); + } + if (cmds.at(0) == ".") { + cmds.at(0).clear(); + } + + return listComments(ZoneName(cmds.at(0))); +} + + static int addRecord(vector& cmds, const std::string_view synopsis) { if(cmds.size() < 4) {