]> git.ipfire.org Git - thirdparty/knot-dns.git/commitdiff
purge: start using keys purge
authorDavid Vašek <david.vasek@nic.cz>
Tue, 25 Nov 2025 15:59:51 +0000 (16:59 +0100)
committerDavid Vašek <david.vasek@nic.cz>
Wed, 20 May 2026 07:10:38 +0000 (09:10 +0200)
doc/man_knotc.rst
src/knot/ctl/commands.c
src/knot/zone/zone.c
src/knot/zone/zone.h
tests-extra/tests/dnssec/shared_ksk/test.py

index 6b4015221161cf2b1668956478933696076a35d0..152df0ee903d2425127b6e9c4ed3d9e335c272ce 100644 (file)
@@ -297,12 +297,13 @@ Actions
 **zone-purge** *zone*... [**+orphan**] [*filter*...]
   Purge zone data, zone file, journal, timers, and/or KASP data of specified zones.
   Available filters are **+expire**, **+zonefile**, **+journal**, **+timers**,
-  **+kaspdb**, and **+catalog**. If no filter is specified, all filters are enabled.
-  If the zone is no longer configured, add **+orphan** parameter (zone file cannot
-  be purged in this case). When purging orphans, always check the server log for
-  possible errors. For proper operation, it's necessary to prevent ongoing changes
-  to the zone and triggering of zone related events during purge; use of
-  **zone-freeze** is advisable. This command always requires the force option. (#)
+  **+keys**, **+kaspdb**, and **+catalog**. If no filter is specified, all filters
+  are enabled, except for **+keys**, which must be listed explicitly. If the zone is
+  no longer configured, add **+orphan** parameter (zone file cannot be purged in this
+  case). When purging orphans, always check the server log for possible errors. For proper
+  operation, it's necessary to prevent ongoing changes to the zone and triggering of zone
+  related events during purge; use of **zone-freeze** is advisable. This command always
+  requires the force option. (#)
 
 .. _knotc_zone-stats:
 
index 8f6965ff63c20833ff5cba0cbc0d55dfc9a21090..179a4f6106fd34964fa983020477e5f5034784b2 100644 (file)
@@ -1660,8 +1660,8 @@ static int purge_orphan_member_cb(const knot_dname_t *member, const knot_dname_t
        orphan->server = server;
 
        const purge_flag_t params =
-               PURGE_ZONE_TIMERS | PURGE_ZONE_JOURNAL | PURGE_ZONE_KASPDB |
-               PURGE_ZONE_BEST | PURGE_ZONE_LOG;
+               PURGE_ZONE_TIMERS | PURGE_ZONE_JOURNAL | PURGE_ZONE_KEYS |
+               PURGE_ZONE_KASPDB | PURGE_ZONE_BEST | PURGE_ZONE_LOG;
 
        int ret = selective_zone_purge(conf(), orphan, params);
        free(orphan);
@@ -1745,6 +1745,13 @@ static int orphans_purge(ctl_args_t *args)
        bool failed = false;
 
        if (args->data[KNOT_CTL_IDX_ZONE] == NULL) {
+               // Purge keys. (It needs to be requested explicitly.)
+               if (MATCH_AND_FILTER(args, CTL_FILTER_PURGE_KEYS)) {
+                       ret = kasp_db_sweep_keys(&args->server->kaspdb,
+                                                zone_exists, args->server->zone_db);
+                       log_if_orphans_error(NULL, ret, "keys", &failed);
+               }
+
                // Purge KASP DB.
                if (only_orphan || MATCH_AND_FILTER(args, CTL_FILTER_PURGE_KASPDB)) {
                        ret = kasp_db_sweep(&args->server->kaspdb,
@@ -1792,6 +1799,14 @@ static int orphans_purge(ctl_args_t *args)
                        knot_dname_to_lower(zone_name);
 
                        if (!zone_exists(zone_name, args->server->zone_db)) {
+                               // Purge keys. (It needs to be requested explicitly.)
+                               if (MATCH_AND_FILTER(args, CTL_FILTER_PURGE_KEYS)) {
+                                       if (knot_lmdb_open(&args->server->kaspdb) == KNOT_EOK) {
+                                               ret = kasp_db_delete_keys(&args->server->kaspdb, zone_name, true, false);
+                                               log_if_orphans_error(zone_name, ret, "keys", &failed);
+                                       }
+                               }
+
                                // Purge KASP DB.
                                if (only_orphan || MATCH_AND_FILTER(args, CTL_FILTER_PURGE_KASPDB)) {
                                        if (knot_lmdb_open(&args->server->kaspdb) == KNOT_EOK) {
@@ -1852,6 +1867,8 @@ static int zone_purge(zone_t *zone, ctl_args_t *args)
                MATCH_OR_FILTER(args, CTL_FILTER_PURGE_KASPDB)   * PURGE_ZONE_KASPDB |
                MATCH_OR_FILTER(args, CTL_FILTER_PURGE_CATALOG)  * PURGE_ZONE_CATALOG |
                MATCH_OR_FILTER(args, CTL_FILTER_PURGE_EXPIRE)   * PURGE_ZONE_EXPIRE |
+               // Keys purge must be requested explicitly.
+               MATCH_AND_FILTER(args, CTL_FILTER_PURGE_KEYS)    * PURGE_ZONE_KEYS |
                PURGE_ZONE_NOSYNC; // Purge even zonefiles with disabled syncing.
 
        zone_set_flag(zone, (zone_flag_t)params);
index f4c4eb8bc172b6488ea07f55d1ad3463b0046c76..a029a095424828ad2c50fe9257577a2da8427705 100644 (file)
@@ -345,6 +345,16 @@ int selective_zone_purge(conf_t *conf, zone_t *zone, purge_flag_t params)
                RETURN_IF_FAILED("journal", KNOT_ENOENT);
        }
 
+       // Purge keys and related metadata.
+       if (params & PURGE_ZONE_KEYS) {
+               ret = knot_lmdb_open(zone_kaspdb(zone));
+               if (ret == KNOT_EOK) {
+                       ret = kasp_db_delete_keys(zone_kaspdb(zone), zone->name,
+                                                 false, !exit_immediately);
+               }
+               RETURN_IF_FAILED("keys", KNOT_ENOENT);
+       }
+
        // Purge KASP DB.
        if (params & PURGE_ZONE_KASPDB) {
                ret = knot_lmdb_open(zone_kaspdb(zone));
index f4b7fa7f6e0c3b3418ad2bfddfc49d0bfb11e0e2..15f3d89d8ed9add5713e5faf512bd37c9549dfbe 100644 (file)
@@ -74,8 +74,8 @@ typedef enum {
 #define PURGE_ZONE_DATA  (PURGE_ZONE_TIMERS | PURGE_ZONE_ZONEFILE | PURGE_ZONE_JOURNAL | \
                           PURGE_ZONE_KASPDB | PURGE_ZONE_CATALOG)
 
-/*!< Standard purge (respect C_ZONEFILE_SYNC param). */
-#define PURGE_ZONE_ALL   (PURGE_ZONE_DATA | PURGE_ZONE_BEST | PURGE_ZONE_LOG)
+/*!< Standard purge (including keys; respect C_ZONEFILE_SYNC param). */
+#define PURGE_ZONE_ALL   (PURGE_ZONE_DATA | PURGE_ZONE_KEYS | PURGE_ZONE_BEST | PURGE_ZONE_LOG)
 
 /*!< All purge-related flags. */
 #define PURGE_ZONE_FLAGS (PURGE_ZONE_ALL | PURGE_ZONE_NOSYNC | PURGE_ZONE_EXPIRE)
index 07fb5b87200ccec002c83dcf31dad65e9fbb5e28..6bc930508e8f3efb620995ee103d0342c6ca25ce 100644 (file)
@@ -61,7 +61,7 @@ check_ksks(knot, zones0 + zones_add1, zones0[1])
 
 # now purge zones keys in order to create dangling policy_last
 for z in zones0:
-    knot.ctl("zone-purge -f +kaspdb " + z.name)
+    knot.ctl("zone-purge -f +keys " + z.name)
 
 zones_add2 = t.zone_rnd(5, dnssec=False, records=10)
 add_shared(t, knot, zones_add2, zones0[0])