transfer github

This commit is contained in:
Stefan 2024-12-30 20:02:57 +01:00
parent 4f9725daa9
commit cdd5fab8e4
14 changed files with 822 additions and 2 deletions

23
ansible/README.md Normal file
View File

@ -0,0 +1,23 @@
# Ansible
## Complete examples
Example and code fragments for Cisco, Netbox and Ansible.
* `debian-graylog-example` Ansible Role to onboard Debian Linux Servers in Graylog Open
*
* `windows-graylog-example` Ansible Role to onboard Windows Servers in Graylog Open
* `windows-snmp-example` OpenSSH Server on Windows and SNMP Service installation with Ansible
* `windows-nsclientplusplus-example` NSCLient++ on Windows installation with Ansible
## Code snippets
* `cisco-asa-firewalls-serial-nums.yaml` Collects minimum facts from ASA in single or clustered mode
* `netbox-cisco-asa-firewall-serialnums.yaml` Update Serial number of single and clustered ASA firewall
* `netbox-cisco-switch-serialnums.yaml` Update Serial number of single and stacked switch
* `collect_mac_address.yaml` Collect MAC addresses from Cisco Switches

View File

@ -0,0 +1,77 @@
---
# ASA / Min-Facts
# ===============
# Collects minimum facts from ASA in single or clustered mode
#
# 2023-08-26 stefan init
#
- name: "Block: Min-Facts Firewall-Single"
block:
- name: "Firewall-Single: Get Min-Facts"
cisco.asa.asa_command:
commands:
- show run | include hostname
- show version
- show inventory
register: asa_vars
- name: "Firewall-Single: Extract Min-Facts"
set_fact:
ansible_net_hostname: "{{ asa_vars.stdout[0].split()[1] }}"
ansible_net_version: "{{ asa_vars.stdout[1].split('\n')[0].split()[6] }}"
ansible_net_model: "{{ asa_vars.stdout[2].split('\n')[1].split()[1] }}"
ansible_net_serialnum: "{{ asa_vars.stdout[2].split('\n')[1].split()[7] }}"
- name: "Firewall-Single: Display Min-Facts"
debug:
msg: "Device: {{ ansible_net_hostname }} is model: {{ ansible_net_model }} with serial: {{ ansible_net_serialnum }} and version: {{ ansible_net_version }}"
when: role == "Firewall-Single"
- name: "Block: Min-Facts Firewall-Cluster"
block:
- name: "Firewall-Cluster: Get Min-Facts Primary"
cisco.asa.asa_command:
commands:
- show run | include hostname
- show version
- show inventory
register: asa_vars_primary
- name: "Firewall-Cluster: Get Min-Facts Failover"
cisco.asa.asa_command:
commands:
- failover exec mate show run | include hostname
- failover exec mate show version
- failover exec mate show inventory
register: asa_vars_failover
ignore_errors: yes
- name: "Firewall-Cluster: Extract Min-Facts Hostname/Version"
set_fact:
ansible_net_hostname: "{{ asa_vars_primary.stdout[0].split()[1] }}"
ansible_net_version: "{{ asa_vars_primary.stdout[1].split('\n')[0].split()[6] }}"
- name: "Firewall-Cluster: Extract Min-Facts Stacked Models"
set_fact:
ansible_net_stacked_models:
- "{{ asa_vars_primary.stdout[2].split('\n')[1].split()[1] }}"
- "{{ asa_vars_failover.stdout[2].split('\n')[1].split()[1] }}"
ignore_errors: yes
- name: "Firewall-Cluster: Extract Min-Facts Stacked Serials"
set_fact:
ansible_net_stacked_serialnums:
- "{{ asa_vars_primary.stdout[2].split('\n')[1].split()[7] }}"
- "{{ asa_vars_failover.stdout[2].split('\n')[1].split()[7] }}"
ignore_errors: yes
- name: "Firewall-Cluster: Display Min-Facts"
debug:
msg: "Device: {{ ansible_net_hostname }} is model: {{ ansible_net_stacked_models }} with serial: {{ ansible_net_stacked_serialnums }} and version: {{ ansible_net_version }}"
when: role == "Firewall-Cluster"

View File

@ -0,0 +1,21 @@
---
# Collect MAC Address Table
# =========================
# 2023-10-25 stefan init
- name: "Collect MAC Address"
block:
- name: "Get facts"
cisco.ios.ios_facts:
gather_subset: all
- name: "Register output of show command"
cisco.ios.ios_command:
commands: 'show mac address-table dynamic'
register: mac_addr
- name: "Save output to file"
ansible.builtin.copy:
content="{{ mac_addr.stdout | replace('\\n', '\n') }}"
dest=/home/stefan/mac_addr/{{ inventory_hostname }}.txt

View File

@ -0,0 +1,38 @@
---
# NetBox / Update Serial Numbers
# ==============================
# Update Serial number of single and clustered ASA firewall
#
# 2023-08-26 stefan init
#
#
# Update Serial Number of Single Firewall
#
- name: "Firewall-Single: Update Serial Number"
netbox.netbox.netbox_device:
netbox_url: "{{ netbox_url }}"
netbox_token: "{{ netbox_token }}"
validate_certs: no
data:
name: "{{ fqdn }}"
serial: "{{ ansible_net_serialnum }}"
state: present
ignore_errors: yes
#
# Update Serial Number of Clustered Firewall
#
- name: "Firewall-Cluster: Update Serial Numbers"
netbox.netbox.netbox_device:
netbox_url: "{{ netbox_url }}"
netbox_token: "{{ netbox_token }}"
validate_certs: no
data:
name: "{{ item.name }}"
serial: "{{ ansible_net_stacked_serialnums[idx_stack] }}"
state: present
loop: "{{ vchassis_stacked_firewalls }}"
loop_control:
index_var: idx_stack
ignore_errors: yes

View File

@ -0,0 +1,37 @@
---
# NetBox / Update Serial Numbers
# ==============================
# Update Serial number of single and stacked switch
#
# 2023-08-26 stefan init
#
#
# Update Serial Number of Single Switch
#
- name: "Switch-Single: Update Serial"
netbox.netbox.netbox_device:
netbox_url: "{{ netbox_url }}"
netbox_token: "{{ netbox_token }}"
validate_certs: no
data:
name: "{{ name }}"
serial: "{{ ansible_net_serialnum }}"
state: present
#
# Update all Serial Number of Switch-Stack
#
- name: "Switch-Stack: Update Serials"
netbox.netbox.netbox_device:
netbox_url: "{{ netbox_url }}"
netbox_token: "{{ netbox_token }}"
validate_certs: no
data:
name: "{{ item.name }}"
serial: "{{ ansible_net_stacked_serialnums[idx_stack] }}"
state: present
loop: "{{ vchassis_stacked_switches }}"
loop_control:
index_var: idx_stack

View File

@ -2,7 +2,7 @@
## English
🇺🇸 [Ansible Role to onboard Windows Servers in Graylog Open](https://www.thierolf.org/en/ansible/ansible-role-to-onboard-windows-server-in-graylog-open)
🇬🇧 [Ansible Role to onboard Windows Servers in Graylog Open](https://www.thierolf.org/en/ansible/ansible-role-to-onboard-windows-server-in-graylog-open)
## Deutsch

View File

@ -2,7 +2,7 @@
## English
🇺🇸 [OpenSSH Server on Windows and SNMP Service Installation with Ansible](https://www.thierolf.org/posts/openssh-server-on-windows-and-snmp-service-installation-with-ansible/)
🇬🇧 [OpenSSH Server on Windows and SNMP Service Installation with Ansible](https://www.thierolf.org/posts/openssh-server-on-windows-and-snmp-service-installation-with-ansible/)
## Deutsch

15
netbox/README.md Normal file
View File

@ -0,0 +1,15 @@
# Netbox
Example and code fragments for Cisco, Netbox and Ansible.
* `backup2git.py` Python script to backup Cisco configs controlled by Netbox status and pushing them to GitLab
* `netbox-librenms-graph.py` Include Interface graphs from LibreNMS in Netbox
* `netbox-librenms.py` Pass (link) device from Netbox to LibreNMS
* `netbox-snipeit.php` Pass (link) device from Netbox to Snipe-IT (PHP)
* `netbox-snipeit.py` Pass (link) device from Netbox to Snipe-IT (Python)
* `qrcode-snipeit.py` QR-Codes Snipe-IT

303
netbox/backup2git.py Normal file
View File

@ -0,0 +1,303 @@
#!/usr/bin/python3
import pynetbox
import requests
import urllib3
import pexpect
import sys
import json
import gitlab
from datetime import date
today = str(date.today())
###############################################################################
#
# Set global variables
#
###############################################################################
# Netbox URL and Token
netbox_url = "https://HOST_OR_IP"
netbox_token = "TOKEN"
# Gitlab URL and Token
gitlab_url = "https://HOST_OR_IP"
gitlab_token = "TOKEN"
# SCP User, Password and Host (SCP host can be same like Netbox host)
scp_user = "USERNAME"
scp_pass = "PASSWORD"
scp_host = "HOST_OR_IP"
# Set User, Password and Enable to connect with SSH to devices
backup_user = "USERNAME"
backup_pass = "PASSWORD"
backup_enable = "ENABLE_PASSWORD"
# Set Gitlab project ID
project_id = PROJECT_ID
###############################################################################
def getDevicesFromNetbox():
urllib3.disable_warnings()
requests.packages.urllib3.disable_warnings()
netbox = pynetbox.api(
url = netbox_url,
token = netbox_token,
threading = True
)
netbox.http_session.verify = False
# init empty device array
devices_netbox = []
#
# Build a list with Core-Switches
# Note: The filtering by role depends on the roles defined in netbox
#
# the list needs at minimum the following information:
# device / site / hostname / status / ipv4 address
# device: used to determine the device and what CLI commands are required to start a backup
# site: used to build a directory structure in gitlab project
# hostname: the hostname of the device to build .cfg
# status: to determine if device can be backed up or is out of it
# ipv4: IP address to connect to the device
core_switch = netbox.dcim.devices.filter(role='net-core-switch')
for i in range(0, len(core_switch)):
data = netbox.dcim.devices.get(name = core_switch[i])
hostname = str(data).split(":")
hostname = hostname[0]
device_details = ["switch", str(data.site), hostname, str(data.primary_ip), str(data.status)]
devices_netbox.append(device_details)
access_switch = netbox.dcim.devices.filter(role='net-access-switch')
for i in range(0, len(access_switch)):
data = netbox.dcim.devices.get(name = access_switch[i])
hostname = str(data).split(":")
hostname = hostname[0]
device_details = ["switch", str(data.site), hostname, str(data.primary_ip), str(data.status)]
devices_netbox.append(device_details)
wifi_controller = netbox.dcim.devices.filter(role='net-wireless-lan-controller')
for i in range(0, len(wifi_controller)):
data = netbox.dcim.devices.get(name = wifi_controller[i])
hostname = str(data).split(":")
hostname = hostname[0]
device_details = ["wificontroller", str(data.site), hostname, str(data.primary_ip), str(data.status)]
devices_netbox.append(device_details)
wan_firewall = netbox.dcim.devices.filter(role='net-wan-firewall')
for i in range(0, len(wan_firewall)):
data = netbox.dcim.devices.get(name = wan_firewall[i])
hostname = str(data).split(":")
hostname = hostname[0]
device_details = ["wanfirewall", str(data.site), hostname, str(data.primary_ip), str(data.status)]
devices_netbox.append(device_details)
return devices_netbox
###############################################################################
def cliCiscoSwitch():
try:
print ("INFO: Connecting to device: " + hostname + " with IP: " + ipv4)
sshconn = pexpect.spawn('ssh %s@%s' % (backup_user, ipv4))
#sshconn.logfile = sys.stdout.buffer
sshconn.timeout = 30
sshconn.expect('.*assword:.*')
sshconn.sendline(backup_pass)
sshconn.expect('#')
sshconn.sendline('term len 0')
sshconn.expect('#')
print ('INFO: Set exec banner')
sshconn.sendline('conf t')
sshconn.expect('#')
sshconn.sendline('file prompt quiet')
sshconn.expect('#')
sshconn.sendline('banner exec ^')
sshconn.sendline(today + ' - Config saved by backup2git')
sshconn.sendline('^')
sshconn.expect('#')
sshconn.sendline('exit')
print ('INFO: Executing write memory command')
sshconn.sendline('wr mem')
sshconn.expect('.*OK.*')
print ('INFO: Executing copy run scp command')
sshconn.sendline('copy run scp://' + scp_user + ':' + scp_pass + '@' + scp_host + '//tmp/' + hostname + '.cfg')
sshconn.expect('.*copied.*')
print ('INFO: Log out from device: ' + hostname + " with ip: " + ipv4)
sshconn.sendline('logout')
except pexpect.TIMEOUT:
print ("ERROR: No login to device: " + hostname + " with ip: " + ipv4)
pass
###############################################################################
def cliCiscoWirelessController():
try:
print ("INFO: Connecting to device: " + hostname + " with IP: " + ipv4)
sshconn = pexpect.spawn('ssh %s@%s' % (backup_user, ipv4))
#sshconn.logfile = sys.stdout.buffer
sshconn.timeout = 30
sshconn.expect('.*ser:.*')
sshconn.sendline(backup_user)
sshconn.expect('.*assword:.*')
sshconn.sendline(backup_pass)
sshconn.expect('>')
print ('INFO: Executing save config command')
sshconn.sendline('save config')
sshconn.expect('(y/n)')
sshconn.sendline('y')
print ('INFO: set transfer parameters')
sshconn.sendline('transfer upload datatype config')
sshconn.expect('>')
sshconn.sendline('transfer upload mode sftp')
sshconn.expect('>')
sshconn.sendline('transfer upload serverip ' + scp_host)
sshconn.expect('>')
sshconn.sendline('transfer upload filename ' + hostname + ".cfg")
sshconn.expect('>')
sshconn.sendline('transfer upload path /tmp/')
sshconn.expect('>')
sshconn.sendline('transfer upload username ' + scp_user)
sshconn.expect('>')
sshconn.sendline('transfer upload password ' + scp_pass)
sshconn.expect('>')
print ('INFO: Executing transfer upload start command')
sshconn.sendline('transfer upload start')
sshconn.expect('(y/N)')
sshconn.sendline('y')
sshconn.expect('successfully.')
print ('INFO: Log out from device: ' + hostname + " with ip: " + ipv4)
sshconn.sendline('logout')
except pexpect.TIMEOUT:
print ("ERROR: No login to device: " + hostname + " with ip: " + ipv4)
pass
###############################################################################
def cliCiscoAsaFirewall():
try:
print ("INFO: Connecting to device: " + hostname + " with IP: " + ipv4)
sshconn = pexpect.spawn('ssh %s@%s' % (backup_user, ipv4))
#sshconn.logfile = sys.stdout.buffer
sshconn.timeout = 30
sshconn.expect('.*assword:.*')
sshconn.sendline(backup_pass)
sshconn.expect('>')
sshconn.sendline('enable')
sshconn.expect('.*assword:.*')
sshconn.sendline(backup_pass)
print ('INFO: Executing write memory command')
sshconn.sendline('wr mem')
sshconn.expect('.*OK.*')
print ('INFO: Executing copy run scp command')
sshconn.sendline('copy run scp://' + scp_user + ':' + scp_pass + '@' + scp_host + '//tmp/' + hostname + '.cfg')
sshconn.expect('.*ource')
sshconn.sendline()
sshconn.expect('.*ddress')
sshconn.sendline()
sshconn.expect('.*sername')
sshconn.sendline()
sshconn.expect('.*ilename')
sshconn.sendline()
sshconn.expect('continue connecting')
sshconn.sendline('yes')
sshconn.expect('copied')
sshconn.sendline('logout')
print ('INFO: Log out from device: ' + hostname + " with ip: " + ipv4)
sshconn.sendline('logout')
except pexpect.TIMEOUT:
print ("ERROR: No login to device: " + hostname + " with ip: " + ipv4)
pass
###############################################################################
# Get the devices from Netbox
devices = getDevicesFromNetbox()
# Use a for-loop to go through the devices and check in the configuration files
for i in range(0, len(devices)):
# Split list
role = str(devices[i][0])
location = str(devices[i][1])
hostname = str(devices[i][2])
ipv4 = str(devices[i][3])[:len(str(devices[i][3]))-3]
status = str(devices[i][4])
# If device is active and has a primary IPv4 address (ssh connect action)
if status == "Active" and ipv4 != "N":
# role is a switch
if role == "switch":
cliCiscoSwitch()
# role is a wlc
elif role == "wificontroller":
cliCiscoWirelessController()
# role is a firewall
elif role == "wanfirewall":
cliCiscoAsaFirewall()
# handle list from netbox if device is missing ipv4 or if
# device status is set to something else than active
else:
print ("WARN: device not set to active or IP missing")
# If device is active and has primary IPv4 address (open file action)
if status == "Active" and ipv4 != "N":
# open config file and read it into a string variable
try:
content = open('/tmp/' + hostname + '.cfg').read()
except:
print ("ERROR: Cannot open file: " + hostname + ".cfg")
urllib3.disable_warnings()
requests.packages.urllib3.disable_warnings()
gl = gitlab.Gitlab(gitlab_url, ssl_verify=False, private_token=gitlab_token)
# authenticate
gl.auth()
# get gitlab project
project = gl.projects.get(project_id)
# try with a commit create if file does not exist on gitlab project
try:
data_create = {
'branch': 'master',
'commit_message': 'Initial commit of config file on ' + today + ' by backup2git',
'actions': [
{
'action': 'create',
'file_path': location + '/' + hostname + '.cfg',
'content': open('/tmp/' + hostname + '.cfg').read(),
}
]
}
except:
print ("Cannot build commit create JSON")
pass
# If file exists, use commit update to check in new version of file
try:
data_update = {
'branch': 'master',
'commit_message': 'Update of config file on ' + today + ' by backup2git',
'actions': [
{
'action': 'update',
'file_path': location + '/' + hostname + '.cfg',
'content': open('/tmp/' + hostname + '.cfg').read(),
}
]
}
except:
print ("Cannot build commit update JSON")
pass

View File

@ -0,0 +1,63 @@
#!/usr/bin/python3
# This file is copyright under the latest version of the EUPL.
# Please see LICENSE file for your rights under this license.
import requests
import cgi
import cgitb
import time
import urllib.parse
import sys
#
# LibreNMS HOST and API token
#
librenms_host = 'https://LIBRENMS_HOST'
token = 'LIBRENMS_API_TOKEN'
#
# get form data
#
cgitb.enable()
form = cgi.FieldStorage()
if "device" in form and "interface" in form:
timefrom = str(int(time.time()) - 28800)
device = form.getvalue('device')
interface = form.getvalue('interface')
for i in range(0,9):
device = device.replace(':' + str(i), '')
device = urllib.parse.quote(device, safe='')
interface = urllib.parse.quote(interface, safe='')
url = librenms_host + '/api/v0/devices/' + device + '/ports/' + interface + '/port_bits?width=780&height=200&from=' + timefrom
headers = {'X-Auth-Token': token}
r = requests.get(url, headers = headers)
#
# if status code is 200, then print interface graph
#
if r.status_code == requests.codes.ok:
#
# LibreNMS must return something like an ID
# If there is no ID, then just list all devices
#
print ("Content-Type: image/png")
print ()
sys.stdout.flush()
sys.stdout.buffer.write(r.content)
else:
print ('Content-Type: text/html')
print ()
print ('error')
#
# handle all other errors by printing out error
#
else:
print ('Content-Type: text/html')
print ()
print ('error')

70
netbox/netbox-librenms.py Normal file
View File

@ -0,0 +1,70 @@
#!/usr/bin/python3
# This file is copyright under the latest version of the EUPL.
# Please see LICENSE file for your rights under this license.
import requests
import cgi
import cgitb
import json
#
# LibreNMS HOST and API token
#
librenms_host = 'https://LIBRENMS_HOST'
token = 'LIBRENMS_TOKEN'
#
# get form data
#
cgitb.enable()
form = cgi.FieldStorage()
#
# handle devices
#
if "devicegroup" in form:
devicegroup = form.getvalue('devicegroup')
url = librenms_host + '/api/v0/devicegroups'
headers = {'X-Auth-Token': token}
r = requests.get(url, headers = headers)
#
# if status code is 200, then redirect to device group
#
if r.status_code == requests.codes.ok:
#
# LibreNMS must return something like an ID
# If there is no ID, then just list all devices
#
try:
data = r.json()
#
# LibreNMS API returns a count of device groups
#
rows = data['count']
#
# Look up ID by group name
#
for i in range(0, rows):
group_name = str(data['groups'][i]['name'])
#
# if group_name matches the passed devicegroup,
# then get the corresponding ID
#
if group_name == devicegroup:
group_id = str(data['groups'][i]['id'])
print ('Location: ' + librenms_host + '/devices/group=' + group_id + '\n')
else:
print ('Location: ' + librenms_host + '/devices/' + '\n')
except IndexError:
print ('Location: ' + librenms_host + '/devices/' + '\n')
else:
print ('Location: ' + librenms_host +'\n')
#
# handle all other errors by just forwarding to the LibreNMS host
#
else:
print ('Location: ' + librenms_host +'\n')

48
netbox/netbox-snipeit.php Normal file
View File

@ -0,0 +1,48 @@
<?php
#
# Initialize a snipeit array with token and URL to location API function
#
$snipeit = Array(
'token' => 'Bearer API_TOKEN_GOES_HERE
'accept' => 'application/json',
'content-type' => 'application/json',
'url' => 'https://SNIPEIT_FQDN/api/v1/locations?limit=1&offset=0&search=',
);
#
# Verify if a location parameter is passed as HTTP GET
#
if(isset($_GET['location'])) {
#
# Set CURL options and get data
#
$ch = curl_init($snipeit['url'] . $_GET['location']);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_URL, $snipeit['url'] . $_GET['location']);
curl_setopt($ch, CURLOPT_HTTPHEADER, Array('authorization: ' . $snipeit['token']));
$data = curl_exec($ch);
#
# If CURL returns HTTP status code 200 (OK), then we can
# parse the json data and redirect to Snipe-IT location
#
if(curl_getinfo($ch, CURLINFO_HTTP_CODE) == 200){
#
# use json data as object
#
$object = json_decode($data);
#
# DEBUG to verify output
#
#print_r($object);
#print $object->rows[0]->id;
#
# Do an HTTP redirect to Snipe-IT location by the ID
#
$redirect = 'Location: https://SNIPEIT_FQDN/locations/' . $object->rows[0]->id;
header($redirect);
exit;
}
curl_close($ch);
}
?>

75
netbox/netbox-snipeit.py Normal file
View File

@ -0,0 +1,75 @@
#!/usr/bin/python3
# This file is copyright under the latest version of the EUPL.
# Please see LICENSE file for your rights under this license.
import requests
import cgi
import cgitb
import json
#
# Snipe-IT HOST and API token
#
snipeit_host = 'https://SNIPE-IT_HOST'
token = 'Bearer SNIPE-IT_API_TOKEN'
#
# get form data
#
cgitb.enable()
form = cgi.FieldStorage()
#
# handle devices
#
if "device" in form:
device = form.getvalue('device')
url = snipeit_host + '/api/v1/hardware?limit=1&offset=0&search='
headers = {'authorization': token}
r = requests.get(url + device, headers = headers)
#
# if status code is 200, then redirect to hardware
#
if r.status_code == requests.codes.ok:
#
# Snipe-IT must return something like an ID
# If there is no ID, then just list all hardware
#
try:
data = r.json()
device_id = str(data['rows'][0]['id'])
print ('Location: ' + snipeit_host + '/hardware/' + device_id + '\n')
except IndexError:
print ('Location: ' + snipeit_host + '/hardware/' + '\n')
else:
print ('Location: ' + snipeit_host +'\n')
#
# handle locations
#
elif "location" in form:
location = form.getvalue('location')
url = snipeit_host + '/api/v1/locations?limit=1&offset=0&search='
headers = {'authorization': token}
r = requests.get(url + location, headers = headers)
#
# if status code is 200, then redirect to location
#
if r.status_code == requests.codes.ok:
#
# Snipe-IT must return something like an ID
# If there is no ID, then just list all locations
#
try:
data = r.json()
location_id = str(data['rows'][0]['id'])
print ('Location: ' + snipeit_host + '/locations/' + location_id + '\n')
except IndexError:
print ('Location: ' + snipeit_host + '/locations/' +'\n')
else:
print ('Location: ' + snipeit_host +'\n')
#
# handle all other errors by just forwarding to the Snipe-IT host
#
else:
print ('Location: ' + snipeit_host +'\n')

50
netbox/qrcode-snipeit.py Normal file
View File

@ -0,0 +1,50 @@
#!/usr/bin/python3
# This file is copyright under the latest version of the EUPL.
# Please see LICENSE file for your rights under this license.
import requests
import cgi
import cgitb
import json
#
# Snipe-IT HOST and API token
#
snipeit_host = '[SNIPE_IT_HOST]'
token = 'Bearer [SNIPE_IT_AUTH_TOKEN]'
#
# get form data
#
cgitb.enable()
form = cgi.FieldStorage()
#
# handle devices
#
if "tag" in form:
tag = form.getvalue('tag')
url = snipeit_host + '/api/v1/hardware/bytag/'
headers = {'authorization': token}
r = requests.get(url + tag, headers = headers)
#
# if status code is 200, then redirect to hardware
#
if r.status_code == requests.codes.ok:
#
# Snipe-IT must return something like an ID
# If there is no ID, then just list all hardware
#
try:
data = r.json()
device_id = str(data['id'])
print ('Location: ' + snipeit_host + '/hardware/' + device_id + '\n')
except:
print ('Location: ' + snipeit_host + '/hardware/' + '\n')
else:
print ('Location: ' + snipeit_host +'\n')
#
# handle all other errors by just forwarding to the Snipe-IT host
#
else:
print ('Location: ' + snipeit_host +'\n')