Skip to content

Commit 4fca4a7

Browse files
authored
Cleanup (#75)
* - Added exception handler function with easy map dictionary. - Added extra default values for ENV vars. - Moved parser args to Settings for global use. - Started implementing new exception handler - Moved git functions to gitcmd.py. - Implemented exception handler for git functions. - Removed extra imports where no longer needed. * Added how to fix ssl error in case it pops up * - Removed circular import of settings.py and gitcmd.py - Added exception_handler.py to handle exceptions (refer to above) - Made GitCMD a class with init and run methods - Removed git completely from nb-dt-import.py * Fixed missing arg * made exception handler a class to prevent circular import
1 parent 1345a9d commit 4fca4a7

File tree

4 files changed

+106
-53
lines changed

4 files changed

+106
-53
lines changed

exception_handler.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from sys import exit as system_exit
2+
3+
4+
5+
6+
7+
class ExceptionHandler:
8+
def __new__(cls, *args, **kwargs):
9+
return super().__new__(cls)
10+
11+
def __init__(self, args):
12+
self.args = args
13+
14+
def exception(self, exception_type, exception, stack_trace=None):
15+
exception_dict = {
16+
"EnvironmentError": f'Environment variable "{exception}" is not set.',
17+
"SSLError": f'SSL verification failed. IGNORE_SSL_ERRORS is {exception}. Set IGNORE_SSL_ERRORS to True if you want to ignore this error. EXITING.',
18+
"GitCommandError": f'The repo "{exception}" is not a valid git repo.',
19+
"GitInvalidRepositoryError": f'The repo "{exception}" is not a valid git repo.',
20+
"Exception": f'An unknown error occurred: "{exception}"'
21+
}
22+
23+
if self.args.verbose and stack_trace:
24+
print(stack_trace)
25+
print(exception_dict[exception_type])
26+
system_exit(1)
27+

gitcmd.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
from git import Repo, exc
2+
from sys import exit as system_exit
3+
import settings
4+
import os
5+
6+
class GitCMD:
7+
def __new__(cls, *args, **kwargs):
8+
return super().__new__(cls)
9+
10+
def __init__(self, args, repo_path):
11+
self.url = args.url
12+
self.repo_path = repo_path
13+
self.branch = args.branch
14+
self.repo = Repo()
15+
self.cwd = os.getcwd()
16+
17+
if os.path.isdir(self.repo_path):
18+
self.pull_repo()
19+
else:
20+
self.clone_repo()
21+
22+
23+
def pull_repo(self):
24+
try:
25+
print("Package devicetype-library is already installed, "
26+
+ f"updating {os.path.join(self.cwd, self.repo_path)}")
27+
self.repo = Repo(self.repo_path)
28+
if not self.repo.remotes.origin.url.endswith('.git'):
29+
settings.handle.exception("GitInvalidRepositoryError", self.repo.remotes.origin.url, f"Origin URL {self.repo.remotes.origin.url} does not end with .git")
30+
self.repo.remotes.origin.pull()
31+
self.repo.git.checkout(self.branch)
32+
print(f"Pulled Repo {self.repo.remotes.origin.url}")
33+
except exc.GitCommandError as git_error:
34+
settings.handle.exception("GitCommandError", self.repo.remotes.origin.url, git_error)
35+
except Exception as git_error:
36+
settings.handle.exception("Exception", 'Git Repository Error', git_error)
37+
38+
def clone_repo(self):
39+
try:
40+
self.repo = Repo.clone_from(self.url, os.path.join(self.cwd, self.repo_path), branch=self.branch)
41+
print(f"Package Installed {self.repo.remotes.origin.url}")
42+
except exc.GitCommandError as git_error:
43+
settings.handle.exception("GitCommandError", self.url, git_error)
44+
except Exception as git_error:
45+
settings.handle.exception("Exception", 'Git Repository Error', git_error)
46+

nb-dt-import.py

Lines changed: 5 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
11
#!/usr/bin/env python3
2-
from git import Repo, exc, RemoteProgress
32
from collections import Counter
43
from datetime import datetime
54
import yaml
65
import pynetbox
76
import glob
8-
import argparse
97
import os
10-
import settings
11-
import sys
128
import re
139
import requests
1410

11+
import settings
1512

1613
counter = Counter(
1714
added=0,
@@ -44,15 +41,7 @@ def determine_features(nb):
4441
if nb_ver[0] > 3 or (nb_ver[0] == 3 and nb_ver[1] >= 2):
4542
settings.NETBOX_FEATURES['modules'] = True
4643

47-
def update_package(path: str, branch: str):
48-
try:
49-
repo = Repo(path)
50-
if repo.remotes.origin.url.endswith('.git'):
51-
repo.remotes.origin.pull()
52-
repo.git.checkout(branch)
53-
print(f"Pulled Repo {repo.remotes.origin.url}")
54-
except exc.InvalidGitRepositoryError:
55-
pass
44+
5645

5746

5847
def slugFormat(name):
@@ -769,54 +758,22 @@ def main():
769758

770759
cwd = os.getcwd()
771760
startTime = datetime.now()
772-
773-
VENDORS = settings.VENDORS
774-
REPO_URL = settings.REPO_URL
775-
776-
SLUGS = settings.SLUGS
777-
REPO_BRANCH = settings.REPO_BRANCH
778-
779-
parser = argparse.ArgumentParser(description='Import Netbox Device Types')
780-
parser.add_argument('--vendors', nargs='+', default=VENDORS,
781-
help="List of vendors to import eg. apc cisco")
782-
parser.add_argument('--url', '--git', default=REPO_URL,
783-
help="Git URL with valid Device Type YAML files")
784-
parser.add_argument('--slugs', nargs='+', default=SLUGS,
785-
help="List of device-type slugs to import eg. ap4431 ws-c3850-24t-l")
786-
parser.add_argument('--branch', default=REPO_BRANCH,
787-
help="Git branch to use from repo")
788-
parser.add_argument('--verbose', action='store_true',
789-
help="Print verbose output")
790-
args = parser.parse_args()
761+
args = settings.args
791762

792763
nbUrl = settings.NETBOX_URL
793764
nbToken = settings.NETBOX_TOKEN
794765
nb = pynetbox.api(nbUrl, token=nbToken)
795766

796767
try:
797768
determine_features(nb)
798-
except requests.exceptions.SSLError as e:
799-
if args.verbose:
800-
print(e)
769+
except requests.exceptions.SSLError as ssl_exception:
801770
if not settings.IGNORE_SSL_ERRORS:
802-
print("IGNORE_SSL_ERRORS is False. SSL verification failed, exiting.")
803-
sys.exit(1)
771+
settings.handle.exception("SSLError", settings.IGNORE_SSL_ERRORS, ssl_exception)
804772
print("IGNORE_SSL_ERRORS is True, catching exception and disabling SSL verification.")
805773
requests.packages.urllib3.disable_warnings()
806774
nb.http_session.verify = False
807775
determine_features(nb)
808776

809-
try:
810-
if os.path.isdir('./repo'):
811-
print(f"Package devicetype-library is already installed, "
812-
+ f"updating {os.path.join(cwd, 'repo')}")
813-
update_package('./repo', branch=args.branch)
814-
else:
815-
repo = Repo.clone_from(args.url, os.path.join(cwd, 'repo'), branch=args.branch)
816-
print(f"Package Installed {repo.remotes.origin.url}")
817-
except exc.GitCommandError as error:
818-
print("Couldn't clone {} ({})".format(args.url, error))
819-
820777
if not args.vendors:
821778
print("No Vendors Specified, Gathering All Device-Types")
822779
files, vendors = getFiles()

settings.py

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,18 @@
1+
from argparse import ArgumentParser
2+
from sys import exit as system_exit
13
import os
4+
from exception_handler import ExceptionHandler
5+
from gitcmd import GitCMD
26
from dotenv import load_dotenv
37
load_dotenv()
48

5-
REPO_URL = os.getenv("REPO_URL")
6-
REPO_BRANCH = os.getenv("REPO_BRANCH", "master")
9+
REPO_URL = os.getenv("REPO_URL",
10+
default="https://github.com/netbox-community/devicetype-library.git")
11+
REPO_BRANCH = os.getenv("REPO_BRANCH", default="master")
712
NETBOX_URL = os.getenv("NETBOX_URL")
813
NETBOX_TOKEN = os.getenv("NETBOX_TOKEN")
9-
IGNORE_SSL_ERRORS = (os.getenv("IGNORE_SSL_ERRORS", "False") == "True")
14+
IGNORE_SSL_ERRORS = (os.getenv("IGNORE_SSL_ERRORS", default="False") == "True")
15+
REPO_PATH = "./repo"
1016

1117
# optionally load vendors through a comma separated list as env var
1218
VENDORS = list(filter(None, os.getenv("VENDORS", "").split(",")))
@@ -18,8 +24,25 @@
1824
'modules': False,
1925
}
2026

21-
MANDATORY_ENV_VARS = ["REPO_URL", "NETBOX_URL", "NETBOX_TOKEN"]
27+
parser = ArgumentParser(description='Import Netbox Device Types')
28+
parser.add_argument('--vendors', nargs='+', default=VENDORS,
29+
help="List of vendors to import eg. apc cisco")
30+
parser.add_argument('--url', '--git', default=REPO_URL,
31+
help="Git URL with valid Device Type YAML files")
32+
parser.add_argument('--slugs', nargs='+', default=SLUGS,
33+
help="List of device-type slugs to import eg. ap4431 ws-c3850-24t-l")
34+
parser.add_argument('--branch', default=REPO_BRANCH,
35+
help="Git branch to use from repo")
36+
parser.add_argument('--verbose', action='store_true', default=False,
37+
help="Print verbose output")
38+
39+
args = parser.parse_args()
2240

41+
handle = ExceptionHandler(args)
42+
# Evaluate environment variables and exit if one of the mandatory ones are not set
43+
MANDATORY_ENV_VARS = ["REPO_URL", "NETBOX_URL", "NETBOX_TOKEN"]
2344
for var in MANDATORY_ENV_VARS:
2445
if var not in os.environ:
25-
raise EnvironmentError("Failed because {} is not set.".format(var))
46+
handle.exception("EnvironmentError", var, f'Environment variable "{var}" is not set.\n\nMANDATORY_ENV_VARS: {str(MANDATORY_ENV_VARS)}.\n\nCURRENT_ENV_VARS: {str(os.environ)}')
47+
48+
git_repo = GitCMD(args, REPO_PATH)

0 commit comments

Comments
 (0)