catocli 3.0.0__py3-none-any.whl → 3.0.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of catocli might be problematic. Click here for more details.
- catocli/__init__.py +1 -1
- catocli/parsers/custom/export_sites/__init__.py +4 -0
- catocli/parsers/custom/export_sites/export_sites.py +93 -0
- catocli/parsers/custom/import_sites_to_tf/import_sites_to_tf.py +16 -1
- {catocli-3.0.0.dist-info → catocli-3.0.2.dist-info}/METADATA +1 -1
- {catocli-3.0.0.dist-info → catocli-3.0.2.dist-info}/RECORD +10 -10
- {catocli-3.0.0.dist-info → catocli-3.0.2.dist-info}/WHEEL +0 -0
- {catocli-3.0.0.dist-info → catocli-3.0.2.dist-info}/entry_points.txt +0 -0
- {catocli-3.0.0.dist-info → catocli-3.0.2.dist-info}/licenses/LICENSE +0 -0
- {catocli-3.0.0.dist-info → catocli-3.0.2.dist-info}/top_level.txt +0 -0
catocli/__init__.py
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
__version__ = "3.0.
|
|
1
|
+
__version__ = "3.0.2"
|
|
2
2
|
__cato_host__ = "https://api.catonetworks.com/api/v1/graphql2"
|
|
@@ -18,6 +18,10 @@ def export_sites_parse(subparsers):
|
|
|
18
18
|
socket_sites_parser.add_argument('-f', '--format', dest='export_format', choices=['json', 'csv'], default='json',
|
|
19
19
|
help='Export format: json (default) or csv')
|
|
20
20
|
|
|
21
|
+
# Template generation option
|
|
22
|
+
socket_sites_parser.add_argument('--generate-template', '-gt', dest='generate_template', action='store_true',
|
|
23
|
+
help='Generate template files instead of exporting data (use -f to specify format: csv or json)')
|
|
24
|
+
|
|
21
25
|
# Filename arguments (updated for both formats)
|
|
22
26
|
socket_sites_parser.add_argument('--json-filename', dest='json_filename', help='Override JSON file name (default: socket_sites_{account_id}.json)')
|
|
23
27
|
socket_sites_parser.add_argument('--csv-filename', dest='csv_filename', help='Override CSV file name (default: socket_sites_{account_id}.csv)')
|
|
@@ -4,6 +4,7 @@ import traceback
|
|
|
4
4
|
import sys
|
|
5
5
|
import ipaddress
|
|
6
6
|
import csv
|
|
7
|
+
import shutil
|
|
7
8
|
from datetime import datetime
|
|
8
9
|
from graphql_client.api.call_api import ApiClient, CallApi
|
|
9
10
|
from graphql_client.api_client import ApiException
|
|
@@ -41,10 +42,102 @@ def calculateLocalIp(subnet):
|
|
|
41
42
|
# Invalid subnet format
|
|
42
43
|
return None
|
|
43
44
|
|
|
45
|
+
def generate_template(args):
|
|
46
|
+
"""
|
|
47
|
+
Generate template files from embedded templates directory
|
|
48
|
+
"""
|
|
49
|
+
try:
|
|
50
|
+
# Get the directory of this script to locate templates
|
|
51
|
+
script_dir = os.path.dirname(os.path.abspath(__file__))
|
|
52
|
+
|
|
53
|
+
# Try multiple possible template directory locations
|
|
54
|
+
# 1. Development mode: go up 4 directories
|
|
55
|
+
# 2. Installed package: templates should be in the package root
|
|
56
|
+
possible_template_dirs = [
|
|
57
|
+
os.path.join(script_dir, '..', '..', '..', '..', 'templates'), # Development
|
|
58
|
+
os.path.join(os.path.dirname(script_dir.split('catocli')[0]), 'catocli', 'templates'), # Installed package
|
|
59
|
+
]
|
|
60
|
+
|
|
61
|
+
templates_dir = None
|
|
62
|
+
for potential_dir in possible_template_dirs:
|
|
63
|
+
normalized_dir = os.path.normpath(potential_dir)
|
|
64
|
+
if os.path.exists(normalized_dir):
|
|
65
|
+
templates_dir = normalized_dir
|
|
66
|
+
break
|
|
67
|
+
|
|
68
|
+
if templates_dir is None:
|
|
69
|
+
# Fallback: look for templates directory in catocli package
|
|
70
|
+
import catocli
|
|
71
|
+
catocli_root = os.path.dirname(os.path.abspath(catocli.__file__))
|
|
72
|
+
fallback_templates_dir = os.path.join(catocli_root, 'templates')
|
|
73
|
+
if os.path.exists(fallback_templates_dir):
|
|
74
|
+
templates_dir = fallback_templates_dir
|
|
75
|
+
else:
|
|
76
|
+
raise Exception(f"Templates directory not found. Searched locations: {possible_template_dirs} and {fallback_templates_dir}")
|
|
77
|
+
|
|
78
|
+
# Get the template format from export_format argument (defaults to json)
|
|
79
|
+
template_format = getattr(args, 'export_format', 'json')
|
|
80
|
+
|
|
81
|
+
# Determine output directory
|
|
82
|
+
output_dir = getattr(args, 'output_directory', None)
|
|
83
|
+
if output_dir is None:
|
|
84
|
+
output_dir = '.'
|
|
85
|
+
if not os.path.isabs(output_dir):
|
|
86
|
+
output_dir = os.path.join(os.getcwd(), output_dir)
|
|
87
|
+
|
|
88
|
+
os.makedirs(output_dir, exist_ok=True)
|
|
89
|
+
|
|
90
|
+
copied_files = []
|
|
91
|
+
|
|
92
|
+
if template_format == 'csv':
|
|
93
|
+
# Copy CSV template files
|
|
94
|
+
template_files = ['socket_sites.csv', 'Test_network_ranges.csv']
|
|
95
|
+
for template_file in template_files:
|
|
96
|
+
src_path = os.path.join(templates_dir, template_file)
|
|
97
|
+
dst_path = os.path.join(output_dir, template_file)
|
|
98
|
+
|
|
99
|
+
if os.path.exists(src_path):
|
|
100
|
+
shutil.copy2(src_path, dst_path)
|
|
101
|
+
copied_files.append(dst_path)
|
|
102
|
+
if hasattr(args, 'verbose') and args.verbose:
|
|
103
|
+
print(f"Copied template: {src_path} -> {dst_path}")
|
|
104
|
+
else:
|
|
105
|
+
print(f"Warning: Template file not found: {src_path}")
|
|
106
|
+
|
|
107
|
+
elif template_format == 'json':
|
|
108
|
+
# Copy JSON template file
|
|
109
|
+
template_file = 'socket_sites.json'
|
|
110
|
+
src_path = os.path.join(templates_dir, template_file)
|
|
111
|
+
dst_path = os.path.join(output_dir, template_file)
|
|
112
|
+
|
|
113
|
+
if os.path.exists(src_path):
|
|
114
|
+
shutil.copy2(src_path, dst_path)
|
|
115
|
+
copied_files.append(dst_path)
|
|
116
|
+
if hasattr(args, 'verbose') and args.verbose:
|
|
117
|
+
print(f"Copied template: {src_path} -> {dst_path}")
|
|
118
|
+
else:
|
|
119
|
+
print(f"Warning: Template file not found: {src_path}")
|
|
120
|
+
|
|
121
|
+
if copied_files:
|
|
122
|
+
print(f"Successfully generated {template_format.upper()} template files:")
|
|
123
|
+
for file_path in copied_files:
|
|
124
|
+
print(f" {file_path}")
|
|
125
|
+
return [{"success": True, "template_format": template_format, "copied_files": copied_files}]
|
|
126
|
+
else:
|
|
127
|
+
return [{"success": False, "error": f"No template files found for format: {template_format}"}]
|
|
128
|
+
|
|
129
|
+
except Exception as e:
|
|
130
|
+
print(f"Error generating template: {str(e)}")
|
|
131
|
+
return [{"success": False, "error": str(e)}]
|
|
132
|
+
|
|
44
133
|
def export_socket_sites_dispatcher(args, configuration):
|
|
45
134
|
"""
|
|
46
135
|
Dispatcher function that routes to JSON or CSV export based on format argument
|
|
47
136
|
"""
|
|
137
|
+
# Check if template generation is requested
|
|
138
|
+
if hasattr(args, 'generate_template') and args.generate_template:
|
|
139
|
+
return generate_template(args)
|
|
140
|
+
|
|
48
141
|
export_format = getattr(args, 'export_format', 'json')
|
|
49
142
|
|
|
50
143
|
if export_format == 'csv':
|
|
@@ -1098,9 +1098,13 @@ def load_site_network_ranges_csv(site, ranges_csv_file):
|
|
|
1098
1098
|
if default_interface_index and lan_interface_index == default_interface_index:
|
|
1099
1099
|
is_default_interface = True
|
|
1100
1100
|
|
|
1101
|
+
# Check if this is a LAN_LAG_MEMBER interface (special case)
|
|
1102
|
+
is_lan_lag_member = row.get('lan_interface_dest_type', '').strip() == 'LAN_LAG_MEMBER'
|
|
1103
|
+
|
|
1101
1104
|
# If this row has a LAN interface ID, create/update the interface
|
|
1102
1105
|
# OR if this is a default interface, get details from parent CSV
|
|
1103
|
-
if
|
|
1106
|
+
# OR if this is a LAN_LAG_MEMBER interface
|
|
1107
|
+
if (has_lan_interface_id or is_default_interface or is_lan_lag_member) and lan_interface_index:
|
|
1104
1108
|
|
|
1105
1109
|
# Create or get the interface data
|
|
1106
1110
|
if lan_interface_index not in interfaces:
|
|
@@ -1115,6 +1119,17 @@ def load_site_network_ranges_csv(site, ranges_csv_file):
|
|
|
1115
1119
|
'default_lan': True, # Mark as default interface
|
|
1116
1120
|
'network_ranges': []
|
|
1117
1121
|
}
|
|
1122
|
+
elif is_lan_lag_member:
|
|
1123
|
+
# For LAN_LAG_MEMBER interfaces, they don't have interface_id but need to be tracked for import
|
|
1124
|
+
interfaces[lan_interface_index] = {
|
|
1125
|
+
'id': None, # LAN LAG members don't have interface_id in CSV
|
|
1126
|
+
'name': row.get('lan_interface_name', ''),
|
|
1127
|
+
'index': lan_interface_index,
|
|
1128
|
+
'dest_type': row.get('lan_interface_dest_type', 'LAN_LAG_MEMBER'),
|
|
1129
|
+
'default_lan': False,
|
|
1130
|
+
'network_ranges': [],
|
|
1131
|
+
'is_lag_member': True # Special flag for LAN LAG members
|
|
1132
|
+
}
|
|
1118
1133
|
else:
|
|
1119
1134
|
# For regular interfaces, get details from CSV row
|
|
1120
1135
|
interfaces[lan_interface_index] = {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
catocli/__init__.py,sha256=
|
|
1
|
+
catocli/__init__.py,sha256=2XLOXyrteS38EdDU8Rdapr0HJdmnvOI8FsQ3oo0nJAo,84
|
|
2
2
|
catocli/__main__.py,sha256=6Z0ns_k_kUcz1Qtrn1u7UyUnqB-3e85jM_nppOwFsv4,217
|
|
3
3
|
catocli/clisettings.json,sha256=s0NENqEgRtSzX8eJGASfOygI6cueF6mcPWSxj_oWMV4,964
|
|
4
4
|
catocli/Utils/clidriver.py,sha256=lzVs1nYAiStwQjNxioxktwaKmfOF69Mmp5-9aWwsNOY,15972
|
|
@@ -15,12 +15,12 @@ catocli/parsers/custom/customLib.py,sha256=Nv-agL_ewpe1x6GbwWCRb_Ey-NVW_w9L6qWwE
|
|
|
15
15
|
catocli/parsers/custom/eventsFeedEnhanced.py,sha256=t5vPVWBSl57CO6a3UVRyx4292YaXYVK0MEWH6qH8k_c,10736
|
|
16
16
|
catocli/parsers/custom/export_rules/__init__.py,sha256=vst8auriTCLwy5AT2_ySM2puq3PIg920ZWa5yy03K_8,1813
|
|
17
17
|
catocli/parsers/custom/export_rules/export_rules.py,sha256=gXig4NC29yC5nW48ri-j0FEnaTz_kxKiuLF5y-5fZ_4,15646
|
|
18
|
-
catocli/parsers/custom/export_sites/__init__.py,sha256=
|
|
19
|
-
catocli/parsers/custom/export_sites/export_sites.py,sha256=
|
|
18
|
+
catocli/parsers/custom/export_sites/__init__.py,sha256=WAiaVzSGG8tsfWjl-FcUY2JyhfjE1sA265rtIsbmeVI,2427
|
|
19
|
+
catocli/parsers/custom/export_sites/export_sites.py,sha256=CTGe-xXvs6cLThiyuQUyFKz2bLUkwscM2eMytKFg-Bo,82160
|
|
20
20
|
catocli/parsers/custom/import_rules_to_tf/__init__.py,sha256=jFCFceFv8zDW7nGLZOXkFE6NXAMPYRwKQwTbhSawYdM,3908
|
|
21
21
|
catocli/parsers/custom/import_rules_to_tf/import_rules_to_tf.py,sha256=WlyTDxUtWchu9CDs73ILHDfNXCAh7jFARBEKk5WWhwM,18714
|
|
22
22
|
catocli/parsers/custom/import_sites_to_tf/__init__.py,sha256=1ayoaaKIxWf5JBN62CO9F7-yaP9MqizTBCedqCyEc4k,4339
|
|
23
|
-
catocli/parsers/custom/import_sites_to_tf/import_sites_to_tf.py,sha256=
|
|
23
|
+
catocli/parsers/custom/import_sites_to_tf/import_sites_to_tf.py,sha256=scZ8Pecu6b279jG-72eF4eCw-BWNSHFK7cl9JvBGT0E,78130
|
|
24
24
|
catocli/parsers/custom/query_eventsFeed/__init__.py,sha256=awOFdkByn0ycDjZFYhySd9Z5zJ-vNq2-orX16B6NlYM,4405
|
|
25
25
|
catocli/parsers/custom/scim/__init__.py,sha256=filQvWGXeJ-EppAzEHKJjXY12QPiT69weT6mav9TPXo,10410
|
|
26
26
|
catocli/parsers/custom/scim/scim_client.py,sha256=dkObWVtWh331hoeU4Npx4xRzqAYM51MKxNx01WvVW5o,19560
|
|
@@ -395,7 +395,7 @@ catocli/parsers/query_xdr_stories/README.md,sha256=rRW1pTmVMr9-j21-_MWNlozTTQnhi
|
|
|
395
395
|
catocli/parsers/query_xdr_story/README.md,sha256=Fl2HutndHVobrj73Wh5NlTLq56tvVN3W0iib6BuO-b0,925
|
|
396
396
|
catocli/parsers/raw/README.md,sha256=qvDLcg7U12yqacIQStOPtkqTsTLltJ06SSVmbqvlZhY,739
|
|
397
397
|
catocli/parsers/raw/__init__.py,sha256=fiSzQzNSG3vje-eEXuOcdhuL8pyavkufocOJumjdFXs,1356
|
|
398
|
-
catocli-3.0.
|
|
398
|
+
catocli-3.0.2.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
399
399
|
graphql_client/__init__.py,sha256=2nxD4YsWoOnALXi5cXbmtIN_i0NL_eyDTQRTxs52mkI,315
|
|
400
400
|
graphql_client/api_client.py,sha256=2Rc1Zo1xH9Jnk1AO68kLSofTShkZwSVF-WkVtczfIc4,5786
|
|
401
401
|
graphql_client/api_client_types.py,sha256=dM3zl6FA5SSp6nR6KmLfTL1BKaXX9uPMCZAm4v_FiUs,11569
|
|
@@ -743,8 +743,8 @@ vendor/urllib3/util/timeout.py,sha256=4eT1FVeZZU7h7mYD1Jq2OXNe4fxekdNvhoWUkZusRp
|
|
|
743
743
|
vendor/urllib3/util/url.py,sha256=wHORhp80RAXyTlAIkTqLFzSrkU7J34ZDxX-tN65MBZk,15213
|
|
744
744
|
vendor/urllib3/util/util.py,sha256=j3lbZK1jPyiwD34T8IgJzdWEZVT-4E-0vYIJi9UjeNA,1146
|
|
745
745
|
vendor/urllib3/util/wait.py,sha256=_ph8IrUR3sqPqi0OopQgJUlH4wzkGeM5CiyA7XGGtmI,4423
|
|
746
|
-
catocli-3.0.
|
|
747
|
-
catocli-3.0.
|
|
748
|
-
catocli-3.0.
|
|
749
|
-
catocli-3.0.
|
|
750
|
-
catocli-3.0.
|
|
746
|
+
catocli-3.0.2.dist-info/METADATA,sha256=WBNjBRO067-ugVqLqOws5-bhDiPithFoLabdDzKqwug,1286
|
|
747
|
+
catocli-3.0.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
748
|
+
catocli-3.0.2.dist-info/entry_points.txt,sha256=p4k9Orre6aWcqVrNmBbckmCs39h-1naMxRo2AjWmWZ4,50
|
|
749
|
+
catocli-3.0.2.dist-info/top_level.txt,sha256=F4qSgcjcW5wR9EFrO8Ud06F7ZQGFr04a9qALNQDyVxU,52
|
|
750
|
+
catocli-3.0.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|