salt-netbox-roleproxy/roleproxy.py

83 lines
2.5 KiB
Python
Executable File

#!/usr/bin/python3
"""
Copyright 2023, Georg Pfuetzenreuter
Licensed under the EUPL, Version 1.2 or - as soon they will be approved by the European Commission - subsequent versions of the EUPL (the "Licence").
You may not use this work except in compliance with the Licence.
An English copy of the Licence is shipped in a file called LICENSE along with this applications source code.
You may obtain copies of the Licence in any of the official languages at https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12.
---
This program serves a custom "salt_roles" field in NetBox via a HTTP API consumable in Salt top files.
"""
import flask
import logging
import os
import pynetbox
from waitress import serve
if not 'NB_HOST' in os.environ or not 'NB_TOKEN' in os.environ:
print('Pass NB_HOST and NB_TOKEN as environment variables.')
import sys
sys.exit(1)
host = os.environ['NB_HOST']
token = os.environ['NB_TOKEN']
app = flask.Flask(__name__)
def connect(host, token):
netbox = pynetbox.api(host, token)
return(netbox)
def get_roles(netbox, name):
vm = netbox.virtualization.virtual_machines.filter(name=name)
vmroles = {}
if len(vm) > 0:
vmroles = vm[0].custom_fields['salt_roles']
if vmroles is None:
vmroles = {}
return(200, vmroles)
if len(vm) == 0:
return(404, None)
def get_master(netbox, name):
vm = netbox.virtualization.virtual_machines.filter(name=name)
if len(vm) > 0:
vmmaster = vm[0].config_context.salt_master
return(200, vmmaster)
if len(vm) == 0:
return(404, None)
@app.route('/roles')
def query_roles():
name = flask.request.args.get('machine')
query = get_roles(connect(host, token), name)
response = query[0]
logger.info(' %s requested roles for %s and received %i', flask.request.remote_addr, name, response)
if response == 404:
flask.abort(404)
elif response == 200:
roledict = {'roles': query[1]}
return(flask.jsonify(roledict))
@app.route('/master')
def query_master():
name = flask.request.args.get('machine')
query = get_master(connect(host, token), name)
response = query[0]
logger.info(' %s requested master for %s and received %i', flask.request.remote_addr, name, response)
if response == 404:
flask.abort(404)
elif response == 200:
return(query[1])
if __name__ == '__main__':
#app.run(debug=False)
logger = logging.getLogger('roleproxy')
logger.setLevel(logging.INFO)
logger.info('Booting ...')
serve(app, host='*', port=4580)