diff --git a/.github/ISSUE_TEMPLATE/bug.yml b/.github/ISSUE_TEMPLATE/bug.yml new file mode 100644 index 0000000..8fa85ce --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug.yml @@ -0,0 +1,66 @@ +name: Bug Report +description: Report an Issue or Bug with the Package +title: "[Bug]: " +labels: ["bug"] +body: + - type: markdown + attributes: + value: | + We're sorry to hear you have a problem. Can you help us solve it by providing the following details. + - type: textarea + id: what-happened + attributes: + label: What happened? + description: What did you expect to happen? + placeholder: I cannot currently do X thing because when I do, it breaks X thing. + validations: + required: true + - type: textarea + id: how-to-reproduce + attributes: + label: How to reproduce the bug + description: How did this occur, please add any config values used and provide a set of reliable steps if possible. + placeholder: When I do X I see Y. + validations: + required: true + - type: input + id: package-version + attributes: + label: Package Version + description: What version of our Package are you running? Please be as specific as possible + placeholder: 2.0.0 + validations: + required: true + - type: input + id: php-version + attributes: + label: PHP Version + description: What version of PHP are you running? Please be as specific as possible + placeholder: 8.2.0 + validations: + required: true + - type: input + id: laravel-version + attributes: + label: Laravel Version + description: What version of Laravel are you running? Please be as specific as possible + placeholder: 9.0.0 + validations: + required: true + - type: dropdown + id: operating-systems + attributes: + label: Which operating systems does with happen with? + description: You may select more than one. + multiple: true + options: + - macOS + - Windows + - Linux + - type: textarea + id: notes + attributes: + label: Notes + description: Use this field to provide any other notes that you feel might be relevant to the issue. + validations: + required: false diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..1f2d77f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,11 @@ +blank_issues_enabled: false +contact_links: + - name: Ask a question + url: https://github.com/dominion-solutions/ansible-netbird-role/discussions/new?category=q-a + about: Ask the community for help + - name: Request a feature + url: https://github.com/dominion-solutions/ansible-netbird-role/discussions/new?category=ideas + about: Share ideas for new features + - name: Report a security issue + url: https://github.com/dominion-solutions/ansible-netbird-role/security/policy + about: Learn how to notify us for sensitive bugs diff --git a/.github/SECURITY.md b/.github/SECURITY.md new file mode 100644 index 0000000..1f2c47f --- /dev/null +++ b/.github/SECURITY.md @@ -0,0 +1,48 @@ +# Security Policy + +If you discover any security related issues, please email compliance@dominion.solutions instead of using the issue tracker. +Please encrypt messages using our PGP Key below: +``` +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +wNGl4zykRU8x8Qs= +=9AAX +-----END PGP PUBLIC KEY BLOCK----- +``` diff --git a/.github/workflows/update-changelog.yml b/.github/workflows/update-changelog.yml index 2b38dd1..17263cc 100644 --- a/.github/workflows/update-changelog.yml +++ b/.github/workflows/update-changelog.yml @@ -15,6 +15,7 @@ jobs: uses: actions/checkout@v4 with: ref: main + token: ${{ secrets.DEVOPS_BOT_PAT }} - name: Update Changelog uses: stefanzweifel/changelog-updater-action@v1 @@ -28,3 +29,4 @@ jobs: branch: main commit_message: Update CHANGELOG file_pattern: CHANGELOG.md + push_options: --force diff --git a/galaxy.yml b/galaxy.yml index ed7212c..382909f 100644 --- a/galaxy.yml +++ b/galaxy.yml @@ -8,7 +8,7 @@ namespace: dominion_solutions name: netbird # The version of the collection. Must be compatible with semantic versioning -version: 0.1.1 +version: 0.1.2 # The path to the Markdown (.md) readme file. This path is relative to the root of the collection readme: README.md diff --git a/plugins/inventory/netbird.py b/plugins/inventory/netbird.py index 3eb50e5..de607e5 100644 --- a/plugins/inventory/netbird.py +++ b/plugins/inventory/netbird.py @@ -106,7 +106,9 @@ display = Display() class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable): NAME = "dominion_solutions.netbird.netbird" - _load_name = NAME + + def _cacheable_inventory(self): + return [p._raw_json for p in self.peers] def _build_client(self, loader): """Build the Netbird API Client""" @@ -129,7 +131,12 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable): def _add_groups(self): """ Add peer groups to the inventory. """ self.netbird_groups = set( - filter(None, [group[0].get('name') for group in [item.data.get('groups') for l in self.peers for item in self.peers]])) + filter(None, [ + group.get('name') for peer + in self.peers + for group in + peer.data.get('groups') + ])) for group in self.netbird_groups: self.inventory.add_group(group) diff --git a/tests/unit/module_utils/inventories/fixtures/groups_develoment.netbird.yml b/tests/unit/module_utils/inventories/fixtures/groups_develoment.netbird.yml new file mode 100644 index 0000000..3042657 --- /dev/null +++ b/tests/unit/module_utils/inventories/fixtures/groups_develoment.netbird.yml @@ -0,0 +1,11 @@ +--- +plugin: dominion_solutions.netbird.netbird +api_url: https://api.netbird.io/api/ +api_key: nbp_this_is_a_fake_api_key +netbird_groups: + - Development +ip_style: plain +groups: +strict: No +keyed_groups: +compose: diff --git a/tests/unit/module_utils/inventories/fixtures/invalid_token.json b/tests/unit/module_utils/inventories/fixtures/invalid_token.json new file mode 100644 index 0000000..4f8b42d --- /dev/null +++ b/tests/unit/module_utils/inventories/fixtures/invalid_token.json @@ -0,0 +1,4 @@ +{ + "message": "token invalid", + "code": 401 + } diff --git a/tests/unit/module_utils/inventories/fixtures/netbird.yml b/tests/unit/module_utils/inventories/fixtures/netbird.yml index 9ab7ff1..085e4c9 100644 --- a/tests/unit/module_utils/inventories/fixtures/netbird.yml +++ b/tests/unit/module_utils/inventories/fixtures/netbird.yml @@ -1,6 +1,6 @@ --- -plugin: netbird -api_key: nbp_1234567890123456789012345678901234567 +plugin: dominion_solutions.netbird.netbird +api_key: nbp_this_is_a_fake_api_key api_url: https://netbird.example.com/api/v1 ip_style: plain netbird_connected: False diff --git a/tests/unit/module_utils/inventories/fixtures/only_connected.netbird.yml b/tests/unit/module_utils/inventories/fixtures/only_connected.netbird.yml index 504ce74..814a64b 100644 --- a/tests/unit/module_utils/inventories/fixtures/only_connected.netbird.yml +++ b/tests/unit/module_utils/inventories/fixtures/only_connected.netbird.yml @@ -1,6 +1,6 @@ --- plugin: netbird -api_key: nbp_1234567890123456789012345678901234567 +api_key: nbp_this_is_a_fake_api_key api_url: https://netbird.example.com/api/v1 ip_style: plain netbird_connected: True diff --git a/tests/unit/module_utils/inventories/fixtures/peers_multigroup.json b/tests/unit/module_utils/inventories/fixtures/peers_multigroup.json new file mode 100644 index 0000000..26c2218 --- /dev/null +++ b/tests/unit/module_utils/inventories/fixtures/peers_multigroup.json @@ -0,0 +1,69 @@ +[ + { + "accessible_peers_count": 1, + "approval_required": false, + "city_name": "", + "connected": false, + "connection_ip": "", + "country_code": "", + "dns_label": "apple.netbird.cloud", + "geoname_id": 0, + "groups": [ + { + "id": "3aBcD4eF5gHiJ6kLmNoP", + "name": "All", + "peers_count": 2 + } + ], + "hostname": "apple", + "id": "2j3k4l5m6n7o8p9q0r1", + "ip": "10.10.10.123", + "kernel_version": "", + "last_login": "2024-02-10T22:01:27.744131502Z", + "last_seen": "2024-02-11T03:21:42.202104672Z", + "login_expiration_enabled": true, + "login_expired": false, + "name": "apple", + "os": "Linux Mint 21.3", + "ssh_enabled": false, + "ui_version": "netbird-desktop-ui/0.25.7", + "user_id": "auth0|abc123xyz4567890defg", + "version": "0.25.7" + }, + { + "accessible_peers_count": 1, + "approval_required": false, + "city_name": "New York", + "connected": true, + "connection_ip": "146.123.45.67", + "country_code": "US", + "dns_label": "banana.netbird.cloud", + "geoname_id": 1234567, + "groups": [ + { + "id": "2j3k4l5m6n7o8p9q0r1", + "name": "Development", + "peers_count": 1 + }, + { + "id": "3aBcD4eF5gHiJ6kLmNoP", + "name": "All", + "peers_count": 2 + } + ], + "hostname": "banana", + "id": "hkwJPXNUmGywCLo5S8Wg", + "ip": "10.10.10.124", + "kernel_version": "", + "last_login": "2024-02-02T11:20:05.934889112Z", + "last_seen": "2024-02-24T02:59:35.324496386Z", + "login_expiration_enabled": false, + "login_expired": false, + "name": "docker-manager", + "os": "Alpine Linux 3.19.1", + "ssh_enabled": false, + "ui_version": "", + "user_id": "", + "version": "0.25.5" + } + ] diff --git a/tests/unit/plugins/inventory/test_netbird.py b/tests/unit/plugins/inventory/test_netbird.py index e3ecb95..bf33704 100644 --- a/tests/unit/plugins/inventory/test_netbird.py +++ b/tests/unit/plugins/inventory/test_netbird.py @@ -25,7 +25,7 @@ display = Display() def inventory(): plugin = InventoryModule() plugin.templar = Templar(loader=DataLoader()) - plugin._redirected_names = ["netbird", "dominion_solutions.netbird"] + plugin._redirected_names = ["netbird", "dominion_solutions.netbird.netbird"] plugin._load_name = plugin.NAME return plugin @@ -44,6 +44,20 @@ def netbird_api(): return mock_netbird_api +@pytest.fixture(scope="module") +def netbird_api_multigroup(): + mock_netbird_api = NetbirdApi(None, None) + response_data = [] + with open('tests/unit/module_utils/inventories/fixtures/peers_multigroup.json') as peers_file: + peers_map = json.load(peers_file) + for data in peers_map: + response_data.append(Peer(data['hostname'], data['dns_label'], data['id'], data)) + + mock_netbird_api.ListPeers = MagicMock(return_value=response_data) + + return mock_netbird_api + + def test_missing_access_token_lookup(inventory): loader = DataLoader() inventory._options = {'api_key': None, 'api_url': None} @@ -84,3 +98,16 @@ def test_get_only_connected_peers(inventory, netbird_api): assert inventory.inventory.hosts is not None assert len(inventory.inventory.hosts) == 1 assert list(inventory.inventory.hosts.values())[0].get_vars().get('connected') is True + + +def test_with_multiple_groups(inventory, netbird_api_multigroup): + loader = DataLoader() + path = 'tests/unit/module_utils/inventories/fixtures/only_connected.netbird.yml' + inventory._build_client = MagicMock() + inventory.client = netbird_api_multigroup + inventory.parse(InventoryData(), loader, path, False) + assert inventory.inventory is not None + assert inventory.inventory.hosts is not None + assert inventory.inventory.groups is not None + assert 'All' in inventory.inventory.groups + assert 'Development' in inventory.inventory.groups