WIP! Getting the netbird api up
This commit is contained in:
parent
6acbd0acc2
commit
93f4f8b67f
|
|
@ -1,3 +0,0 @@
|
|||
image: python:3.17-alpine3.19
|
||||
before_script:
|
||||
- pip install -r requirements.txt
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
from __future__ import (absolute_import, division, print_function)
|
||||
__metaclass__ = type
|
||||
|
||||
DOCUMENTATION = r"""
|
||||
name: netbird
|
||||
author:
|
||||
- Mark Horninger (@dominion.soltuions@mstdn.business) <mark.horninger@dominion.solutions>
|
||||
version_added: "0.0.2"
|
||||
requirements:
|
||||
- requests>=2.31.0
|
||||
short_description:
|
||||
description:
|
||||
-
|
||||
extends_documentation_fragment:
|
||||
- constructed
|
||||
- inventory_cache
|
||||
options:
|
||||
api_key:
|
||||
description: The API Key for the Netbird API.
|
||||
required: true
|
||||
type: string
|
||||
env:
|
||||
- name: NETBIRD_API_KEY
|
||||
notes:
|
||||
- if read in variable context, the file can be interpreted as YAML if the content is valid to the parser.
|
||||
- this lookup does not understand globbing --- use the fileglob lookup instead.
|
||||
"""
|
||||
|
||||
EXAMPLES = r"""
|
||||
"""
|
||||
from ansible.errors import AnsibleError, AnsibleParserError
|
||||
from ansible.utils.display import Display
|
||||
from ansible.plugins.inventory import BaseInventoryPlugin, Constructable, Cacheable
|
||||
|
||||
# Specific for the NetbirdAPI Class
|
||||
import requests
|
||||
import json
|
||||
|
||||
display = Display()
|
||||
|
||||
class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
|
||||
NAME="dominion_solutions.netbird"
|
||||
|
||||
def _build_client(self):
|
||||
"""Build the Netbird API Client"""
|
||||
access_token = self.get_option('api_key')
|
||||
api_url = self.get_option('api_url')
|
||||
if access_token is None:
|
||||
raise AnsibleError("Could not retrieve the Netbird API Key from the configuration sources.")
|
||||
self.client = NetbirdApi(self.get_option('api_key'), self.get_option('api_url'))
|
||||
|
||||
def _get_peer_inventory(self):
|
||||
"""Get the inventory from the Netbird API"""
|
||||
return json.loads(self.client.ListPeers())
|
||||
|
||||
def parse(self, inventory, loader, path, cache=True):
|
||||
"""Dynamically parse the inventory from the Netbird API"""
|
||||
super(InventoryModule, self).parse(inventory, loader, path)
|
||||
self.peers = None
|
||||
|
||||
self._read_config_data(path)
|
||||
cache_key = self.get_cache_key(path)
|
||||
|
||||
if cache:
|
||||
cache = self.get_option('cache')
|
||||
update_cache = False
|
||||
if cache:
|
||||
try:
|
||||
self.peers = [Peer(None, i["id"], i) for i in self._cache[cache_key]]
|
||||
except KeyError:
|
||||
update_cache = True
|
||||
|
||||
# Check for None rather than False in order to allow
|
||||
# for empty sets of cached instances
|
||||
if self.instances is None:
|
||||
self._build_client(loader)
|
||||
self._get_peer_inventory()
|
||||
|
||||
if update_cache:
|
||||
self._cache[cache_key] = self._cacheable_inventory()
|
||||
|
||||
self.populate()
|
||||
|
||||
|
||||
### This is a very limited wrapper for the netbird API.
|
||||
class NetbirdApi:
|
||||
def __init__ (self, api_key, api_url):
|
||||
self.api_key = api_key
|
||||
self.api_url = api_url
|
||||
def ListPeers(self):
|
||||
url = f"{self.api_url}/peers"
|
||||
|
||||
headers = {
|
||||
'Accept': 'application/json',
|
||||
'Authorization': f'Token {self.api_key}'
|
||||
}
|
||||
response = requests.request("GET", url, headers=headers)
|
||||
return response.text
|
||||
|
||||
class Peer:
|
||||
def __init__(self, name, id, data):
|
||||
self.name = name
|
||||
self.id = id
|
||||
self.data = data
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2024 Dominion Solutions LLC <sales@dominion.solutions> (https://dominion.solutions)
|
||||
# SPDX-License-Identifier: MIT
|
||||
|
||||
from __future__ import (absolute_import, division, print_function)
|
||||
__metaclass__ = type
|
||||
|
||||
import pytest
|
||||
import sys
|
||||
|
||||
from ansible.errors import AnsibleError
|
||||
from ansible.parsing.dataloader import DataLoader
|
||||
from ansible.template import Templar
|
||||
from ansible_collections.community.general.plugins.inventory.linode import InventoryModule
|
||||
|
||||
|
||||
@pytest.fixture(scope="module")
|
||||
def inventory():
|
||||
plugin = InventoryModule()
|
||||
plugin.templar = Templar(loader=DataLoader())
|
||||
return plugin
|
||||
|
||||
|
||||
def test_missing_access_token_lookup(inventory):
|
||||
loader = DataLoader()
|
||||
inventory._options = {'access_token': None}
|
||||
with pytest.raises(AnsibleError) as error_message:
|
||||
inventory._build_client(loader)
|
||||
assert 'Could not retrieve Linode access token' in error_message
|
||||
|
||||
|
||||
def test_verify_file(tmp_path, inventory):
|
||||
file = tmp_path / "foobar.netbird.yml"
|
||||
file.touch()
|
||||
assert inventory.verify_file(str(file)) is True
|
||||
|
||||
|
||||
def test_verify_file_bad_config(inventory):
|
||||
assert inventory.verify_file('foobar.netbird.yml') is False
|
||||
|
|
@ -7,4 +7,6 @@ MarkupSafe==2.1.5
|
|||
packaging==23.2
|
||||
pycparser==2.21
|
||||
PyYAML==6.0.1
|
||||
requests>=2.31.0
|
||||
resolvelib==1.0.1
|
||||
pytest==8.0.0
|
||||
|
|
|
|||
Loading…
Reference in New Issue