Skip to content

Commit

Permalink
Merge pull request #6 from Tes3awy/refactor
Browse files Browse the repository at this point in the history
Refactor
  • Loading branch information
Tes3awy authored Jul 24, 2021
2 parents 32b8dbe + f423fa2 commit a0906be
Show file tree
Hide file tree
Showing 10 changed files with 138 additions and 187 deletions.
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,6 @@ repos:
args: ["--profile", "black"]
name: isort (python)
- repo: https://github.com/asottile/pyupgrade
rev: v2.21.2
rev: v2.22.0
hooks:
- id: pyupgrade
28 changes: 10 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,40 +76,35 @@ $ pip install -r requirements.txt --user
path_to\subnetting> python main.py
```

**macOS or Linux**
**macOS or Unix**

```bash
$ python3 main.py
```

You will be prompted to enter the name of the CSV file containing input subnets, the gateway IP address, a name for the Excel file to be created, and the name of the sheet within the Excel file. _(All inputs have default values)_.
You will be prompted to enter the name of the CSV file containing input subnets, the gateway, a name for the Excel file to be created. _(All inputs have default values)_.

> A `subnets.csv` file can be found in the repo. This file is an entry point to get started using this program. It's prepopulated with three different subnets. _(Class A, B, and C)_.
```bash
- CSV file w/ extension? [Defaults to subnets.csv]:
- The gateway, first or last IP Address? [0/1] [Defaults to 0]:
- Excel file w/o extension? [Defaults to IP-Schema]: Test-Schema
- Worksheet name? [Defaults to IP Schema Worksheet]: Test Worksheet
- CSV file [subnets.csv]:
- The gateway, first or last IP Address [0/1] [0]:
- Excel file to create [New-Schema.xlsx]:
```

> - Abbreviations: <br /> - **w/: With** <br /> - **w/o: Without**
Voila :sparkles: You have an Excel file that includes all required data about each subnet.

```bash
Please check Test-Schema_<TODAYS_DATE>.xlsx in current working directory.
Please check New-Schema_<TODAYS_DATE>.xlsx in current working directory.
```

> **Default behaviors:**
> 1. CIDR notation with no prefix length will be handled as /32. <br /> - For example, if you enter `10.0.0.0` without a prefix length in the CSV file, the script will handle it like `10.0.0.0/32`.
> 1. CIDR notation with no prefix length will be handled as /32. <br /> - For example, if you enter `10.0.0.1` without a prefix length in the CSV file, the script will handle it like `10.0.0.1/32`.
> 2. The header line **`Subnets in CIDR Notation`** within the `subnets.csv` file is automatically skipped. So, there is no need to manually remove it.
> 3. Gateway input accepts 0 or 1 **ONLY** [Defaults to 0]. 0 picks the first IP address of the subnet, while 1 picks the last IP address.
> 4. Microsoft Excel does not allow worksheet name longer than 31 characters. Worksheet names longer than 31 chars will be truncated.
> 3. The gateway input accepts 0 or 1 **ONLY** [Defaults to 0]. 0 picks the first IP address of the subnet, while 1 picks the last IP address.
---

Expand All @@ -120,10 +115,6 @@ Finally, if you have a L3 switch and you want to create [SVI interfaces](https:/
```bash
$ python parse_excel.py --file <EXCEL_FILE_NAME>.xlsx
```
**OR**
```
$ python parse_excel.py -f <EXCEL_FILE_NAME>.xlsx
```

This Python script will generate a configuration file that includes all VLANs and their SVI interfaces.

Expand All @@ -135,14 +126,15 @@ This Python script will generate a configuration file that includes all VLANs an

**Terminal**
![Python CLI](assets/subnetting-cli.png)
_Elapsed time is about 9 seconds in here because a CIDR notation like 10.0.0.0/8 is a little bit extensive to process._

**CSV File (Input File)**
![CSV File](assets/subnets-csv.png)

**Excel File (Output File)**
![Excel Preview](assets/preview.png)

**python parse_excel.py --file <EXCEL_FILE_NAME>.xlsx**
**python parse_excel.py -f <EXCEL_FILE_NAME>.xlsx**
![SVI CLI](assets/svi.png)

**SVI Template**
Expand Down
Binary file modified assets/subnetting-cli.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
50 changes: 24 additions & 26 deletions export_subnets.py
Original file line number Diff line number Diff line change
@@ -1,34 +1,38 @@
#!usr/bin/env python3

from datetime import date
from typing import AnyStr, Dict, List
from typing import AnyStr, Dict, List, Optional

from termcolor import colored, cprint
from xlsxwriter import Workbook


def export_subnets(
subnets: List[Dict],
workbook_name: AnyStr = "IP-Schema",
worksheet_name: AnyStr = "IP Schema Worksheet",
workbook_name: Optional[AnyStr] = "New-Schema.xlsx",
):
"""Export an Excel file of entered subnets
Args:
subnets (List[Dict]): Processed subnets
workbook_name (AnyStr, optional): Name of the Excel file. Defaults to "IP-Schema".
worksheet_name (AnyStr, optional): Name of the sheet within the Excel file. Defaults to "IP Schema Worksheet".
Raises:
SystemExit: TypeError
"""Exports an Excel file of subnetting data
Parameters
----------
subnets : List[Dict]
List of subnets went througth subnetting
workbook_name : Optional[AnyStr], optional
Name of Workbook to create, by default "New-Schema.xlsx"
Raises
------
SystemExit
TypeError, KeyError
"""

excel_fname = f"{workbook_name}_{date.today()}.xlsx"
wb_name, ext = workbook_name.split(".")
excel_fname = f"{wb_name}_{date.today()}.{ext}"

# Create an Excel file
with Workbook(filename=excel_fname) as workbook:
# Create a sheet within the Excel file
worksheet = workbook.add_worksheet(name=worksheet_name)
worksheet = workbook.add_worksheet(name="Subnetting Results")
# Filters
worksheet.autofilter("A1:L1")
# Freeze top row and 2 most left columns
Expand All @@ -51,7 +55,7 @@ def export_subnets(
}

# Header line format
header_line_frmt = workbook.add_format(
h_frmt = workbook.add_format(
properties={
"bold": True,
"border": True,
Expand All @@ -62,15 +66,11 @@ def export_subnets(

# Create a header line row
for cell, value in header_line.items():
worksheet.write_string(cell, value, cell_format=header_line_frmt)
worksheet.write_string(cell, value, cell_format=h_frmt)

# Generic cell format
c_frmt = workbook.add_format(
properties={
"border": True,
"align": "center",
"valign": "vcenter",
}
properties={"border": True, "align": "center", "valign": "vcenter"}
)

# Format cell containing number
Expand Down Expand Up @@ -106,8 +106,6 @@ def export_subnets(
# Jump to next row
row += 1

except TypeError as e:
raise SystemExit(colored(f"export_subnets.py: {e}", "red"))
except KeyError as e:
raise SystemExit(colored(f"export_subnets.py: {e}", "red"))
cprint(f"\nPlease check {excel_fname} in the PWD.\n", "green")
except (TypeError, KeyError) as e:
raise SystemExit(colored(text=f"export_subnets.py: {e}", color="red"))
cprint(text=f"\nPlease check {excel_fname} in the PWD.\n", color="green")
53 changes: 19 additions & 34 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
#!usr/bin/env python3

import time
from getpass import getuser

from colorama import init
from termcolor import colored
from termcolor import colored, cprint

from export_subnets import export_subnets
from read_subnets import read_subnets
Expand All @@ -15,59 +16,43 @@
def main():
try:
# CSV file
input_subnets = (
input(f"\n- CSV file w/ extension? [Defaults to subnets.csv]: ")
or "subnets.csv"
)
if ".csv" not in input_subnets:
raise SystemExit(
colored("Sorry! The input file MUST include .csv extension", "red")
)
input_csv = input(f"\n- CSV file [subnets.csv]: ") or "subnets.csv"
gateway = int(
input("- The gateway, first or last IP Address? [0/1] [Defaults to 0]: ")
or "0"
input("- The gateway, first or last IP Address [0/1] [0]: ") or "0"
)
if gateway not in (0, 1):
raise SystemExit(
colored(
"0 and 1 are the only allowed values! 0: First IP, 1: Last IP",
"red",
)
colored(text="0 and 1 are the only allowed values!", color="red")
)
# Excel file name
workbook_name = (
input("- Excel file w/o extension? [Defaults to IP-Schema]: ")
or "IP-Schema"
)
if workbook_name.endswith(".xlsx"):
raise SystemExit(colored("Oops! Please remove the .xlsx extension", "red"))
# Excel sheet name
worksheet_name = (
input("- Worksheet name? [Defaults to IP Schema Worksheet]: ")
or "IP Schema Worksheet"
input("- Excel file to create [New-Schema.xlsx]: ") or "New-Schema.xlsx"
)

start = time.perf_counter()

# Read CSV file
subnets = read_subnets(file_path=input_subnets)
subnets = read_subnets(file_path=input_csv)

# Do Subnetting
network_subnets = subnetting(input_subnets=subnets, gateway=gateway)

# Export subnetting results to an Excel file
export_subnets(
subnets=network_subnets,
workbook_name=workbook_name,
worksheet_name=worksheet_name[:31],
)
export_subnets(subnets=network_subnets, workbook_name=workbook_name)

end = time.perf_counter()

delta = round(end - start, 2)
cprint(text=f"Finished in {delta} second(s)", on_color="on_blue")

except FileNotFoundError:
raise SystemExit(
colored(f"main.py: {input_subnets} file does not exist!", "red")
colored(text=f"`{input_csv}` file does not exist!", color="red")
)
except KeyboardInterrupt:
raise SystemExit(colored(f"\nProcess interrupted by {getuser()}", "yellow"))

print("Done")
raise SystemExit(
colored(text=f"Process interrupted by {getuser()}", color="yellow")
)


if __name__ == "__main__":
Expand Down
16 changes: 4 additions & 12 deletions parse_excel.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#!usr/bin/env python3

import os
from argparse import ArgumentParser

from colorama import init
Expand Down Expand Up @@ -32,14 +31,7 @@

args = parser.parse_args()

if not args.file.endswith(".xlsx"):
raise SystemExit(colored("\nInvalid input file. The file MUST be a .xlsx", "red"))
if not os.path.isfile(args.file):
raise SystemExit(colored(f"{args.file} does not exist!", "red"))

svi_generator(args.file) # Execute the svi_generator

cprint(
f'\nCreated {args.file.replace(".xlsx", "")}-svi-template.txt successfully.',
"green",
)
try:
svi_generator(excel_file=args.file)
except (FileNotFoundError, PermissionError) as e:
raise SystemExit(colored(text=e, color="red"))
28 changes: 12 additions & 16 deletions read_subnets.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,25 @@
#!usr/bin/env python3

import csv
from typing import AnyStr, List
from typing import AnyStr, Dict, List


def read_subnets(file_path: AnyStr = "subnets.csv") -> List[List]:
def read_subnets(file_path: AnyStr = "subnets.csv") -> List[Dict[AnyStr, AnyStr]]:
"""Reads CSV subnets file
Args:
file_path (AnyStr, optional): Path to subnets CSV file. Defaults to "subnets.csv".
Parameters
----------
file_path : AnyStr, optional
Name of a CSV file, by default "subnets.csv"
Returns:
List[List]: Subnets in CIDR notation representation
Returns
-------
List[Dict[AnyStr, AnyStr]]
Subnets in CIDR Notation
"""

# Define an empty list to hold all subnets
subnets = []

# Read subnets CSV file
with open(file=file_path, mode="r") as csvfile:
next(csvfile) # Skip header line
csv_data = csv.reader(
csvfile, delimiter="\n", dialect="excel", doublequote=True
)
for subnet in csv_data:
subnets.append(subnet[0])

return subnets
csv_data = csv.DictReader(f=csvfile, fieldnames={"cidr"})
return [cidr for cidr in csv_data]
Loading

0 comments on commit a0906be

Please sign in to comment.