Cloudflare force create a non-glue record that is beneath a delegated child zone.

Plugin for Cloudflare. Fix error for: Cannot create a non-glue record that is beneath a delegated child zone. (Code: 89018).

// ==UserScript==
// @name         Cloudflare force create a non-glue record that is beneath a delegated child zone.
// @namespace    https://medium.com/chouhsiang
// @version      1.2
// @description  Plugin for Cloudflare. Fix error for: Cannot create a non-glue record that is beneath a delegated child zone. (Code: 89018).
// @author       Sean Chou
// @match        https://dash.cloudflare.com/*
// @icon        
// @grant        none
// @license      MIT
// ==/UserScript==
async function submit(ele) {
  const u = new URL(window.location);
  const path = u.pathname.split("/");
  const account = path[1];
  const domain = path[2];

  // Check Insert or Update
  const form = ele.form;
  let record_id = form.parentElement.parentElement.id;
  record_id = record_id == "" ? null : record_id.split("-")[0];

  // Get zone id
  let url = `https://dash.cloudflare.com/api/v4/zones?name=${domain}&account.id=${account}`;
  let response = await fetch(url);
  let data = await response.json();
  const zone = data.result[0].id;

  // Get atok
  url = "https://dash.cloudflare.com/api/v4/system/bootstrap";
  response = await fetch(url);
  data = await response.json();
  const atok = data.result.data.atok;

  // Get form data
  const type = form.querySelector("[aria-labelledby=dns-label-type]").value;
  let name = form.querySelector("[aria-labelledby=dns-label-name]").value;
  if (!name.endsWith(domain)) {
    name += "." + domain;
  }
  let content;
  if (type == "A") {
    content = form.querySelector(
      "[aria-labelledby=dns-label-ipv4_address]"
    ).value;
  } else if (type == "AAAA") {
    content = form.querySelector(
      "[aria-labelledby=dns-label-ipv6_address]"
    ).value;
  } else if (type == "CNAME") {
    content = form.querySelector("[aria-labelledby=dns-label-target]").value;
  } else {
    alert("Only support A、AAAA、CNAME");
    return;
  }

  // Get ns record & delete
  const parent_domain = name.split(".").slice(1).join(".");
  url = `https://dash.cloudflare.com/api/v4/zones/${zone}/dns_records?type=NS&name=${parent_domain}`;
  response = await fetch(url);
  data = await response.json();
  const ns = data.result;
  for (const i of ns) {
    const dns_id = i.id;
    url = `https://dash.cloudflare.com/api/v4/zones/${zone}/dns_records/${dns_id}`;
    await fetch(url, {
      method: "DELETE",
      headers: {
        "X-Atok": atok,
        "X-Cross-Site-Security": "dash",
      },
    });
  }

  // Insert or update record
  let d = {
    content: content,
    name: name,
    type: type,
    zone_id: zone,
    zone_name: domain,
    proxied: true,
    ttl: 1,
    comment: "",
    data: {},
    proxiable: true,
    tags: [],
  };
  if (record_id) {
    url = `https://dash.cloudflare.com/api/v4/zones/${zone}/dns_records/${record_id}`;
    response = await fetch(url, {
      method: "PUT",
      headers: {
        "Content-Type": "application/json",
        "X-Atok": atok,
        "X-Cross-Site-Security": "dash",
      },
      body: JSON.stringify(d),
    });
    data = await response.json();
    if (data.success) {
      alert("Force update succeeded");
    } else {
      alert("Force update failed:" + JSON.stringify(data.errors));
    }
  } else {
    url = `https://dash.cloudflare.com/api/v4/zones/${zone}/dns_records`;
    response = await fetch(url, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "X-Atok": atok,
        "X-Cross-Site-Security": "dash",
      },
      body: JSON.stringify(d),
    });
    data = await response.json();
    if (data.success) {
      alert("Force create succeeded");
    } else {
      alert("Force create succeeded:" + JSON.stringify(data.errors));
    }
  }

  // Add ns record
  for (const i of ns) {
    url = `https://dash.cloudflare.com/api/v4/zones/${zone}/dns_records`;
    d = {
      content: i.content,
      name: i.name,
      type: "NS",
      zone_id: zone,
      zone_name: domain,
    };
    await fetch(url, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "X-Atok": atok,
        "X-Cross-Site-Security": "dash",
      },
      body: JSON.stringify(d),
    });
  }
  location.reload();
}

async function addBtn() {
  const u = new URL(window.location);
  if (u.host == "dash.cloudflare.com" && u.pathname.endsWith("/dns/records")) {
    const old_btns = document.querySelectorAll(
      "button[data-testid=dns-record-form-save-button]"
    );
    const new_btns = document.querySelectorAll(
      "button[data-testid=force-save-button]"
    );
    if (old_btns.length > new_btns.length) {
      const new_btn = document.createElement("button");
      new_btn.setAttribute("data-testid", "force-save-button");
      new_btn.setAttribute("type", "button");
      new_btn.setAttribute("class", old_btns[0].className);
      new_btn.setAttribute(
        "style",
        "margin-left: 8px; background-color: rgb(235, 20, 3)"
      );
      new_btn.innerText = "Force Save";
      new_btn.onclick = async function () {
        await submit(this);
      };
      old_btns.forEach(function (old_btn) {
        if (old_btn.nextSibling == null) {
          old_btn.parentNode.insertBefore(new_btn, old_btn.nextSibling);
        }
      });
    }
  }
}

setInterval(async () => await addBtn(), 1000);

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址