]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Basic functionality works
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Fri, 22 Nov 2024 10:40:02 +0000 (11:40 +0100)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Tue, 11 Feb 2025 15:28:22 +0000 (16:28 +0100)
pdns/recursordist/Makefile.am
pdns/recursordist/rec-web-stubs.hh [new file with mode: 0644]
pdns/recursordist/rec_control.cc
pdns/recursordist/settings/Makefile.am
pdns/recursordist/settings/rust/.gitignore
pdns/recursordist/settings/rust/Makefile.am
pdns/recursordist/settings/rust/src/bridge.hh
pdns/recursordist/settings/rust/src/web.rs
pdns/recursordist/test-syncres_cc.cc
pdns/recursordist/ws-recursor.cc

index 92dcd7583a790c5461d0f1e391d085d334f1aeb0..5bf734313e72be9bb11e17124a82728258ce4e0f 100644 (file)
@@ -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 (file)
index 0000000..bf9e68f
--- /dev/null
@@ -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
+}
index 3e1a935704fdec27f5503c28f79d86ce1b442c54..a7936cfba5d1455c65f0fa358a23f6489c5b8a9f 100644 (file)
@@ -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 */)
-{
-}
index 8d186d14aaed07bba0123f453a29c210c26ae437..7bfd21922a656c4a30ef0a3485bb4f472c4a0eb2 100644 (file)
@@ -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
index eacb110ccd069fc97447c532e7b29b4143e03e08..d31bd391e756cba5c22b74d555fb51c77854ad9e 100644 (file)
@@ -3,5 +3,6 @@
 /Makefile.in
 /cxx.h
 /lib.rs.h
+/web.rs.h
 src/lib.rs
 .dir-locals.el
index ae99af21eb1b2804d0934003d2ffac7325c1678f..6299a9f51e027d204db14c4a924b2d0e05d37e4a 100644 (file)
@@ -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
index eca7324d9fa3bca6f8c219a92c9c5f15d5b83d72..4ab8f387f8e963e87445951f36293cbad1269419 100644 (file)
@@ -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);
 }
index 2ac5f2b6d2f7dfa2b862dea077d409cad332d401..db56e23a7fe00bad1e79624050d58457ba57126f 100644 (file)
@@ -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<()>;
     }
 }
index a6447f230baad55188a4f5c50fea4e4ad09d4a2e..a38c1569439b8201fe94fb21c2513750146213fc 100644 (file)
@@ -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"
index 0d8f5137a3a6d3ff7c02f344129fc24e4308f9f3..afee7d1827069840807b743c664f1960e006fc19 100644 (file)
 
 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<string, string>& 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<const char*>(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<std::string, MetricDefinition> 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<const ::rust::String>{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<void (HttpRequest*, HttpResponse*)>& func, const pdns::rust::web::rec::Request& rustRequest, pdns::rust::web::rec::Response& rustResponse)
+{
+  HttpRequest request;
+  HttpResponse response;
+  request.body = std::string(reinterpret_cast<const char*>(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)
+
 }