From: Otto Moerbeek Date: Fri, 22 Nov 2024 10:40:02 +0000 (+0100) Subject: Basic functionality works X-Git-Tag: dnsdist-2.0.0-alpha1~95^2~34 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=71e102dd547ed8717b6004c79c2214ae27f22fbc;p=thirdparty%2Fpdns.git Basic functionality works --- diff --git a/pdns/recursordist/Makefile.am b/pdns/recursordist/Makefile.am index 92dcd7583a..5bf734313e 100644 --- a/pdns/recursordist/Makefile.am +++ b/pdns/recursordist/Makefile.am @@ -328,6 +328,7 @@ testrunner_SOURCES = \ rec-system-resolve.hh rec-system-resolve.cc \ rec-taskqueue.cc rec-taskqueue.hh \ rec-tcounters.cc rec-tcounters.hh \ + rec-web-stubs.hh \ rec-xfrtracker.cc \ rec-zonetocache.cc rec-zonetocache.hh \ recpacketcache.cc recpacketcache.hh \ @@ -543,6 +544,7 @@ rec_control_SOURCES = \ rec-system-resolve.cc rec-system-resolve.hh \ rec_channel.cc rec_channel.hh \ rec_control.cc \ + rec-web-stubs.hh \ settings/cxxsupport.cc \ sillyrecords.cc \ sortlist.cc sortlist.hh \ diff --git a/pdns/recursordist/rec-web-stubs.hh b/pdns/recursordist/rec-web-stubs.hh new file mode 100644 index 0000000000..bf9e68ff01 --- /dev/null +++ b/pdns/recursordist/rec-web-stubs.hh @@ -0,0 +1,15 @@ +namespace pdns::rust::web::rec { +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define WRAPPER(A) void A(const Request& /* unused */ , Response& /* unused */) { } + +WRAPPER(jsonstat) +WRAPPER(apiServerCacheFlush) +WRAPPER(apiServerDetail) +WRAPPER(apiServerZonesGET) +WRAPPER(apiServerZonesPOST) +WRAPPER(prometheusMetrics) +WRAPPER(serveStuff) +WRAPPER(apiServerStatistics) + +#undef WRAPPER +} diff --git a/pdns/recursordist/rec_control.cc b/pdns/recursordist/rec_control.cc index 3e1a935704..a7936cfba5 100644 --- a/pdns/recursordist/rec_control.cc +++ b/pdns/recursordist/rec_control.cc @@ -448,23 +448,5 @@ int main(int argc, char** argv) return 1; } } +#include "rec-web-stubs.hh" -void pdns::rust::web::rec::serveStuff(const pdns::rust::web::rec::Request& /* unused */, pdns::rust::web::rec::Response& /* unused */) -{ -} - -void pdns::rust::web::rec::prometheusMetrics(const pdns::rust::web::rec::Request& /* unused */, pdns::rust::web::rec::Response& /* unused */) -{ -} - -void pdns::rust::web::rec::apiServerZonesGET(const pdns::rust::web::rec::Request& /* unused */, pdns::rust::web::rec::Response& /* unused */) -{ -} - -void pdns::rust::web::rec::apiServerCacheFlush(const pdns::rust::web::rec::Request& /* unused */, pdns::rust::web::rec::Response& /* unused */) -{ -} - -void pdns::rust::web::rec::apiServerZonesPOST(const pdns::rust::web::rec::Request& /* unused */, pdns::rust::web::rec::Response& /* unused */) -{ -} diff --git a/pdns/recursordist/settings/Makefile.am b/pdns/recursordist/settings/Makefile.am index 8d186d14aa..7bfd21922a 100644 --- a/pdns/recursordist/settings/Makefile.am +++ b/pdns/recursordist/settings/Makefile.am @@ -22,7 +22,7 @@ BUILT_SOURCES=cxxsettings-generated.cc rust/src/lib.rs # with an rust/src/lib.rs.h that does not contain e.g. field name or field type changes. # # Use patterns to avoid having two instances of generate run simultaneously, a well-known hack for GNU make -cxxsettings-generated%cc rust/src/lib%rs: table.py generate.py rust-preamble-in.rs rust-bridge-in.rs docs-old-preamble-in.rst docs-new-preamble-in.rst +cxxsettings-generated%cc rust/src/lib%rs rust/src/web%rs: table.py generate.py rust-preamble-in.rs rust-bridge-in.rs docs-old-preamble-in.rst docs-new-preamble-in.rst @if test "$(PYTHON)" = ":"; then echo "Settings table table.py has changed, python is needed to regenerate the related settings files but python was not found. Please install python and re-run configure"; exit 1; fi @if ! $(PYTHON) --version | grep -q "Python 3"; then echo $(PYTHON) should be at least version 3. Please install python 3 and re-run configure; exit 1; fi $(MAKE) -C rust clean diff --git a/pdns/recursordist/settings/rust/.gitignore b/pdns/recursordist/settings/rust/.gitignore index eacb110ccd..d31bd391e7 100644 --- a/pdns/recursordist/settings/rust/.gitignore +++ b/pdns/recursordist/settings/rust/.gitignore @@ -3,5 +3,6 @@ /Makefile.in /cxx.h /lib.rs.h +/web.rs.h src/lib.rs .dir-locals.el diff --git a/pdns/recursordist/settings/rust/Makefile.am b/pdns/recursordist/settings/rust/Makefile.am index ae99af21eb..6299a9f51e 100644 --- a/pdns/recursordist/settings/rust/Makefile.am +++ b/pdns/recursordist/settings/rust/Makefile.am @@ -7,7 +7,8 @@ EXTRA_DIST = \ Cargo.lock \ build.rs \ src/bridge.rs \ - src/helpers.rs + src/helpers.rs \ + src/web.rs # should actually end up in a target specific dir... libsettings.a lib.rs.h: src/web.rs src/bridge.rs src/lib.rs src/helpers.rs Cargo.toml Cargo.lock build.rs diff --git a/pdns/recursordist/settings/rust/src/bridge.hh b/pdns/recursordist/settings/rust/src/bridge.hh index eca7324d9f..4ab8f387f8 100644 --- a/pdns/recursordist/settings/rust/src/bridge.hh +++ b/pdns/recursordist/settings/rust/src/bridge.hh @@ -35,9 +35,12 @@ namespace pdns::rust::web::rec struct KeyValue; struct Request; struct Response; -void serveStuff(const Request& rustRequest, Response& rustResponse); -void prometheusMetrics(const Request& rustRequest, Response& rustResponse); void apiServerCacheFlush(const Request& rustRequest, Response& rustResponse); +void apiServerDetail(const Request& rustRequest, Response& rustResponse); +void apiServerStatistics(const Request& rustRequest, Response& rustResponse); void apiServerZonesGET(const Request& rustRequest,Response& rustResponse); void apiServerZonesPOST(const Request& rustRequest, Response& rustResponse); +void prometheusMetrics(const Request& rustRequest, Response& rustResponse); +void serveStuff(const Request& rustRequest, Response& rustResponse); +void jsonstat(const Request& rustRequest, Response& rustResponse); } diff --git a/pdns/recursordist/settings/rust/src/web.rs b/pdns/recursordist/settings/rust/src/web.rs index 2ac5f2b6d2..db56e23a7f 100644 --- a/pdns/recursordist/settings/rust/src/web.rs +++ b/pdns/recursordist/settings/rust/src/web.rs @@ -60,14 +60,12 @@ fn api_wrapper( header::HeaderValue::from_static("default-src 'self'; style-src 'self' 'unsafe-inline'"), ); - println!("api_wrapper A0 Status {}", response.status); match handler(request, response) { Ok(_) => {} Err(_) => { response.status = StatusCode::UNPROCESSABLE_ENTITY.as_u16(); // 422 } } - println!("api_wrapper A Status {}", response.status); } async fn hello( @@ -101,8 +99,13 @@ async fn hello( }; let headers = rust_response.headers_mut().expect("no headers?"); match (rust_request.method(), rust_request.uri().path()) { - (&Method::GET, "/metrics") => { - rustweb::prometheusMetrics(&request, &mut response).unwrap(); + (&Method::GET, "/jsonstat") => { + api_wrapper( + rustweb::jsonstat as Func, + &request, + &mut response, + headers, + ); } (&Method::PUT, "/api/v1/servers/localhost/cache/flush") => { api_wrapper( @@ -112,8 +115,15 @@ async fn hello( headers, ); } + (&Method::GET, "/api/v1/servers/localhost/statistics") => { + api_wrapper( + rustweb::apiServerStatistics as Func, + &request, + &mut response, + headers, + ); + } (&Method::GET, "/api/v1/servers/localhost/zones") => { - println!("hello Status {}", response.status); api_wrapper( rustweb::apiServerZonesGET as Func, &request, @@ -130,6 +140,17 @@ async fn hello( headers, ); } + (&Method::GET, "/api/v1/servers/localhost") => { + api_wrapper( + rustweb::apiServerDetail as Func, + &request, + &mut response, + headers, + ); + } + (&Method::GET, "/metrics") => { + rustweb::prometheusMetrics(&request, &mut response).unwrap(); + } _ => { let mut path = rust_request.uri().path(); if path == "/" { @@ -147,7 +168,6 @@ async fn hello( } } } - println!("B Status {}", response.status); let mut rust_response = rust_response .status(StatusCode::from_u16(response.status).unwrap()) .body(full(response.body))?; @@ -267,10 +287,13 @@ mod rustweb { unsafe extern "C++" { include!("bridge.hh"); - fn serveStuff(request: &Request, response: &mut Response) -> Result<()>; - fn prometheusMetrics(request: &Request, response: &mut Response) -> Result<()>; fn apiServerCacheFlush(request: &Request, response: &mut Response) -> Result<()>; + fn apiServerDetail(requst: &Request, response: &mut Response) -> Result<()>; + fn apiServerStatistics(requst: &Request, response: &mut Response) -> Result<()>; fn apiServerZonesGET(request: &Request, response: &mut Response) -> Result<()>; fn apiServerZonesPOST(requst: &Request, response: &mut Response) -> Result<()>; + fn jsonstat(request: &Request, response: &mut Response) -> Result<()>; + fn prometheusMetrics(request: &Request, response: &mut Response) -> Result<()>; + fn serveStuff(request: &Request, response: &mut Response) -> Result<()>; } } diff --git a/pdns/recursordist/test-syncres_cc.cc b/pdns/recursordist/test-syncres_cc.cc index a6447f230b..a38c156943 100644 --- a/pdns/recursordist/test-syncres_cc.cc +++ b/pdns/recursordist/test-syncres_cc.cc @@ -591,23 +591,4 @@ LWResult::Result basicRecordsForQnameMinimization(LWResult* res, const DNSName& return LWResult::Result::Timeout; } -void pdns::rust::web::rec::serveStuff(const pdns::rust::web::rec::Request& /* unused */, pdns::rust::web::rec::Response& /* unused */) -{ -} - -void pdns::rust::web::rec::prometheusMetrics(const pdns::rust::web::rec::Request& /* unused */, pdns::rust::web::rec::Response& /* unused */) -{ -} - -void pdns::rust::web::rec::apiServerZonesGET(const pdns::rust::web::rec::Request& /* unused */, pdns::rust::web::rec::Response& /* unused */) -{ -} - -void pdns::rust::web::rec::apiServerCacheFlush(const pdns::rust::web::rec::Request& /* unused */, pdns::rust::web::rec::Response& /* unused */) -{ -} - -void pdns::rust::web::rec::apiServerZonesPOST(const pdns::rust::web::rec::Request& /* unused */, pdns::rust::web::rec::Response& /* unused */) -{ -} - +#include "rec-web-stubs.hh" diff --git a/pdns/recursordist/ws-recursor.cc b/pdns/recursordist/ws-recursor.cc index 0d8f5137a3..afee7d1827 100644 --- a/pdns/recursordist/ws-recursor.cc +++ b/pdns/recursordist/ws-recursor.cc @@ -50,19 +50,6 @@ using json11::Json; -static void fromCxxToRust(const HttpResponse& cxxresp, pdns::rust::web::rec::Response& rustResponse) -{ - if (cxxresp.status != 0) { - rustResponse.status = cxxresp.status; - } - rustResponse.body = ::rust::Vec<::rust::u8>(); - rustResponse.body.reserve(cxxresp.body.size()); - std::copy(cxxresp.body.cbegin(), cxxresp.body.cend(), std::back_inserter(rustResponse.body)); - for (const auto& header : cxxresp.headers) { - rustResponse.headers.emplace_back(pdns::rust::web::rec::KeyValue{header.first, header.second}); - } -} - void productServerStatisticsFetch(map& out) { auto stats = getAllStatsMap(StatComponent::API); @@ -384,16 +371,6 @@ static void apiServerZonesPOST(HttpRequest* req, HttpResponse* resp) resp->status = 201; } -void pdns::rust::web::rec::apiServerZonesPOST(const pdns::rust::web::rec::Request& rustRequest, pdns::rust::web::rec::Response& rustResponse) -{ - HttpRequest req; - HttpResponse resp; - - req.body = std::string(reinterpret_cast(rustRequest.body.data()), rustRequest.body.size()); - apiServerZonesPOST(&req, &resp); - fromCxxToRust(resp, rustResponse); -} - static void apiServerZonesGET(HttpRequest* /* req */, HttpResponse* resp) { Json::array doc; @@ -416,13 +393,6 @@ static void apiServerZonesGET(HttpRequest* /* req */, HttpResponse* resp) resp->setJsonBody(doc); } -void pdns::rust::web::rec::apiServerZonesGET(const pdns::rust::web::rec::Request& /* rustRequest */, pdns::rust::web::rec::Response& rustResponse) -{ - HttpResponse resp; - apiServerZonesGET(nullptr, &resp); - fromCxxToRust(resp, rustResponse); -} - static inline DNSName findZoneById(HttpRequest* req) { auto zonename = apiZoneIdToName(req->parameters["id"]); @@ -520,18 +490,6 @@ static void apiServerCacheFlush(HttpRequest* req, HttpResponse* resp) {"result", "Flushed cache."}}); } -void pdns::rust::web::rec::apiServerCacheFlush(const pdns::rust::web::rec::Request& rustRequest, pdns::rust::web::rec::Response& rustResponse) -{ - HttpRequest request; - for (const auto& [key, value] : rustRequest.vars) { - cerr << key << ' ' << value << endl; - request.getvars[std::string(key)] = std::string(value); - } - HttpResponse response; - apiServerCacheFlush(&request, &response); - fromCxxToRust(response, rustResponse); -} - static void apiServerRPZStats(HttpRequest* /* req */, HttpResponse* resp) { auto luaconf = g_luaconfs.getLocal(); @@ -613,13 +571,6 @@ static void prometheusMetrics(HttpRequest* /* req */, HttpResponse* resp) resp->status = 200; } -void pdns::rust::web::rec::prometheusMetrics(const pdns::rust::web::rec::Request& /* rustRequest */, pdns::rust::web::rec::Response& rustReponse) -{ - HttpResponse resp; - prometheusMetrics(nullptr, &resp); - fromCxxToRust(resp, rustReponse); -} - #include "htmlfiles.h" static void serveStuff(HttpRequest* req, HttpResponse* resp) @@ -660,15 +611,6 @@ static void serveStuff(HttpRequest* req, HttpResponse* resp) } } -void pdns::rust::web::rec::serveStuff(const pdns::rust::web::rec::Request& rustRequest, pdns::rust::web::rec::Response& rustReponse) -{ - HttpRequest request; - HttpResponse response; - request.url = std::string(rustRequest.uri); - serveStuff(&request, &response); - fromCxxToRust(response, rustReponse); -} - const std::map MetricDefinitionStorage::d_metrics = { #include "rec-prometheus-gen.h" }; @@ -1019,5 +961,51 @@ void serveRustWeb() for (const auto& [url, _] : g_urlmap) { urls.emplace_back(url); } - pdns::rust::web::rec::serveweb({"127.0.0.1:3000", "[::1]:3000"}, urls); + pdns::rust::web::rec::serveweb({"127.0.0.1:3000", "[::1]:3000"}, ::rust::Slice{urls.data(), urls.size()}); +} + +static void fromCxxToRust(const HttpResponse& cxxresp, pdns::rust::web::rec::Response& rustResponse) +{ + if (cxxresp.status != 0) { + rustResponse.status = cxxresp.status; + } + rustResponse.body = ::rust::Vec<::rust::u8>(); + rustResponse.body.reserve(cxxresp.body.size()); + std::copy(cxxresp.body.cbegin(), cxxresp.body.cend(), std::back_inserter(rustResponse.body)); + for (const auto& header : cxxresp.headers) { + rustResponse.headers.emplace_back(pdns::rust::web::rec::KeyValue{header.first, header.second}); + } +} + +static void rustWrapper(const std::function& func, const pdns::rust::web::rec::Request& rustRequest, pdns::rust::web::rec::Response& rustResponse) +{ + HttpRequest request; + HttpResponse response; + request.body = std::string(reinterpret_cast(rustRequest.body.data()), rustRequest.body.size()); + request.url = std::string(rustRequest.uri); + for (const auto& [key, value] : rustRequest.vars) { + request.getvars[std::string(key)] = std::string(value); + } + func(&request, &response); + fromCxxToRust(response, rustResponse); +} + +namespace pdns::rust::web::rec { + +// NOLINTNEXTLINE(cppcoreguidelines-macro-usage) +#define WRAPPER(A) void A(const Request& rustRequest, Response& rustResponse) { rustWrapper(::A, rustRequest, rustResponse); } + +void jsonstat(const Request& rustRequest, Response& rustResponse) +{ + rustWrapper(RecursorWebServer::jsonstat, rustRequest, rustResponse); +} + +WRAPPER(apiServerCacheFlush) +WRAPPER(apiServerDetail) +WRAPPER(apiServerZonesGET) +WRAPPER(apiServerZonesPOST) +WRAPPER(prometheusMetrics) +WRAPPER(serveStuff) +WRAPPER(apiServerStatistics) + }