{"id":20947517,"url":"https://github.com/unredacted/ansible-role-pathvector","last_synced_at":"2026-04-19T10:31:45.072Z","repository":{"id":238204379,"uuid":"796089483","full_name":"unredacted/ansible-role-pathvector","owner":"unredacted","description":"An Ansible role install and configure Pathvector","archived":false,"fork":false,"pushed_at":"2026-04-10T05:48:42.000Z","size":74,"stargazers_count":5,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-04-10T07:41:39.697Z","etag":null,"topics":["ansible","bgp","bgp-automation","bird","edge-routing","pathvector"],"latest_commit_sha":null,"homepage":"","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/unredacted.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"unredacted","patreon":"unredacted_org","open_collective":"unredacted","ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":"unredacted","issuehunt":null,"lfx_crowdfunding":null,"polar":null,"buy_me_a_coffee":null,"thanks_dev":null,"custom":["https://unredacted.org/donate/"]}},"created_at":"2024-05-04T22:40:57.000Z","updated_at":"2026-04-10T05:48:47.000Z","dependencies_parsed_at":"2024-11-19T00:11:53.316Z","dependency_job_id":"f823fe13-183a-426f-ae6e-353b478065f2","html_url":"https://github.com/unredacted/ansible-role-pathvector","commit_stats":null,"previous_names":["unredacted/ansible-role-pathvector"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/unredacted/ansible-role-pathvector","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unredacted%2Fansible-role-pathvector","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unredacted%2Fansible-role-pathvector/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unredacted%2Fansible-role-pathvector/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unredacted%2Fansible-role-pathvector/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/unredacted","download_url":"https://codeload.github.com/unredacted/ansible-role-pathvector/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/unredacted%2Fansible-role-pathvector/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32004000,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-18T20:23:30.271Z","status":"online","status_checked_at":"2026-04-19T02:00:07.110Z","response_time":55,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["ansible","bgp","bgp-automation","bird","edge-routing","pathvector"],"created_at":"2024-11-19T00:11:51.548Z","updated_at":"2026-04-19T10:31:45.064Z","avatar_url":"https://github.com/unredacted.png","language":"Shell","funding_links":["https://github.com/sponsors/unredacted","https://patreon.com/unredacted_org","https://opencollective.com/unredacted","https://liberapay.com/unredacted","https://unredacted.org/donate/"],"categories":[],"sub_categories":[],"readme":"# ansible-role-pathvector\n\nAn Ansible role to install and configure [Pathvector](https://pathvector.io/) \u0026 Bird (Bird2 or Bird3) from official CZ.NIC repositories with automatic UniFi detection and support.\n\n## Features\n\n- Installs Bird2 or Bird3 from official CZ.NIC repositories  \n- Automatic OS detection (Debian/Ubuntu) with proper repository configuration\n- Automatic detection of UniFi vs standard Debian systems\n- Persistent UniFi on-boot scripts that survive firmware updates (via [unifi-on-boot](https://github.com/unredacted/unifi-on-boot))\n- **Shadow Gateway Support**: Automatically handled by [unifi-on-boot](https://github.com/unredacted/unifi-on-boot) (v1.1.0+) which syncs all `/data/on_boot.d/` scripts to the shadow gateway\n- **Cron Mode**: Ensures services are running and enabled without full re-installation\n- Standard APT installation for Debian/Ubuntu systems\n- BGP AS-path prepend optimization script\n- Support for mixed infrastructure (UniFi + Debian in same playbook)\n- **Config validation**: Validates Bird configuration after generation\n- **Deploy-only mode**: Deploy configuration without installing packages\n\n## Requirements\n\n- **Supported Systems**:\n  - Debian 11 (Bullseye), 12 (Bookworm)\n  - Ubuntu 22.04 (Jammy), 24.04 (Noble)\n  - UniFi devices with 2.x-5.x firmware and [unifi-on-boot](https://github.com/unredacted/unifi-on-boot) installed for `/data/on_boot.d/` support\n- **Ansible**: 2.9+\n- **Python**: 3.6+ (with `requests`, `ipaddress`, `ruamel.yaml` for prepend script)\n\n## Installation\n\n```bash\nansible-galaxy role install unredacted.pathvector\n```\n\n## Quick Start\n\n### Basic Usage\n```yaml\n---\n- hosts: routers\n  become: yes\n  roles:\n    - unredacted.pathvector\n```\n\nThe role automatically detects if it's running on a UniFi system or standard Debian/Ubuntu.\n\n### Configuration Files\n\nPlace your Pathvector configuration files in your playbook's `files/` directory:\n\n```\nplaybook/\n└── files/\n    ├── router1.yml\n    ├── router2.yml\n    └── unifi-gateway.yml\n```\n\nFiles should be named after the inventory hostname (e.g., `router1.yml` for host `router1`).\n\n### Example Configuration\n\n```yaml\n# files/router1.yml\nasn: 65001\nrouter-id: 192.168.1.1\n\nsource4: 203.0.113.1\nsource6: 2001:db8::1\n\nprefixes:\n  - 203.0.113.0/24\n  - 2001:db8::/32\n\nrtr-server: rtr.rpki.cloudflare.com:8282\n\ntemplates:\n  upstream:\n    interpret-communities: true\n    filter-max-prefix: true\n    filter-rpki: true\n    filter-bogon-routes: true\n    filter-bogon-asns: true\n\npeers:\n  cogent:\n    asn: 174\n    template: upstream\n    neighbors:\n      - 38.140.0.1\n      - 2001:550:1::1\n```\n\n## Role Variables\n\n### Bird Configuration\n```yaml\nbird_version: \"bird2\"                          # Choose \"bird2\" or \"bird3\"\nbird_install_from_official: true               # Install from CZ.NIC official repos\nbird_gpg_key_url: \"https://pkg.labs.nic.cz/gpg\"  # CZ.NIC GPG key URL\n```\n\n### Common Variables\n```yaml\npathvector_config_path: \"/etc/pathvector.yml\"  # Config destination\npathvector_debug: false                        # Enable debug output\npathvector_run_script: false                   # Run prepend optimization\npathvector_script_flags: \"\"                    # Prepend script flags\npathvector_deploy_only: false                  # Deploy config only (skip install)\npathvector_skip_install: false                 # Skip package install (repos still configured)\n```\n\n### UniFi-Specific Variables\n```yaml\npathvector_unifi_script_name: \"20-unifi-pathvector-setup.sh\"  # On-boot script name\npathvector_unifi_run_immediately: false                       # Install immediately\npathvector_unifi_autostart_services: false                    # Auto-start bird service\n```\n\n\u003e **Note:** This role requires [unifi-on-boot](https://github.com/unredacted/unifi-on-boot) (v1.1.0+) to be installed on your UniFi devices. The on-boot script will check for this dependency and exit with an error if not found. Shadow gateway sync is handled automatically by `unifi-on-boot`.\n\n### Repository Configuration\n```yaml\npathvector_pgp_key_url: \"https://repo.pathvector.io/pgp.asc\"\npathvector_repo_url: \"https://repo.pathvector.io/apt/\"\npathvector_repo_dist: \"stable\"\npathvector_repo_component: \"main\"\n```\n\n## Repository Sources\n\n- **Bird**: Official CZ.NIC Labs packages from https://pkg.labs.nic.cz/\n  - GPG Key fingerprint: `9C71 D59C D4CE 8BD2 966A 7A3E AB6A 3031 2401 9B64`\n- **Pathvector**: Official packages from https://repo.pathvector.io/\n\n## How It Works\n\n### For UniFi Systems\n1. Deploys a persistent on-boot script to `/data/on_boot.d/`\n2. Copies your configuration to `/data/on_boot.d/pathvector.yml`\n3. On boot, the script:\n   - Verifies `unifi-on-boot` is installed (exits with error if not)\n   - Installs bird2 and pathvector (if needed)\n   - Copies config from persistent storage to `/etc/` (only if changed, using SHA256 checksums)\n   - Runs `pathvector generate`\n   - Validates the generated Bird configuration with `bird -p`\n   - Triggers `unifi-on-boot` to sync to shadow gateway\n   - Logs to `/var/log/unifi-pathvector-setup.log`\n\n### Shadow Gateway\nShadow gateway sync is handled by [unifi-on-boot](https://github.com/unredacted/unifi-on-boot) (v1.1.0+), which automatically `rsync --delete`s the entire `/data/on_boot.d/` directory to the shadow gateway at `169.254.254.3` after running all scripts. This ensures the shadow has an identical set of scripts and configurations.\n\n### Cron Mode\nThe script supports a `--cron` flag which is lighter weight:\n- Checks if Bird is running and enabled\n- Restarts/Enables if necessary\n- Does NOT attempt to install packages or modify config\n- Useful for periodic health checks\n\n### For Debian/Ubuntu Systems\n1. Adds CZ.NIC official Bird repository (configures based on OS release)\n2. Adds Pathvector repository\n3. Installs chosen Bird version (bird2 or bird3) and pathvector packages\n4. Deploys configuration to `/etc/pathvector.yml`\n5. Starts and enables bird service\n\n## Advanced Usage\n\n### Install Bird3 instead of Bird2\n```yaml\n- hosts: routers\n  become: yes\n  roles:\n    - unredacted.pathvector\n  vars:\n    bird_version: \"bird3\"\n```\n\n### Use Distribution's Bird Package\n```yaml\n- hosts: routers\n  become: yes\n  roles:\n    - unredacted.pathvector\n  vars:\n    bird_install_from_official: false  # Will use distro's bird2 package\n```\n\n### Run Installation Immediately on UniFi\n```yaml\n- hosts: unifi_devices\n  become: yes\n  roles:\n    - unredacted.pathvector\n  vars:\n    pathvector_unifi_run_immediately: true\n    pathvector_unifi_autostart_services: true\n```\n\n### Deploy Config Only (Skip Package Install)\n```yaml\n- hosts: routers\n  become: yes\n  roles:\n    - unredacted.pathvector\n  vars:\n    pathvector_deploy_only: true\n```\n\n### Enable Prepend Optimization\n```yaml\n- hosts: routers\n  become: yes\n  roles:\n    - unredacted.pathvector\n  vars:\n    pathvector_run_script: true\n    pathvector_script_flags: \"--prepends 2,1,0 --ignore router1.yml\"\n```\n\n### Mixed Infrastructure\n```yaml\n# Works automatically with both UniFi and Debian hosts\n- hosts: all_routers\n  become: yes\n  roles:\n    - unredacted.pathvector\n```\n\n## Troubleshooting\n\n### Enable Debug Mode\n```yaml\npathvector_debug: true\n```\n\n## License\n\nGPL-3.0\n\n## Author\n\nZach - [Unredacted](https://unredacted.org/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Funredacted%2Fansible-role-pathvector","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Funredacted%2Fansible-role-pathvector","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Funredacted%2Fansible-role-pathvector/lists"}