Skip to content

feat(parser): add UptimeRobot IP range parser#15

Merged
cnlangzi merged 2 commits intomainfrom
fix/uptimerbot
Jan 22, 2026
Merged

feat(parser): add UptimeRobot IP range parser#15
cnlangzi merged 2 commits intomainfrom
fix/uptimerbot

Conversation

@cnlangzi
Copy link
Owner

@cnlangzi cnlangzi commented Jan 22, 2026

  • Add parser_uptimerobot.go to handle UptimeRobot API JSON format
  • Update uptimerobot.yaml to use correct API endpoint and parser
  • UptimeRobot uses ip_prefix/ipv6_prefix fields (snake_case)

Summary by Sourcery

Add a dedicated parser and configuration to consume UptimeRobot IP ranges from their JSON metadata API instead of the legacy text endpoint.

New Features:

  • Introduce an UptimeRobot-specific JSON parser that extracts IPv4 and IPv6 CIDR prefixes from the API response.

Enhancements:

  • Update the UptimeRobot monitor configuration to use the new JSON endpoint and custom parser.

- Add parser_uptimerobot.go to handle UptimeRobot API JSON format
- Update uptimerobot.yaml to use correct API endpoint and parser
- UptimeRobot uses ip_prefix/ipv6_prefix fields (snake_case)

PiperOrigin-RevId: 028161d
Change-Id: I028161dcde3769a4b5d6546649af9d18
@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Jan 22, 2026

Reviewer's Guide

Adds a custom parser for UptimeRobot's JSON IP range API and updates the UptimeRobot monitor configuration to use the new parser and endpoint.

Sequence diagram for UptimeRobot JSON IP range parsing flow

sequenceDiagram
    participant MonitorConfig_uptimerobot as MonitorConfig_uptimerobot
    participant Fetcher
    participant UptimeRobotAPI
    participant UptimeRobotParser
    participant netip

    MonitorConfig_uptimerobot->>Fetcher: configure parser uptimerobot and URL https_api_uptimerobot_com_meta_ips
    Fetcher->>UptimeRobotAPI: HTTP GET https_api_uptimerobot_com_meta_ips
    UptimeRobotAPI-->>Fetcher: JSON body prefixes_ip_prefix_ipv6_prefix
    Fetcher->>UptimeRobotParser: Parse(reader)
    UptimeRobotParser->>UptimeRobotParser: io_ReadAll
    UptimeRobotParser->>UptimeRobotParser: json_Unmarshal_to_uptimeRobotResponse
    loop over resp_Prefixes
        UptimeRobotParser->>netip: ParsePrefix(IPPrefix_or_IPv6Prefix)
        netip-->>UptimeRobotParser: netip_Prefix_or_error
        UptimeRobotParser->>UptimeRobotParser: append_valid_prefixes
    end
    UptimeRobotParser-->>Fetcher: []netip_Prefix
    Fetcher-->>MonitorConfig_uptimerobot: normalized_IP_prefix_list
Loading

Class diagram for UptimeRobotParser and related types

classDiagram
    class Parser {
        <<interface>>
        Name() string
        Parse(r io_Reader) []netip_Prefix
    }

    class UptimeRobotParser {
        Name() string
        Parse(r io_Reader) []netip_Prefix
    }

    Parser <|.. UptimeRobotParser

    class uptimeRobotResponse {
        Prefixes []uptimeRobotPrefix
    }

    class uptimeRobotPrefix {
        IPPrefix string
        IPv6Prefix string
    }

    uptimeRobotResponse "1" *-- "many" uptimeRobotPrefix

    class ParserRegistry {
        RegisterParser(name string, parser Parser)
    }

    ParserRegistry o--> UptimeRobotParser
    UptimeRobotParser ..> uptimeRobotResponse
    UptimeRobotParser ..> uptimeRobotPrefix
    UptimeRobotParser ..> netip_Prefix
    UptimeRobotParser ..> io_Reader
    UptimeRobotParser ..> json_Unmarshal
    UptimeRobotParser ..> io_ReadAll
Loading

File-Level Changes

Change Details Files
Introduce a dedicated JSON parser for UptimeRobot IP ranges and register it in the parser registry.
  • Add UptimeRobotParser type implementing Name and Parse methods for the uptimerobot JSON format
  • Define uptimeRobotResponse struct to match the prefixes array with ip_prefix and ipv6_prefix fields
  • Read and unmarshal the JSON body, iterating prefixes and parsing ip_prefix/ipv6_prefix values into netip.Prefix
  • Silently skip invalid prefixes by ignoring parse errors
  • Register the uptimerobot parser in init so it becomes available by name
parser/parser_uptimerobot.go
Switch UptimeRobot monitor configuration from plain-text IPv4 list to the new JSON API and parser.
  • Update documentation comments to reference the JSON API endpoint and response structure
  • Change parser from txt to uptimerobot to use the new custom parser
  • Replace old IPv4-only URL with the new JSON meta/ips endpoint
bots/conf.d/uptimerobot.yaml

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've left some high level feedback:

  • In Parse, prefix parsing errors are silently ignored; consider either returning an error with context or logging which prefixes failed to parse so malformed data from the upstream API is visible rather than being quietly dropped.
  • You can avoid the intermediate allocation with io.ReadAll by using json.NewDecoder(r).Decode(&resp), which simplifies the parsing path and streams directly from the reader.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `Parse`, prefix parsing errors are silently ignored; consider either returning an error with context or logging which prefixes failed to parse so malformed data from the upstream API is visible rather than being quietly dropped.
- You can avoid the intermediate allocation with `io.ReadAll` by using `json.NewDecoder(r).Decode(&resp)`, which simplifies the parsing path and streams directly from the reader.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

@codecov
Copy link

codecov bot commented Jan 22, 2026

Codecov Report

❌ Patch coverage is 14.28571% with 18 lines in your changes missing coverage. Please review.
✅ Project coverage is 61.80%. Comparing base (60ce193) to head (0910f0d).
⚠️ Report is 6 commits behind head on main.

Files with missing lines Patch % Lines
parser/parser_uptimerobot.go 10.52% 17 Missing ⚠️
parser/parser_google.go 0.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##             main      #15       +/-   ##
===========================================
- Coverage   72.76%   61.80%   -10.97%     
===========================================
  Files          15       24        +9     
  Lines         661     1000      +339     
===========================================
+ Hits          481      618      +137     
- Misses        136      324      +188     
- Partials       44       58       +14     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Replace io.ReadAll + json.Unmarshal with json.NewDecoder(r).Decode()
for zero-allocation streaming JSON parsing.

PiperOrigin-RevId: 83e1682
Change-Id: I83e168289585ebac84bed837eb92f6a0
@github-actions
Copy link

Benchmark Results

BenchmarkASNCache_Add                      	 1000000	      1555 ns/op	     443 B/op	      10 allocs/op
BenchmarkASNCache_Add-4                    	 1000000	      1420 ns/op	     443 B/op	      10 allocs/op
BenchmarkASNCache_Add-8                    	 1000000	      1399 ns/op	     442 B/op	      10 allocs/op
BenchmarkASNCache_Contains                 	17764437	        66.76 ns/op	      20 B/op	       2 allocs/op
BenchmarkASNCache_Contains-4               	33180291	        35.63 ns/op	      20 B/op	       2 allocs/op
BenchmarkASNCache_Contains-8               	33647773	        37.50 ns/op	      20 B/op	       2 allocs/op
BenchmarkASNCache_Count                    	241006500	         4.979 ns/op	       0 B/op	       0 allocs/op
BenchmarkASNCache_Count-4                  	240414904	         5.102 ns/op	       0 B/op	       0 allocs/op
BenchmarkASNCache_Count-8                  	241131631	         4.986 ns/op	       0 B/op	       0 allocs/op
BenchmarkManager_VerifyIP                  	14903115	        82.34 ns/op	      20 B/op	       2 allocs/op
BenchmarkManager_VerifyIP-4                	31156500	        37.76 ns/op	      20 B/op	       2 allocs/op
BenchmarkManager_VerifyIP-8                	30515032	        42.90 ns/op	      20 B/op	       2 allocs/op
BenchmarkDistinct                          	 1540237	       781.9 ns/op	     384 B/op	      19 allocs/op
BenchmarkDistinct-4                        	 1624651	       746.1 ns/op	     384 B/op	      19 allocs/op
BenchmarkDistinct-8                        	 1620219	       740.4 ns/op	     384 B/op	      19 allocs/op
BenchmarkValidatePrefix                    	39323305	        30.48 ns/op	       0 B/op	       0 allocs/op
BenchmarkValidatePrefix-4                  	39238968	        30.82 ns/op	       0 B/op	       0 allocs/op
BenchmarkValidatePrefix-8                  	39266649	        30.54 ns/op	       0 B/op	       0 allocs/op
BenchmarkFindBotByUA_Hit_First             	 1243837	       979.2 ns/op	      21 B/op	       0 allocs/op
BenchmarkFindBotByUA_Hit_First-4           	 3355891	       395.6 ns/op	       7 B/op	       0 allocs/op
BenchmarkFindBotByUA_Hit_First-8           	 2860724	       596.3 ns/op	      18 B/op	       0 allocs/op
BenchmarkFindBotByUA_Hit_Middle            	 1000000	      1093 ns/op	      33 B/op	       0 allocs/op
BenchmarkFindBotByUA_Hit_Middle-4          	 3655989	       466.0 ns/op	      15 B/op	       0 allocs/op
BenchmarkFindBotByUA_Hit_Middle-8          	 4532031	       238.3 ns/op	       6 B/op	       0 allocs/op
BenchmarkFindBotByUA_Hit_Last              	 1000000	      1224 ns/op	      28 B/op	       0 allocs/op
BenchmarkFindBotByUA_Hit_Last-4            	 4581644	       400.8 ns/op	      18 B/op	       0 allocs/op
BenchmarkFindBotByUA_Hit_Last-8            	 3789250	       371.1 ns/op	      15 B/op	       0 allocs/op
BenchmarkFindBotByUA_Miss                  	  507259	      2518 ns/op	      57 B/op	       0 allocs/op
BenchmarkFindBotByUA_Miss-4                	 1326340	       901.7 ns/op	      46 B/op	       0 allocs/op
BenchmarkFindBotByUA_Miss-8                	 1324240	       886.9 ns/op	      39 B/op	       0 allocs/op
BenchmarkFindBotByUA_CaseSensitive         	 1334022	      1271 ns/op	      36 B/op	       0 allocs/op
BenchmarkFindBotByUA_CaseSensitive-4       	 3361206	       480.5 ns/op	      19 B/op	       0 allocs/op
BenchmarkFindBotByUA_CaseSensitive-8       	 4783660	       432.9 ns/op	      17 B/op	       0 allocs/op
BenchmarkValidate_KnownBot_IPHit           	  832438	      1254 ns/op	      43 B/op	       2 allocs/op
BenchmarkValidate_KnownBot_IPHit-4         	 2505069	       472.9 ns/op	      37 B/op	       2 allocs/op
BenchmarkValidate_KnownBot_IPHit-8         	 2179538	       524.1 ns/op	      40 B/op	       2 allocs/op
BenchmarkValidate_Browser                  	  222181	      6282 ns/op	     270 B/op	       1 allocs/op
BenchmarkValidate_Browser-4                	  602955	      2029 ns/op	      94 B/op	       0 allocs/op
BenchmarkValidate_Browser-8                	  583444	      2191 ns/op	      94 B/op	       0 allocs/op
BenchmarkContainsWord                      	73716625	        17.60 ns/op	       0 B/op	       0 allocs/op
BenchmarkContainsWord-4                    	71733424	        16.34 ns/op	       0 B/op	       0 allocs/op
BenchmarkContainsWord-8                    	69659703	        16.23 ns/op	       0 B/op	       0 allocs/op
BenchmarkValidate_WithBotUA                	  979230	      1210 ns/op	      29 B/op	       1 allocs/op
BenchmarkValidate_WithBotUA-4              	 2506902	       488.9 ns/op	      38 B/op	       1 allocs/op
BenchmarkValidate_WithBotUA-8              	 2461690	       483.8 ns/op	      33 B/op	       1 allocs/op
BenchmarkValidate_WithBotUA_IPMismatch     	  744144	      1719 ns/op	      83 B/op	       1 allocs/op
BenchmarkValidate_WithBotUA_IPMismatch-4   	 1949667	       622.7 ns/op	      26 B/op	       1 allocs/op
BenchmarkValidate_WithBotUA_IPMismatch-8   	 1939293	       584.0 ns/op	      25 B/op	       1 allocs/op
BenchmarkValidate_BrowserUA                	  265984	      4340 ns/op	      94 B/op	       0 allocs/op
BenchmarkValidate_BrowserUA-4              	  804224	      1572 ns/op	      86 B/op	       0 allocs/op
BenchmarkValidate_BrowserUA-8              	  816519	      1603 ns/op	      74 B/op	       0 allocs/op
BenchmarkValidate_UnknownBotUA             	 5936239	       169.9 ns/op	       7 B/op	       0 allocs/op
BenchmarkValidate_UnknownBotUA-4           	17702670	        61.80 ns/op	       2 B/op	       0 allocs/op
BenchmarkValidate_UnknownBotUA-8           	20559013	        65.88 ns/op	       3 B/op	       0 allocs/op
BenchmarkContainsIP                        	48694965	        27.49 ns/op	       1 B/op	       0 allocs/op
BenchmarkContainsIP-4                      	96163292	        13.65 ns/op	       0 B/op	       0 allocs/op
BenchmarkContainsIP-8                      	90843036	        38.55 ns/op	      20 B/op	       1 allocs/op
BenchmarkFindBotByUA                       	  751040	      1595 ns/op	      25 B/op	       0 allocs/op
BenchmarkFindBotByUA-4                     	 2039274	       598.4 ns/op	      16 B/op	       0 allocs/op
BenchmarkFindBotByUA-8                     	 1958347	       618.5 ns/op	      22 B/op	       0 allocs/op
BenchmarkClassifyUA                        	 2012967	       577.0 ns/op	      10 B/op	       0 allocs/op
BenchmarkClassifyUA-4                      	 4760684	       250.8 ns/op	       1 B/op	       0 allocs/op
BenchmarkClassifyUA-8                      	 4819369	       249.6 ns/op	       0 B/op	       0 allocs/op
Benchmark_MixedTraffic                     	  470281	      2538 ns/op	      16 B/op	       0 allocs/op
Benchmark_MixedTraffic-4                   	 1273668	       943.5 ns/op	      39 B/op	       0 allocs/op
Benchmark_MixedTraffic-8                   	 1213797	       975.3 ns/op	      27 B/op	       0 allocs/op
PASS
ok  	github.com/cnlangzi/knownbots	111.984s

@cnlangzi cnlangzi merged commit 665fecc into main Jan 22, 2026
4 of 6 checks passed
@cnlangzi cnlangzi deleted the fix/uptimerbot branch January 22, 2026 01:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant