Using bash and jq, why is this returning null instead of the ID?

I’m creating an http_ratelimit ruleset, and it seems to create it properly. But instead of returning the ID, it’s returning “null”.

rl_ruleset_id=$(curl https://api.cloudflare.com/client/v4/zones/$zone_id/rulesets \
	--silent \
	--header "X-Auth-Email: $email" \
	--header "X-Auth-Key: $key" \
	--header "Content-Type: application/json" \
	--data '{
		"name": "default",
		"kind": "zone",
		"description": "",
		"phase": "http_ratelimit"
	}' | jq -r '.result.id')

if [[ -n $rl_ruleset_id ]]
	then
		printf "Rate Limit Ruleset ID (two): $rl_ruleset_id...\n"
fi

and it’s printing:

Rate Limit Ruleset ID (two): null…

So even though the value is “null”, -n recognizes that the variable exists.

Do you see what I’m doing wrong?

Try with '.result[].id' instead.

That is because jq has returned a string value of null rather than returning null. (A string of length 4 is not the same as a null string).

Try using the --exit-status option, and check the return code from jq for errors. I think you are getting an error from the API call, and you are not seeing the error at all.

This would be the answer for listZoneRulesets, but the body being sent makes this a POST to createZoneRuleset. I usually explicitly set the POST method.

1 Like

I just tried it, and now I get a different error:

jq: error (at <stdin>:15): Cannot index string with string "id"

Like this?

rl_ruleset_id=$(curl --request POST \
	--url https://api.cloudflare.com/client/v4/zones/$zone_id/rulesets \
	--silent \
	--exit-status
	--header "X-Auth-Email: $email" \
	--header "X-Auth-Key: $key" \
	--header "Content-Type: application/json" \
	--data '{
		"name": "default",
		"kind": "zone",
		"description": "",
		"phase": "http_ratelimit"
	}' | jq -r '.result.id')

That gave me an error of:

curl: option --exit-status: is unknown

It’s worth mentioning that I create another ruleset just before this one, with a phase of “http_request_firewall_custom”. It works every time with an identical code structure, but then this one fails.

If it’s not an issue of a typo, then maybe there’s a limit to how many curl requests I can make to /rulesets? There would be 7 before the one that’s failing.

Its an option to jq, not curl!

Can you run the command without the jq filter at all, and confirm you are not getting an error.

There is a global API limit of 1,200 requests per 5 minutes, and separate limits for Rulesets.

Haha, oh, my mistake :slight_smile: So, like this?

| jq -r --exit-status '.result.id')

Well, it turns out I AM getting an error, but it’s not super helpful:

{“success”:false,“errors”:[{“code”:10000,“message”:“Authe…cation error”}]}

I copied the section to a separate script, though, and when I run it by itself (without the WAF rules prior) then it’s working properly. So it’s definitely not an issue of a typo, it has to be a rate limit issue. Who’d have thought that 7 would be the limit, though?

You should get a HTTP 429 response code if you are being rate limited.

The documentation indicates to try and update the ruleset in a single operation if you are hitting the rate limit.

1 Like

I

am so

dumb

:disguised_face:

I was overwriting $key in a for loop.

Sorry, everybody! Thanks for the extra set of eyes, though!

2 Likes

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.