-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy pathNCM_APIv3_regrades_by_mac.py
More file actions
132 lines (112 loc) · 5.49 KB
/
NCM_APIv3_regrades_by_mac.py
File metadata and controls
132 lines (112 loc) · 5.49 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# This script applies/regrades a subscription to devices by MAC address using the NCM library (pip install -U ncm)
# It reads a CSV file with MAC addresses and subscriptions and applies/regrades subscriptions to the devices in NCM in chunks of 100
# Usage: python NCM_APIv3_regrades_by_mac.py <csv_filename> [token]
# Token can be set via command-line argument, token environment variable, or hardcoded in the script
# CSV file must contain columns for MAC addresses and subscription (example subscription_id: BA-NCADV)
# Column names are automatically detected (case-insensitive):
# MAC address: "mac", "mac address", or "mac_address"
# Subscription ID: "subscription_id", "subscription", or "subscription id"
import csv
import os
import sys
from ncm import ncm
# Get CSV filename from command-line argument
if len(sys.argv) < 2:
print("Error: CSV filename required as command-line argument")
print(f"Usage: {sys.argv[0]} <csv_filename> [token]")
exit(1)
csv_filename = sys.argv[1]
# Get token from command-line argument, environment variable, or use hardcoded value
if len(sys.argv) >= 3:
token = sys.argv[2]
else:
token = os.environ.get("token", "Put Your NCM APIv3 Token Here")
# Possible MAC address column names (case-insensitive)
mac_address_column_names = ["mac", "mac address", "mac_address"]
# Possible subscription_id column names (case-insensitive)
subscription_id_column_names = ["subscription_id", "subscription", "subscription id"]
# Check if token is still placeholder
if token == "Put Your NCM APIv3 Token Here":
print("Error: Please set your NCM APIv3 token either:")
print(" 1. Pass it as a command-line argument: <csv_filename> <token>")
print(" 2. Set token environment variable, or")
print(" 3. Hardcode it in the script")
exit(1)
def chunks(lst, n):
"""Yield successive n-sized chunks from lst."""
for i in range(0, len(lst), n):
yield lst[i:i + n]
# Initialize the NCM client
ncm_client = ncm.NcmClientv3(api_key=token, log_events=True)
# Read MAC addresses and subscription IDs from CSV file
try:
with open(csv_filename, 'r') as file:
csv_reader = csv.DictReader(file)
# Get the actual column names from the CSV
csv_columns = [col.lower() for col in csv_reader.fieldnames]
# Find the MAC address column (case-insensitive match)
mac_address_column = None
for col_name in mac_address_column_names:
if col_name.lower() in csv_columns:
# Find the actual column name (preserving original case)
for original_col in csv_reader.fieldnames:
if original_col.lower() == col_name.lower():
mac_address_column = original_col
break
if mac_address_column:
break
if not mac_address_column:
print(f"Error: Could not find MAC address column. Looking for: {', '.join(mac_address_column_names)}")
print(f"Available columns: {', '.join(csv_reader.fieldnames)}")
exit(1)
print(f"Using MAC address column: '{mac_address_column}'")
# Find the subscription_id column (case-insensitive match)
subscription_id_column = None
for col_name in subscription_id_column_names:
if col_name.lower() in csv_columns:
# Find the actual column name (preserving original case)
for original_col in csv_reader.fieldnames:
if original_col.lower() == col_name.lower():
subscription_id_column = original_col
break
if subscription_id_column:
break
if not subscription_id_column:
print(f"Error: Could not find subscription_id column. Looking for: {', '.join(subscription_id_column_names)}")
print(f"Available columns: {', '.join(csv_reader.fieldnames)}")
exit(1)
print(f"Using subscription_id column: '{subscription_id_column}'")
devices = []
for row in csv_reader:
mac = row[mac_address_column].lower().strip().replace(':', '')
sub_id = row[subscription_id_column].strip()
devices.append({'mac': mac, 'subscription_id': sub_id})
except FileNotFoundError:
print(f"Error: CSV file '{csv_filename}' not found")
exit(1)
except KeyError as e:
print(f"Error: Column '{e}' not found in CSV file")
exit(1)
except Exception as e:
print(f"Error reading CSV file: {e}")
exit(1)
print(f"Found {len(devices)} devices to regrade. Processing in chunks of 100...")
# Group devices by subscription_id for efficient processing
subscription_groups = {}
for device in devices:
sub_id = device['subscription_id']
if sub_id not in subscription_groups:
subscription_groups[sub_id] = []
subscription_groups[sub_id].append(device['mac'])
# Regrade devices in chunks of 100, grouped by subscription_id
if devices:
for subscription_id, mac_addresses in subscription_groups.items():
print(f"Processing {len(mac_addresses)} devices with subscription_id: {subscription_id}")
for chunk in chunks(mac_addresses, 100):
try:
result = ncm_client.regrade(subscription_id, chunk)
print(f"Chunk regrade result for {subscription_id}: {result}")
except Exception as e:
print(f"Error processing chunk for {subscription_id}: {e}")
else:
print("No devices found in CSV file")