Compare commits
20 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
90725d8998 | |
|
|
a221973f1e | |
|
|
38f3f4c7f4 | |
|
|
4b829fa9d1 | |
|
|
895904251f | |
|
|
6243672014 | |
|
|
7bfce168a3 | |
|
|
b5c798ea0e | |
|
|
b16c650525 | |
|
|
c9ef2888f5 | |
|
|
d8a559bfbc | |
|
|
a835f30771 | |
|
|
d983d504fc | |
|
|
69dda01d5e | |
|
|
0bc546671e | |
|
|
b5c8b550f9 | |
|
|
a111310bae | |
|
|
dbd9874ef0 | |
|
|
795341dc84 | |
|
|
d63c53574c |
|
|
@ -0,0 +1,2 @@
|
||||||
|
# These are supported funding model platforms
|
||||||
|
open_collective: dominion-solutions-foss/projects/ansible-netbird
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
|
@ -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-----
|
||||||
|
|
||||||
|
mQGNBGXZ4joBDADKC9XF05nU53n5EXE0JM0G2FrhZaPEpzJ47CFcOyvx3eHTOfwN
|
||||||
|
Z+Rtjgcugk66VNdj/fkwPpjj+Yj1ISchGDhOCXVlNnwiRdknGJ8uHZXlVYuPsVSF
|
||||||
|
voocOthFuRgM8CighScO4uPybHZUa4VwQ2+B48WFa/3FszLf6YlDWoBwljE3KVZD
|
||||||
|
WgTy/VvXx3Momwk+cher6W2eA8SuJEuixeX9mx7iu5kCjcvPBmvnDTfQS9zjKCuD
|
||||||
|
ymwJg9h+paFFcx+ObmdOnpoG7jiB4kXENFtaAIrYR/vroODZZQUnBGvvEASXbJh6
|
||||||
|
drEQu8t14l+qqaBCeGIbp/rM875VZPH7StAKRAhYGCr474Wj31jN9v93njnJtX5K
|
||||||
|
gmBSyugI/FUOP+Eov7Fp4gvm7Mrupa/z01iRcomp7qCzOEmopE+Jx7Yj3ek79LWx
|
||||||
|
1YpCaYxbp4uAg0Qtk3A8fAm/7YwoJbsNCwh8fPUfyi6JTwomejJD1jA7IR+PBaX3
|
||||||
|
pzFq9TLlzJlHsyMAEQEAAbRDRG9taW5pb24gU29sdXRpb25zIENvbXBsaWFuY2Ug
|
||||||
|
R3JvdXAgPGNvbXBsaWFuY2VAZG9taW5pb24uc29sdXRpb25zPokB1AQTAQoAPhYh
|
||||||
|
BNFjAqujHtMbhkYJGnpssxhf2tTABQJl2eI6AhsDBQkDwmcABQsJCAcCBhUKCQgL
|
||||||
|
AgQWAgMBAh4BAheAAAoJEHpssxhf2tTABYUMAI8BAnA9sMhQD0M8Gv5Pt2dSt5Ok
|
||||||
|
nQDS8zqTxZiwX5Fm+o7UOuKP+JK1RVwu3n/6XoM1G276dRwp05FJl7Qk36E5DxFU
|
||||||
|
29W4lPnvbvdJFRGbkb5JqaVnDnc/cobsytfu6qUDZPoJ6H41XgGdcQ43BuqLoux3
|
||||||
|
z5kmnWr7uUg9SZZJR2q+RMbAsSHQuepRRmQj5ONmrHZaGIYTP5D9yblotsIcXQ98
|
||||||
|
5gb5qKIges+LyBdZPONP+YiJdwH3whAw6sljgpSaF0xBPLJnvy4LpBOb4/wThh0C
|
||||||
|
pL1y+avi/fjCe2RSeAHxk9kiEyid4OPZNJx500g7jfFnLst0stct/QFLW8kenYyb
|
||||||
|
bUe/oBWWYuxhh/XQR7YkezgUcIXjbLQFPXbDakQoc7yKrI1HGP6aHjLQis2hbXiH
|
||||||
|
YrFc289vY1XuFlZaTP7rwmrabRi+lK6S5HX44aM3LmsSsL0s9sh6DhI27qqBrfsW
|
||||||
|
Tsh+fojeANNFvx75fI6/DT8RZbz4cHmKTIQoFLkBjQRl2eI6AQwAwgDv1oraOTap
|
||||||
|
HXwNdGJG9G8XIbie4w0iEhhIMpqiwbfrhBYDVKG+W9zoOzy5uu4D9OrnijFQgBlw
|
||||||
|
5gYqdmfHbpFDse1o0IMKYf+D/K9Ju/ZumBJHyI/SxkRT/MTkMmTW2Cse3sprujJO
|
||||||
|
nvEyWt0PrT7ce/oJEfngjCIlPBoGdvAIoOToWi3+nqNHRksFaiMFV7151Sj3UWmb
|
||||||
|
kd+VI9FooIgAvpr+c7mNkXBlASQGcm8ccaVseoKoi+EcLzZrnSFBAvYNDw/9fMue
|
||||||
|
M1VsowkYjRmjhVqapRM2TVwlZhA9PBOwmcljYe7UXwF1rEpT6EkNKe2iL3cZ1PU6
|
||||||
|
ElffLk3Gt7Y7BYOMftWY9d987jJhX0C8K5yygPtAG9hFlB+BEMNhNQlcSGKDRUfs
|
||||||
|
W1rHLV2cHS9OUe8WLCKczZPCunuNQ7QTGSdOdgeMUps4MIWgauXNRFYBU+g4vYf8
|
||||||
|
ibLaPACwMaGgj3CR4T5VaMx7c9DvOb6iKNT9kNje/CB/TXqW4S+lABEBAAGJAbwE
|
||||||
|
GAEKACYWIQTRYwKrox7TG4ZGCRp6bLMYX9rUwAUCZdniOgIbDAUJA8JnAAAKCRB6
|
||||||
|
bLMYX9rUwFjBC/4lO/cKl46AZ1+MwMrIMlb5/JCsa2uMloKllcnkufoqKSyW6yWk
|
||||||
|
0H7kqpsk4sSg53gGnfgIUrNo88FSac8OyMRmapbJRiq5kriJyJvadZdBpjVK/vAG
|
||||||
|
PxdsRWeGFpnNz8eZOINbZBPg6/inLixloQeiJpMg11J2qVniGvqgPLTZ3AxmGUmL
|
||||||
|
IDajBR7uYJgws0hw/pXGU1OQ5Z93472J44FxHMTRlTtA3AvCOLZ8v2O/wyBfKfpm
|
||||||
|
x+0NpIauJ3pCerrsfpdwvftxubyBVtbsqvxLODBj79Pg6H+MPJN9aQeC3DNN9dA3
|
||||||
|
ABRcFfFGpZ1u3Hh31xMo3+g1AGjl2E1wBliLy9wZwvJNtqX/gIqRFccYCNFNwama
|
||||||
|
+sz87Je6Ykb350onCeKr6BtzU11A6RqXvdpFQQ3MQ1lDVF8J1XiXdKWE5X/KHjKR
|
||||||
|
/5iPPc93z7ttRgcnJ5kEbHJPKMLMmMU7rTF6Af9+sxjgoolPTMzcjyek1ilVKdKv
|
||||||
|
wNGl4zykRU8x8Qs=
|
||||||
|
=9AAX
|
||||||
|
-----END PGP PUBLIC KEY BLOCK-----
|
||||||
|
```
|
||||||
|
|
@ -3,26 +3,27 @@ on:
|
||||||
release:
|
release:
|
||||||
types: [published]
|
types: [published]
|
||||||
jobs:
|
jobs:
|
||||||
update-version:
|
update-version-and-publish:
|
||||||
permissions:
|
permissions:
|
||||||
contents: write
|
contents: write
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: main
|
||||||
|
token: ${{ secrets.DEVOPS_BOT_PAT }}
|
||||||
|
|
||||||
- name: Update version
|
- name: Update version
|
||||||
run: |
|
run: |
|
||||||
echo "Updating version"
|
echo "Updating version"
|
||||||
sed -i "s/version: .*/version: ${{ github.event.release.tag_name }}/g" galaxy.yml
|
sed -i "s/version: .*/version: ${{ github.event.release.tag_name }}/g" galaxy.yml
|
||||||
|
|
||||||
- uses: stefanzweifel/git-auto-commit-action@v4
|
- uses: stefanzweifel/git-auto-commit-action@v4
|
||||||
with:
|
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"
|
branch: "main"
|
||||||
|
file_pattern: "galaxy.yml"
|
||||||
ansible-publish:
|
push_options: --force
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- uses: ansible/ansible-publish-action@v1.0.0
|
- uses: ansible/ansible-publish-action@v1.0.0
|
||||||
with:
|
with:
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ jobs:
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
ref: main
|
ref: main
|
||||||
|
token: ${{ secrets.DEVOPS_BOT_PAT }}
|
||||||
|
|
||||||
- name: Update Changelog
|
- name: Update Changelog
|
||||||
uses: stefanzweifel/changelog-updater-action@v1
|
uses: stefanzweifel/changelog-updater-action@v1
|
||||||
|
|
@ -28,3 +29,4 @@ jobs:
|
||||||
branch: main
|
branch: main
|
||||||
commit_message: Update CHANGELOG
|
commit_message: Update CHANGELOG
|
||||||
file_pattern: CHANGELOG.md
|
file_pattern: CHANGELOG.md
|
||||||
|
push_options: --force
|
||||||
|
|
|
||||||
92
CHANGELOG.md
92
CHANGELOG.md
|
|
@ -1,3 +1,95 @@
|
||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
All notable changes to this project will be documented in this file.
|
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
107
README.md
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ namespace: dominion_solutions
|
||||||
name: netbird
|
name: netbird
|
||||||
|
|
||||||
# The version of the collection. Must be compatible with semantic versioning
|
# 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
|
# The path to the Markdown (.md) readme file. This path is relative to the root of the collection
|
||||||
readme: README.md
|
readme: README.md
|
||||||
|
|
|
||||||
|
|
@ -59,9 +59,8 @@ options:
|
||||||
description: Whether or not to fail if a group or variable is not found.
|
description: Whether or not to fail if a group or variable is not found.
|
||||||
compose:
|
compose:
|
||||||
description: compose variables for Ansible based on jinja2 expression and inventory vars
|
description: compose variables for Ansible based on jinja2 expression and inventory vars
|
||||||
default: False
|
|
||||||
required: False
|
required: False
|
||||||
type: boolean
|
type: dict
|
||||||
keyed_groups:
|
keyed_groups:
|
||||||
description: create groups for plugins based on variable values and add the corresponding hosts to it
|
description: create groups for plugins based on variable values and add the corresponding hosts to it
|
||||||
type: list
|
type: list
|
||||||
|
|
@ -106,7 +105,9 @@ display = Display()
|
||||||
|
|
||||||
class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||||
NAME = "dominion_solutions.netbird.netbird"
|
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):
|
def _build_client(self, loader):
|
||||||
"""Build the Netbird API Client"""
|
"""Build the Netbird API Client"""
|
||||||
|
|
@ -129,7 +130,12 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||||
def _add_groups(self):
|
def _add_groups(self):
|
||||||
""" Add peer groups to the inventory. """
|
""" Add peer groups to the inventory. """
|
||||||
self.netbird_groups = set(
|
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:
|
for group in self.netbird_groups:
|
||||||
self.inventory.add_group(group)
|
self.inventory.add_group(group)
|
||||||
|
|
||||||
|
|
@ -141,7 +147,10 @@ class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||||
|
|
||||||
def _get_peer_inventory(self):
|
def _get_peer_inventory(self):
|
||||||
"""Get the inventory from the Netbird API"""
|
"""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):
|
def _filter_by_config(self):
|
||||||
"""Filter peers by user specified configuration."""
|
"""Filter peers by user specified configuration."""
|
||||||
|
|
@ -279,6 +288,9 @@ class NetbirdApi:
|
||||||
}
|
}
|
||||||
peers = []
|
peers = []
|
||||||
response = requests.request("GET", url, headers=headers)
|
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)
|
peer_json = json.loads(response.text)
|
||||||
for current_peer_map in peer_json:
|
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)
|
current_peer = Peer(current_peer_map["hostname"], current_peer_map['dns_label'], current_peer_map["id"], current_peer_map)
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
ansible>=9.2.0
|
ansible>=9.2.0
|
||||||
ansible-core>=2.16.3
|
ansible-core>=2.16.3
|
||||||
cffi==1.16.0
|
cffi==1.16.0
|
||||||
cryptography==42.0.2
|
cryptography==42.0.4
|
||||||
epdb==0.15.1
|
epdb==0.15.1
|
||||||
Jinja2==3.1.3
|
Jinja2==3.1.3
|
||||||
jsonpickle==3.0.3
|
jsonpickle==3.0.3
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"message": "token invalid",
|
||||||
|
"code": 401
|
||||||
|
}
|
||||||
|
|
@ -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
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
plugin: netbird
|
plugin: dominion_solutions.netbird.netbird
|
||||||
api_key: nbp_1234567890123456789012345678901234567
|
api_key: nbp_this_is_a_fake_api_key
|
||||||
api_url: https://netbird.example.com/api/v1
|
api_url: https://netbird.example.com/api/v1
|
||||||
ip_style: plain
|
ip_style: plain
|
||||||
netbird_connected: False
|
netbird_connected: False
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
---
|
---
|
||||||
plugin: netbird
|
plugin: netbird
|
||||||
api_key: nbp_1234567890123456789012345678901234567
|
api_key: nbp_this_is_a_fake_api_key
|
||||||
api_url: https://netbird.example.com/api/v1
|
api_url: https://netbird.example.com/api/v1
|
||||||
ip_style: plain
|
ip_style: plain
|
||||||
netbird_connected: True
|
netbird_connected: True
|
||||||
|
|
@ -9,3 +9,4 @@ groups:
|
||||||
strict: No
|
strict: No
|
||||||
keyed_groups:
|
keyed_groups:
|
||||||
compose:
|
compose:
|
||||||
|
ansible_ssh_host: ip
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
@ -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"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
@ -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
|
||||||
|
|
@ -25,7 +25,7 @@ display = Display()
|
||||||
def inventory():
|
def inventory():
|
||||||
plugin = InventoryModule()
|
plugin = InventoryModule()
|
||||||
plugin.templar = Templar(loader=DataLoader())
|
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
|
plugin._load_name = plugin.NAME
|
||||||
return plugin
|
return plugin
|
||||||
|
|
||||||
|
|
@ -44,6 +44,34 @@ def netbird_api():
|
||||||
return mock_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):
|
def test_missing_access_token_lookup(inventory):
|
||||||
loader = DataLoader()
|
loader = DataLoader()
|
||||||
inventory._options = {'api_key': None, 'api_url': None}
|
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 inventory.inventory.hosts is not None
|
||||||
assert len(inventory.inventory.hosts) == 1
|
assert len(inventory.inventory.hosts) == 1
|
||||||
assert list(inventory.inventory.hosts.values())[0].get_vars().get('connected') is True
|
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
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue