Tools for printer discovery and monitoring: - snmp_scanner.py: SNMP-based printer discovery - generate_printer_templates.py: Generate Zabbix templates - analyze_supplies.py: Analyze printer supply levels - extract_summary.py: Extract printer data summaries Includes Zabbix templates for: - HP Color/Mono printers - HP DesignJet T1700 - Xerox Color/Mono/Enterprise printers 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
148 lines
4.7 KiB
Python
148 lines
4.7 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Map each printer IP to the correct Zabbix template
|
|
"""
|
|
|
|
import os
|
|
|
|
MODEL_OID = "1.3.6.1.2.1.25.3.2.1.3.1"
|
|
|
|
def parse_csv(filepath):
|
|
"""Parse printer SNMP CSV file"""
|
|
data = {}
|
|
try:
|
|
with open(filepath, 'r', encoding='utf-8', errors='ignore') as f:
|
|
for line in f:
|
|
parts = line.strip().split(',', 2)
|
|
if len(parts) >= 2:
|
|
oid = parts[0]
|
|
value = parts[1].strip('"')
|
|
data[oid] = value
|
|
except Exception as e:
|
|
print(f"Error reading {filepath}: {e}")
|
|
return data
|
|
|
|
def extract_ip(filename):
|
|
"""Extract IP from filename like printer-10-80-92-20.printer.geaerospace.net.csv"""
|
|
# Remove .csv and domain
|
|
name = filename.replace('.printer.geaerospace.net.csv', '')
|
|
# Remove printer- prefix
|
|
name = name.replace('printer-', '')
|
|
# Convert dashes to dots
|
|
return name.replace('-', '.')
|
|
|
|
def determine_template(model):
|
|
"""Determine which template to use based on model"""
|
|
model_lower = model.lower()
|
|
|
|
# Xerox Enterprise (EC8036, AltaLink)
|
|
if 'xerox ec' in model_lower or 'xerox altalink' in model_lower:
|
|
return "xerox_enterprise", "Xerox Enterprise - Color"
|
|
|
|
# Xerox VersaLink Color
|
|
if 'xerox versalink c' in model_lower:
|
|
return "xerox_color", "Xerox VersaLink - Color"
|
|
|
|
# Xerox VersaLink Mono
|
|
if 'xerox versalink b' in model_lower:
|
|
return "xerox_mono", "Xerox VersaLink - Monochrome"
|
|
|
|
# HP Color
|
|
if 'hp color laserjet' in model_lower or 'color laserjet' in model_lower:
|
|
return "hp_color", "HP LaserJet - Color"
|
|
|
|
# HP Mono (includes DesignJet for now - they use different indices but similar structure)
|
|
if 'hp laserjet' in model_lower or 'hp designjet' in model_lower or 'laserjet' in model_lower:
|
|
return "hp_mono", "HP LaserJet - Monochrome"
|
|
|
|
return "unknown", "UNKNOWN - Manual Assignment Required"
|
|
|
|
def main():
|
|
output_dir = '/home/camp/output'
|
|
|
|
# Collect all printers
|
|
printers = []
|
|
|
|
for filename in sorted(os.listdir(output_dir)):
|
|
if not filename.endswith('.csv'):
|
|
continue
|
|
|
|
filepath = os.path.join(output_dir, filename)
|
|
data = parse_csv(filepath)
|
|
model = data.get(MODEL_OID, "Unknown")
|
|
ip = extract_ip(filename)
|
|
|
|
template_key, template_name = determine_template(model)
|
|
|
|
printers.append({
|
|
'ip': ip,
|
|
'filename': filename,
|
|
'model': model,
|
|
'template_key': template_key,
|
|
'template_name': template_name
|
|
})
|
|
|
|
# Group by template
|
|
by_template = {}
|
|
for p in printers:
|
|
key = p['template_key']
|
|
if key not in by_template:
|
|
by_template[key] = []
|
|
by_template[key].append(p)
|
|
|
|
# Print summary
|
|
print("=" * 120)
|
|
print("PRINTER TO TEMPLATE MAPPING")
|
|
print("=" * 120)
|
|
print()
|
|
|
|
# Print by template type
|
|
for template_key in ['hp_mono', 'hp_color', 'xerox_color', 'xerox_mono', 'unknown']:
|
|
if template_key not in by_template:
|
|
continue
|
|
|
|
printers_list = by_template[template_key]
|
|
template_name = printers_list[0]['template_name']
|
|
|
|
print(f"\n{'='*120}")
|
|
print(f"TEMPLATE: {template_name}")
|
|
print(f"File: zabbix_template_{template_key}.yaml / .json")
|
|
print(f"Count: {len(printers_list)} printers")
|
|
print(f"{'='*120}")
|
|
print(f"{'IP Address':<18} {'Hostname':<45} {'Model':<50}")
|
|
print("-" * 120)
|
|
|
|
for p in sorted(printers_list, key=lambda x: x['ip']):
|
|
hostname = p['filename'].replace('.csv', '').replace('printer-', '')
|
|
print(f"{p['ip']:<18} {hostname:<45} {p['model'][:48]:<50}")
|
|
|
|
# Create importable CSV for Zabbix bulk operations
|
|
print("\n" + "=" * 120)
|
|
print("ZABBIX BULK IMPORT FORMAT")
|
|
print("=" * 120)
|
|
print("\nCopy this to use with Zabbix CSV import or manual configuration:\n")
|
|
print(f"{'IP Address':<18} {'Template':<35} {'SNMP Community':<20} {'Model'}")
|
|
print("-" * 120)
|
|
|
|
for p in sorted(printers, key=lambda x: x['ip']):
|
|
print(f"{p['ip']:<18} {p['template_name']:<35} WestJeff2025{' '*8} {p['model'][:40]}")
|
|
|
|
# Create a quick reference table
|
|
print("\n" + "=" * 120)
|
|
print("QUICK REFERENCE - IP TO TEMPLATE")
|
|
print("=" * 120)
|
|
print()
|
|
|
|
for template_key in ['hp_mono', 'hp_color', 'xerox_color', 'xerox_mono']:
|
|
if template_key not in by_template:
|
|
continue
|
|
|
|
template_file = f"zabbix_template_{template_key}.yaml"
|
|
ips = [p['ip'] for p in sorted(by_template[template_key], key=lambda x: x['ip'])]
|
|
|
|
print(f"\n{template_file}:")
|
|
print(" IPs: " + ", ".join(ips))
|
|
|
|
if __name__ == "__main__":
|
|
main()
|