transfer github
This commit is contained in:
parent
4f9725daa9
commit
cdd5fab8e4
23
ansible/README.md
Normal file
23
ansible/README.md
Normal 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
|
77
ansible/cisco-asa-firewalls-serial-nums.yaml
Normal file
77
ansible/cisco-asa-firewalls-serial-nums.yaml
Normal 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"
|
21
ansible/collect_mac_address.yaml
Normal file
21
ansible/collect_mac_address.yaml
Normal 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
|
38
ansible/netbox-cisco-asa-firewall-serialnums.yaml
Normal file
38
ansible/netbox-cisco-asa-firewall-serialnums.yaml
Normal 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
|
37
ansible/netbox-cisco-switch-serialnums.yaml
Normal file
37
ansible/netbox-cisco-switch-serialnums.yaml
Normal 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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
15
netbox/README.md
Normal 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
303
netbox/backup2git.py
Normal 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
|
63
netbox/netbox-librenms-graph.py
Normal file
63
netbox/netbox-librenms-graph.py
Normal 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
70
netbox/netbox-librenms.py
Normal 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
48
netbox/netbox-snipeit.php
Normal 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
75
netbox/netbox-snipeit.py
Normal 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
50
netbox/qrcode-snipeit.py
Normal 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')
|
Loading…
Reference in New Issue
Block a user