Skip to content

Commit ebb6605

Browse files
committed
fix: address Cloudflare review comments (DDoS, pagination, validation, tests)
1 parent e9c1731 commit ebb6605

5 files changed

Lines changed: 144 additions & 296 deletions

File tree

tools/src/aden_tools/credentials/health_check.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1307,6 +1307,11 @@ class YouTubeHealthChecker(BaseHttpHealthChecker):
13071307
AUTH_QUERY_PARAM_NAME = "key"
13081308

13091309

1310+
class CloudflareHealthChecker(BaseHttpHealthChecker):
1311+
ENDPOINT = "https://api.cloudflare.com/client/v4/user/tokens/verify"
1312+
SERVICE_NAME = "Cloudflare"
1313+
1314+
13101315
# Registry of health checkers
13111316
HEALTH_CHECKERS: dict[str, CredentialHealthChecker] = {
13121317
"apify": ApifyHealthChecker(),
@@ -1317,6 +1322,7 @@ class YouTubeHealthChecker(BaseHttpHealthChecker):
13171322
"brevo": BrevoHealthChecker(),
13181323
"calcom": CalcomHealthChecker(),
13191324
"calendly_pat": CalendlyHealthChecker(),
1325+
"cloudflare": CloudflareHealthChecker(),
13201326
"discord": DiscordHealthChecker(),
13211327
"docker_hub": DockerHubHealthChecker(),
13221328
"exa_search": ExaSearchHealthChecker(),

tools/src/aden_tools/tools/cloudflare_tool/cloudflare_tool.py

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1272,16 +1272,8 @@ def cloudflare_get_ddos_protection_settings(zone_id: str) -> dict[str, Any]:
12721272
if validation_error:
12731273
return validation_error
12741274

1275-
# Note: DDoS settings are usually under rulesets with phase
1276-
# 'http_ratelimit' or 'http_request_late_transform'. A general
1277-
# config endpoint exists but may be limited.
1278-
_make_request(
1279-
"GET",
1280-
f"/zones/{zone_id}/settings/automatic_https_rewrites",
1281-
token,
1282-
)
1283-
1284-
return {"ddos_summary": "DDoS protection is on by default; see WAF rulesets for details."}
1275+
result = _make_request("GET", f"/zones/{zone_id}/ddos_protection/settings", token)
1276+
return {"ddos_protection": result}
12851277

12861278
@mcp.tool("cloudflare_create_firewall_rule")
12871279
def cloudflare_create_firewall_rule(
@@ -1538,6 +1530,10 @@ def cloudflare_list_advanced_services(zone_id: str) -> dict[str, Any]:
15381530
if isinstance(token, dict):
15391531
return token
15401532

1533+
validation_error = _validate_zone_id(zone_id)
1534+
if validation_error:
1535+
return validation_error
1536+
15411537
# Note: Workers and Load Balancers often require account-level access
15421538
# but can be filtered by zone. Basic implementation here.
15431539
workers = _make_request("GET", f"/zones/{zone_id}/workers/scripts", token)
@@ -1568,18 +1564,23 @@ def cloudflare_list_accounts(page: int = 1, per_page: int = 20) -> dict[str, Any
15681564
return token
15691565

15701566
params = {"page": page, "per_page": min(per_page, 50)}
1571-
result = _make_request("GET", "/accounts", token, params=params)
1567+
response = _make_request("GET", "/accounts", token, params=params, full_response=True)
15721568

1573-
if "error" in result:
1574-
return result
1569+
if "error" in response:
1570+
return response
15751571

1572+
result = response.get("result", [])
1573+
result_info = response.get("result_info", {})
15761574
accounts = result if isinstance(result, list) else result.get("accounts", [])
1575+
15771576
return {
15781577
"accounts": [
15791578
{"id": a.get("id"), "name": a.get("name"), "status": a.get("status")}
15801579
for a in accounts
15811580
],
1582-
"total": len(accounts),
1581+
"total": result_info.get("total_count", result_info.get("count", len(accounts))),
1582+
"page": page,
1583+
"per_page": per_page,
15831584
}
15841585

15851586
@mcp.tool("cloudflare_get_account_details")
@@ -1681,6 +1682,10 @@ def cloudflare_list_custom_hostnames(zone_id: str) -> dict[str, Any]:
16811682
if isinstance(token, dict):
16821683
return token
16831684

1685+
validation_error = _validate_zone_id(zone_id)
1686+
if validation_error:
1687+
return validation_error
1688+
16841689
result = _make_request("GET", f"/zones/{zone_id}/custom_hostnames", token)
16851690
if "error" in result:
16861691
return result
@@ -1726,6 +1731,10 @@ def cloudflare_list_firewall_rules(zone_id: str) -> dict[str, Any]:
17261731
if isinstance(token, dict):
17271732
return token
17281733

1734+
validation_error = _validate_zone_id(zone_id)
1735+
if validation_error:
1736+
return validation_error
1737+
17291738
result = _make_request(
17301739
"GET",
17311740
f"/zones/{zone_id}/rulesets/phases/http_request_firewall_custom/entrypoint",

tools/tests/test_credential_registry.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,14 +22,12 @@ class TestRegistryCompleteness:
2222
# which the single-value health check dispatcher can't support
2323
# - plaid_client_id/plaid_secret: requires POST with both client_id and
2424
# secret in JSON body, can't validate with a single credential value
25-
# - cloudflare: shares cloudflare_token checker (same credential_group)
2625
KNOWN_EXCEPTIONS = {
2726
"google_cse",
2827
"razorpay",
2928
"razorpay_secret",
3029
"plaid_client_id",
3130
"plaid_secret",
32-
"cloudflare",
3331
}
3432

3533
def test_specs_with_endpoint_have_checkers(self):

tools/tests/test_health_checks.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ def test_all_expected_checkers_registered(self):
6666
"brevo",
6767
"calcom",
6868
"calendly_pat",
69+
"cloudflare",
6970
"discord",
7071
"docker_hub",
7172
"exa_search",

0 commit comments

Comments
 (0)