{"id":28226144,"url":"https://github.com/senseunit/rgap","last_synced_at":"2025-09-03T18:33:50.379Z","repository":{"id":218208373,"uuid":"745873511","full_name":"SenseUnit/rgap","owner":"SenseUnit","description":"Redundancy Group Announcement Protocol","archived":false,"fork":false,"pushed_at":"2025-04-16T23:19:04.000Z","size":119,"stargazers_count":10,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-05-18T11:11:24.405Z","etag":null,"topics":["dns","dns-server","multicast","multicast-messages","networking","service-discovery","service-mesh","unicast","unicast-messages"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/SenseUnit.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-01-20T12:07:22.000Z","updated_at":"2025-05-04T08:26:29.000Z","dependencies_parsed_at":"2024-01-28T21:31:50.172Z","dependency_job_id":"c51e0feb-b711-4802-95b5-a717c930b2ed","html_url":"https://github.com/SenseUnit/rgap","commit_stats":null,"previous_names":["snawoot/rgap","senseunit/rgap"],"tags_count":13,"template":false,"template_full_name":null,"purl":"pkg:github/SenseUnit/rgap","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SenseUnit%2Frgap","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SenseUnit%2Frgap/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SenseUnit%2Frgap/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SenseUnit%2Frgap/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/SenseUnit","download_url":"https://codeload.github.com/SenseUnit/rgap/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/SenseUnit%2Frgap/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259602321,"owners_count":22882963,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dns","dns-server","multicast","multicast-messages","networking","service-discovery","service-mesh","unicast","unicast-messages"],"created_at":"2025-05-18T11:10:53.820Z","updated_at":"2025-06-13T07:32:34.994Z","avatar_url":"https://github.com/SenseUnit.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"rgap\n====\n\nRedundancy Group Announcement Protocol\n\nRGAP allows one group of hosts to be aware about IP addresses of another group of hosts. For example, it is useful for updating load balancers on dynamic IP addresses of backend servers.\n\nAnnouncements are propagated in short HMAC-signed UDP messages using unicast or multicast.\n\nThis implementation defines two primary parts: *agent* and *listener*.\n\nAgent periodically sends unicast or broadcast UDP message to announce it's presense in particular redundancy group.\n\nListener accepts announces, verifies them and maintains the list of active IP addresses for each redundancy group. At the same time it exposes current list of IP addresses through its output plugins.\n\n## Usage\n\n### Agent example\n\n```sh\nRGAP_ADDRESS=127.1.2.3 \\\nRGAP_PSK=8f1302643b0809279794c5cc47f236561d7442b85d748bd7d1a58adfbe9ff431 \\\n    rgap agent -g 1000 -i 5s\n```\n\nwhere RGAP\\_ADDRESS is actual IP address which node exposes to the redundancy group.\n\n### Listener\n\n```sh\nrgap listener -c /etc/rgap.yaml\n```\n\nSee also [configuration example](#configuration-example).\n\n### PSK Generator\n\n```sh\nrgap genpsk\n```\n\n## Reference\n\n### Listener confiruration\n\nThe file is in YAML syntax with following elements\n\n* **`listen`** (_list_)\n    * (_string_) listen port addresses. Accepted formats: _host:port_ or _host:port@interface_ or _host:port@IP/prefixlen_. In later case rgap will find an interface with IP address which belongs to network specified by _IP/prefixlen_. Examples: `239.82.71.65:8271`, `239.82.71.65:8271@eth0`, `239.82.71.65:8271@192.168.0.0/16`.\n* **`groups`** (_list_)\n    * (_dictionary_)\n        * **`id`** (_uint64_) redundancy group identifier.\n        * **`psk`** (_string_) hex-encoded pre-shared key for message authentication.\n        * **`expire`** (_duration_) how long announced address considered active past the timestamp specified in the announcement.\n        * **`clock_skew`** (_duration_) allowed skew between local clock and time in announcement message.\n        * **`readiness_delay`** (_duration_) startup delay before group is reported as READY to output plugins. Useful to supress uninitialized group output after startup.\n* **`outputs`** (_list_)\n    * (_dictionary_)\n        * **`kind`** (_string_) name of output plugin\n        * **`spec`** (_any_) YAML config of corresponding output plugin\n\n### Output plugins reference\n\n#### `noop`\n\nDummy plugin which doesn't do anything.\n\n#### `log`\n\nPeriodically dumps groups contents to the application log.\n\nConfiguration:\n\n* **`interval`** (duration) interval between dumps into log.\n\n#### `eventlog`\n\nLogs group membership changes to the application log.\n\nConfiguration:\n\n* **`only_groups`** (_list_ or _null_) list of group identifiers to subscribe to. All groups are logged if this list is `null` or this key is not specified.\n    * (_uint64_) group ID.\n\n#### `hostsfile`\n\nPeriodically dumps group contents into hosts file.\n\nConfiguration:\n\n* **`interval`** (_duration_) interval between periodic dumps.\n* **`filename`** (_string_) path to hosts file\n* **`mappings`** (_list_)\n    * (_dictionary_)\n        * **`group`** (_uint64_) group which addresses should be mapped to given hostname in hosts file\n        * **`hostname`** (_string_) hostname specified for group addresses in hosts file\n        * **`fallback_addresses`** (_list_)\n            * (_string_) addresses to use instead of group addresses if group is empty\n* **`prepend_lines`** (_list_)\n    * (_string_) lines to prepend before output. Useful for comment lines.\n* **`append_lines`** (_list_)\n    * (_string_) lines to append after output. Useful for comment lines.\n\n#### `dns`\n\nRuns DNS server responding to queries for names mapped to group addresses.\n\nConfiguration:\n\n* **`bind_address`** (_string_)\n* **`mappings`** (_dictionary_)\n    * **\\*DOMAIN NAME\\*** (_dictionary_)\n        * **`group`** (_uint64_) group ID which addresses whould be returned in response to DNS queries for hostname **\\*DOMAIN NAME\\***.\n        * **`fallback_addresses`** (_list_)\n            * (_string_) addresses to use instead of group addresses if group is empty\n* **`compress`** (_boolean_) compress DNS response message\n* **`non_authoritative`** (_boolean_) if true, do not set AA bit for DNS response messages\n\n#### `command`\n\nPipes active addresses of group into stdin of external command after each membership change. Redirects stdout and stderr of external command to output into application log.\n\nConfiguration:\n\n* **`group`** (_uint64_) identifier of group.\n* **`command`** (_list of strings_) command and arguments.\n* **`timeout`** (_duration_) execution time limit for the command.\n* **`retries`** (_int_) attempts to retry failed command. Default is `1`.\n* **`wait_delay`** (_duration_) delay to wait for I/O to complete after process termination. Zero value disables I/O cancellation logic. Default is `100ms`.\n\n### Configuration example\n\n```yaml\nlisten:\n  - 239.82.71.65:8271 # or \"239.82.71.65:8271@eth0\" or \"239.82.71.65:8271@192.168.0.0/16\"\n  - 127.0.0.1:8282\n\ngroups:\n  - id: 1000\n    psk: 8f1302643b0809279794c5cc47f236561d7442b85d748bd7d1a58adfbe9ff431\n    expire: 15s\n    clock_skew: 10s\n    readiness_delay: 15s\n\noutputs:\n  - kind: noop\n    spec:\n  - kind: log\n    spec:\n      interval: 60s\n  - kind: eventlog\n    spec: # or skip spec at all\n      only_groups: # or specify null for all groups\n        - 1000\n  - kind: hostsfile\n    spec:\n      interval: 5s\n      filename: hosts\n      mappings:\n        - group: 1000\n          hostname: worker\n          fallback_addresses:\n            - 1.2.3.4\n            - 5.6.7.8\n      prepend_lines:\n        - \"# Auto-generated hosts file\"\n        - \"# Do not edit manually, changes will be overwritten by RGAP\"\n      append_lines:\n        - \"# End of auto-generated file\"\n  - kind: dns\n    spec:\n      bind_address: :8253\n      mappings:\n        worker.example.com:\n          group: 1000\n          fallback_addresses:\n            - 1.2.3.4\n            - 5.6.7.8\n        worker.example.org:\n          group: 1000\n          fallback_addresses:\n            - 1.2.3.4\n            - 5.6.7.8\n  - kind: command\n    spec:\n      group: 1000\n      command:\n        - \"/home/user/sync.sh\"\n        - \"--group\"\n        - \"1000\"\n      timeout: 5s\n      retries: 3\n\n```\n \n### CLI synopsis\n\nRun `rgap help` to see details of command line interface.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsenseunit%2Frgap","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsenseunit%2Frgap","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsenseunit%2Frgap/lists"}