Compare commits

...

20 Commits
0.1.1 ... main

Author SHA1 Message Date
Mark Horninger 90725d8998
Create FUNDING.yml 2024-05-07 15:31:33 -04:00
spam-n-eggs a221973f1e Update galaxy.yml version to 0.2.0 2024-04-03 16:15:44 +00:00
spam-n-eggs 38f3f4c7f4 Update CHANGELOG 2024-04-03 16:15:40 +00:00
Mark Horninger 4b829fa9d1
Fixes #28 - Tested with a separate inventory. (#29) 2024-04-03 12:08:50 -04:00
Mark Horninger 895904251f
Update README.md (#26)
Documentation updates which fix: 
* #25 
* #20
2024-03-11 13:53:58 -04:00
spam-n-eggs 6243672014 Update CHANGELOG 2024-03-11 02:44:08 +00:00
Mark Horninger 7bfce168a3
Mjh/fix issues with message (#24)
* Fix the ansible error

* Rolled version

* made the wrapping of the error more pythonic

* Fixed exception handling a little more

* Fixed exception handling a little more

* Fixed exception handling a little more

* Wrapping just the message?

* Moving over to a regular old exception

* Wrapping just the message

* Forget about wrapping the error

* Forget about wrapping the error

* Forget about wrapping the error

* Fixing error detections

* Fixed sanity test issues
2024-03-10 22:42:34 -04:00
spam-n-eggs b5c798ea0e Update CHANGELOG 2024-03-11 02:06:44 +00:00
Mark Horninger b16c650525
Mjh/14/error out on bad credentials (#23)
* Testing

* Added a fixture that I was prevoiusly missing

* Wrapped as an AnsibleException

* Rolled Version Number

* Going for the tri-fecta.  Fixing #20, too
2024-03-10 22:02:10 -04:00
spam-n-eggs c9ef2888f5 Update galaxy.yml version to 0.1.4 2024-03-01 19:19:04 +00:00
spam-n-eggs d8a559bfbc Update CHANGELOG 2024-03-01 19:18:50 +00:00
Mark Horninger a835f30771
Updated Readme in a big way. (#17)
* Updeted Readme in a big way.
* Fixed the TOC to make my inner critic happy.
2024-03-01 14:15:32 -05:00
spam-n-eggs d983d504fc Update CHANGELOG 2024-02-24 16:16:10 +00:00
Mark Horninger 69dda01d5e
updated the steps to the galaxy.yml update gets included. (#11) 2024-02-24 11:14:28 -05:00
spam-n-eggs 0bc546671e Update CHANGELOG 2024-02-24 15:37:57 +00:00
spam-n-eggs b5c8b550f9 Update galaxy.yml version to 0.1.3 2024-02-24 15:37:50 +00:00
Mark Horninger a111310bae
'Fixed' Galaxy commit step (#10) 2024-02-24 10:36:19 -05:00
dependabot[bot] dbd9874ef0
Bump cryptography from 42.0.2 to 42.0.4 (#9)
Bumps [cryptography](https://github.com/pyca/cryptography) from 42.0.2 to 42.0.4.
- [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pyca/cryptography/compare/42.0.2...42.0.4)

---
updated-dependencies:
- dependency-name: cryptography
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-02-24 10:11:46 -05:00
spam-n-eggs 795341dc84 Update CHANGELOG 2024-02-24 14:34:32 +00:00
Mark Horninger d63c53574c
Fixed issues with the groups list comprehension (#8) 2024-02-24 09:29:46 -05:00
20 changed files with 628 additions and 20 deletions

2
.github/FUNDING.yml vendored Normal file
View File

@ -0,0 +1,2 @@
# These are supported funding model platforms
open_collective: dominion-solutions-foss/projects/ansible-netbird

67
.github/ISSUE_TEMPLATE/bug.yml vendored Normal file
View File

@ -0,0 +1,67 @@
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: 0.1.5
validations:
required: true
- type: input
id: python-version
attributes:
label: Python Version
description: What version of Python are you running? Please be as specific as possible
placeholder: 3.10.12
validations:
required: true
- type: input
id: ansible-version
attributes:
label: Ansible Version
description: What version of Ansible Core are you running? Please be as specific as possible
placeholder: 2.16.4
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
- BSD
- 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

11
.github/ISSUE_TEMPLATE/config.yml vendored Normal file
View File

@ -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

48
.github/SECURITY.md vendored Normal file
View File

@ -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-----
```

View File

@ -3,26 +3,27 @@ on:
release:
types: [published]
jobs:
update-version:
update-version-and-publish:
permissions:
contents: write
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
ref: main
token: ${{ secrets.DEVOPS_BOT_PAT }}
- name: Update version
run: |
echo "Updating version"
sed -i "s/version: .*/version: ${{ github.event.release.tag_name }}/g" galaxy.yml
- uses: stefanzweifel/git-auto-commit-action@v4
with:
commit_message: "Update version to ${{ github.event.release.tag_name }}"
commit_message: "Update galaxy.yml version to ${{ github.event.release.tag_name }}"
branch: "main"
ansible-publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
file_pattern: "galaxy.yml"
push_options: --force
- uses: ansible/ansible-publish-action@v1.0.0
with:

View File

@ -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

View File

@ -1,3 +1,95 @@
# Changelog
All notable changes to this project will be documented in this file.
## Bug Fixes - Parameters - 2024-04-03
### Bug Fixes
Thanks to @ipsecguy for pointing out that there was an issue with the compose variables.
- #28 - The compose parameter is updated to accept a `dict()` now.
- The documentation has been improved as well.
- Some small issues around creating bugs / questions have been resolved.
### What's Changed
* Update README.md by @spam-n-eggs in https://github.com/dominion-solutions/ansible-netbird/pull/26
* Fixes #28 - Tested with a separate inventory. by @spam-n-eggs in https://github.com/dominion-solutions/ansible-netbird/pull/29
**Full Changelog**: https://github.com/dominion-solutions/ansible-netbird/compare/0.1.6...0.2.0
## Fixed an accidental bug in the last release - 2024-03-11
Bug was accidentally released in the last release. Fixed.
### What's Changed
* Mjh/fix issues with message by @spam-n-eggs in https://github.com/dominion-solutions/ansible-netbird/pull/24
**Full Changelog**: https://github.com/dominion-solutions/ansible-netbird/compare/0.1.5...0.1.6
## Small Bugfixes - 2024-03-11
Minor fixes including:
- #14 Error on bad credentials.
- #22 Wrapped bad urls in an AnsibleError
- #20 The issue templates were bad.
### What's Changed
* Mjh/14/error out on bad credentials by @spam-n-eggs in https://github.com/dominion-solutions/ansible-netbird/pull/23
**Full Changelog**: https://github.com/dominion-solutions/ansible-netbird/compare/0.1.4...0.1.5
## Documentation updates - 2024-03-01
Closes #16
### What's Changed
* Updated Readme in a big way. by @spam-n-eggs in https://github.com/dominion-solutions/ansible-netbird/pull/17
**Full Changelog**: https://github.com/dominion-solutions/ansible-netbird/compare/0.1.3...0.1.4
## Securtity Vulnerability Fixes - 2024-02-24
Fixes security vulnerabilities
### What's Changed
* Bump cryptography from 42.0.2 to 42.0.4 by @dependabot in https://github.com/dominion-solutions/ansible-netbird-role/pull/9
* 'Fixed' Galaxy commit step by @spam-n-eggs in https://github.com/dominion-solutions/ansible-netbird-role/pull/10
* updated the steps to the galaxy.yml update gets included. by @spam-n-eggs in https://github.com/dominion-solutions/ansible-netbird-role/pull/11
### New Contributors
* @dependabot made their first contribution in https://github.com/dominion-solutions/ansible-netbird-role/pull/9
**Full Changelog**: https://github.com/dominion-solutions/ansible-netbird-role/compare/0.1.2...0.1.3
## Security Vulnerability Fixes - 2024-02-24
Fixes security vulnerabilities
### What's Changed
* Bump cryptography from 42.0.2 to 42.0.4 by @dependabot in https://github.com/dominion-solutions/ansible-netbird-role/pull/9
* 'Fixed' Galaxy commit step by @spam-n-eggs in https://github.com/dominion-solutions/ansible-netbird-role/pull/10
### New Contributors
* @dependabot made their first contribution in https://github.com/dominion-solutions/ansible-netbird-role/pull/9
**Full Changelog**: https://github.com/dominion-solutions/ansible-netbird-role/compare/0.1.2...0.1.3
## [Bug] Not all groups being found - 2024-02-24
This release fixes a critical bug where not all groups were being found during the list comprehension that was finding all of the groups.
### What's Changed
* Fixed issues with the groups list comprehension by @spam-n-eggs in https://github.com/dominion-solutions/ansible-netbird-role/pull/8
**Full Changelog**: https://github.com/dominion-solutions/ansible-netbird-role/compare/0.1.1...0.1.2

107
README.md
View File

@ -1,3 +1,106 @@
# Ansible Collection - dominion_solutions.netbird
dominion_solutions.netbird
---
This collection allows you to manage your netbird servers.
Documentation for the collection.
- [Required Python Libraries](#required-python-libraries)
- [Roles](#roles)
- [dominion\_solutions.netbird.netbird](#dominion_solutionsnetbirdnetbird)
- [Inventories](#inventories)
- [dominion\_solutions.netbird.netbird](#dominion_solutionsnetbirdnetbird-1)
- [Sample Inventory Setups](#sample-inventory-setups)
- [Retrieve All Netbird Peers in the _Development_ group](#retrieve-all-netbird-peers-in-the-development-group)
- [Retrieve all Netbird Peers that _are Connected_](#retrieve-all-netbird-peers-that-are-connected)
- [A More Complex example](#a-more-complex-example)
- [Available data for custom groupings](#available-data-for-custom-groupings)
- [Contributing](#contributing)
- [Contributors](#contributors)
# Required Python Libraries
- ansible ~=9.2.0
- requests ~=2.31.0 (If using the inventory plugin)
# Roles
## dominion_solutions.netbird.netbird
Applying this role will install the netbird client on the target machine.
[Documentation](https://galaxy.ansible.com/ui/repo/published/dominion_solutions/netbird/content/role/netbird/)
# Inventories
## dominion_solutions.netbird.netbird
This is a dynamic inventory generated based on the configuration in the netbird API.
[Documentation](https://galaxy.ansible.com/ui/repo/published/dominion_solutions/netbird/content/inventory/netbird/)
### Sample Inventory Setups
#### Retrieve All Netbird Peers in the _Development_ group
```yaml
---
plugin: dominion_solutions.netbird.netbird
api_url: https://api.netbird.io/api/
api_key: nbp_this_is_a_fake_api_key
netbird_groups:
- Development
strict: No
```
#### Retrieve all Netbird Peers that _are Connected_
```yaml
---
plugin: dominion_solutions.netbird.netbird
api_key: nbp_this_is_a_fake_api_key
api_url: https://netbird.example.com/api/
netbird_connected: True
```
#### A More Complex example
This example gets all peers in the _All_ group and builds the additional _connected_ and _ssh\_hosts_ groups, based on the keys.
```yaml
---
plugin: dominion_solutions.netbird.netbird
api_key: nbp_this_is_a_fake_api_key
api_url: https://netbird.example.com/api/
netbird_connected: False
leading_separator: No
netbird_groups:
- "All"
groups:
connected: connected
ssh_hosts: ssh_enabled
strict: No
keyed_groups:
compose:
ansible_ssh_host: label
ansible_ssh_port: 22
```
### Available data for custom groupings
Fields are taken directly from the responses at the [Netbird Peers API](https://docs.netbird.io/api/resources/peers#list-all-peers) unless otherwise indicated
| Field | Type | Notes |
| ------------------------- | --------- | ----- |
| label | `string` | `label` is a field generated as part of the inventory as an alias to the `dns_label` field. |
| id | `string` | |
| name | `string` | |
| ip | `string` | |
| connected | `boolean` | |
| last_seen | `string` | This is is an [ISO-8601](https://en.wikipedia.org/wiki/ISO_8601) UTC Date Time String |
| os | `string` | An OS Identifier such as `Linux Mint 21.3` or `Alpine Linux 3.19.1` |
| version | `string` | The version of the Netbird Client that is running on the Peer |
| groups | `object` | The groups object. This is parsed into the the groups in the inventory by name. |
| enabled | `boolean` | |
| user_id | `string` | |
| hostname | `string` | The hostname part of the FQDN |
| ui_version | `string` | Blank if there's no UI client installed, otherwise a version for the UI such as `netbird-desktop-ui/0.25.7` |
| dns_label | `string` | The Fully Qualified Domain Name for this peer. |
| login_expiration_enabled | `boolean` | Is this peer exempt from login expiration? |
| login_expired | `boolean` | Is the login for this expired? |
| last_login | `string` | |
| approval_required | `boolean` | |
| accessible_peers_count | `integer` | |
# Contributing
Please see [CONTRIBUTING.md](https://github.com/dominion-solutions/ansible-netbird/blob/main/.github/CONTRIBUTING.md)
# Contributors
- [Mark J. Horninger](https://github.com/spam-n-eggs)
- [All Contributors](https://github.com/dominion-solutions/ansible-netbird/graphs/contributors)

View File

@ -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.2.0
# The path to the Markdown (.md) readme file. This path is relative to the root of the collection
readme: README.md

View File

@ -59,9 +59,8 @@ options:
description: Whether or not to fail if a group or variable is not found.
compose:
description: compose variables for Ansible based on jinja2 expression and inventory vars
default: False
required: False
type: boolean
type: dict
keyed_groups:
description: create groups for plugins based on variable values and add the corresponding hosts to it
type: list
@ -106,7 +105,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 +130,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)
@ -141,7 +147,10 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
def _get_peer_inventory(self):
"""Get the inventory from the Netbird API"""
self.peers = self.client.ListPeers()
try:
self.peers = self.client.ListPeers()
except Exception:
raise AnsibleError("Could not retrieve the Netbird inventory. Check the API Key and URL.")
def _filter_by_config(self):
"""Filter peers by user specified configuration."""
@ -279,6 +288,9 @@ class NetbirdApi:
}
peers = []
response = requests.request("GET", url, headers=headers)
if response.status_code in [401, 404]:
raise Exception(f"{response.status_code}: {response.text}\nPlease check the API Key and URL.")
peer_json = json.loads(response.text)
for current_peer_map in peer_json:
current_peer = Peer(current_peer_map["hostname"], current_peer_map['dns_label'], current_peer_map["id"], current_peer_map)

View File

@ -1,7 +1,7 @@
ansible>=9.2.0
ansible-core>=2.16.3
cffi==1.16.0
cryptography==42.0.2
cryptography==42.0.4
epdb==0.15.1
Jinja2==3.1.3
jsonpickle==3.0.3

View File

@ -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:

View File

@ -0,0 +1,4 @@
{
"message": "token invalid",
"code": 401
}

View File

@ -0,0 +1,13 @@
---
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
strict: No
netbird_connected: No
netbird_groups:
groups:
keyed_groups:
compose:
ansible_ssh_host: ip
ansible_ssh_port: 22

View File

@ -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

View File

@ -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
@ -9,3 +9,4 @@ groups:
strict: No
keyed_groups:
compose:
ansible_ssh_host: ip

View File

@ -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"
}
]

View File

@ -0,0 +1,74 @@
[
{
"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
},
{
"id": "2j3k4l5m6n7o8p9q0r1",
"name": "Test Group With Spaces",
"peers_count": 1
}
],
"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"
}
]

View File

@ -0,0 +1,18 @@
---
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
leading_separator: No
netbird_groups:
- "Test Group With Spaces"
groups:
connected: connected
ssh_hosts: ssh_enabled
strict: No
keyed_groups:
compose:
ansible_ssh_host: label
ansible_ssh_port: 22

View File

@ -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,34 @@ 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
@pytest.fixture(scope="module")
def netbird_api_spaces_in_group():
mock_netbird_api = NetbirdApi(None, None)
response_data = []
with open('tests/unit/module_utils/inventories/fixtures/peers_spaces_in_group.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 +112,55 @@ 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
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
def test_use_ip_address(inventory, netbird_api_multigroup):
loader = DataLoader()
path = 'tests/unit/module_utils/inventories/fixtures/ip_address.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
def test_use_group_with_spaces(inventory, netbird_api_spaces_in_group):
loader = DataLoader()
path = 'tests/unit/module_utils/inventories/fixtures/spaces_in_group.netbird.yml'
inventory._build_client = MagicMock()
inventory.client = netbird_api_spaces_in_group
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 'Test Group With Spaces' in inventory.inventory.groups