* - 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
This commit is contained in:
Daniel W. Anner 2023-03-03 16:03:17 -05:00 committed by GitHub
parent 1345a9d89e
commit 4fca4a7fb4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 106 additions and 53 deletions

27
exception_handler.py Normal file
View File

@ -0,0 +1,27 @@
from sys import exit as system_exit
class ExceptionHandler:
def __new__(cls, *args, **kwargs):
return super().__new__(cls)
def __init__(self, args):
self.args = args
def exception(self, exception_type, exception, stack_trace=None):
exception_dict = {
"EnvironmentError": f'Environment variable "{exception}" is not set.',
"SSLError": f'SSL verification failed. IGNORE_SSL_ERRORS is {exception}. Set IGNORE_SSL_ERRORS to True if you want to ignore this error. EXITING.',
"GitCommandError": f'The repo "{exception}" is not a valid git repo.',
"GitInvalidRepositoryError": f'The repo "{exception}" is not a valid git repo.',
"Exception": f'An unknown error occurred: "{exception}"'
}
if self.args.verbose and stack_trace:
print(stack_trace)
print(exception_dict[exception_type])
system_exit(1)

46
gitcmd.py Normal file
View File

@ -0,0 +1,46 @@
from git import Repo, exc
from sys import exit as system_exit
import settings
import os
class GitCMD:
def __new__(cls, *args, **kwargs):
return super().__new__(cls)
def __init__(self, args, repo_path):
self.url = args.url
self.repo_path = repo_path
self.branch = args.branch
self.repo = Repo()
self.cwd = os.getcwd()
if os.path.isdir(self.repo_path):
self.pull_repo()
else:
self.clone_repo()
def pull_repo(self):
try:
print("Package devicetype-library is already installed, "
+ f"updating {os.path.join(self.cwd, self.repo_path)}")
self.repo = Repo(self.repo_path)
if not self.repo.remotes.origin.url.endswith('.git'):
settings.handle.exception("GitInvalidRepositoryError", self.repo.remotes.origin.url, f"Origin URL {self.repo.remotes.origin.url} does not end with .git")
self.repo.remotes.origin.pull()
self.repo.git.checkout(self.branch)
print(f"Pulled Repo {self.repo.remotes.origin.url}")
except exc.GitCommandError as git_error:
settings.handle.exception("GitCommandError", self.repo.remotes.origin.url, git_error)
except Exception as git_error:
settings.handle.exception("Exception", 'Git Repository Error', git_error)
def clone_repo(self):
try:
self.repo = Repo.clone_from(self.url, os.path.join(self.cwd, self.repo_path), branch=self.branch)
print(f"Package Installed {self.repo.remotes.origin.url}")
except exc.GitCommandError as git_error:
settings.handle.exception("GitCommandError", self.url, git_error)
except Exception as git_error:
settings.handle.exception("Exception", 'Git Repository Error', git_error)

View File

@ -1,17 +1,14 @@
#!/usr/bin/env python3
from git import Repo, exc, RemoteProgress
from collections import Counter
from datetime import datetime
import yaml
import pynetbox
import glob
import argparse
import os
import settings
import sys
import re
import requests
import settings
counter = Counter(
added=0,
@ -44,15 +41,7 @@ def determine_features(nb):
if nb_ver[0] > 3 or (nb_ver[0] == 3 and nb_ver[1] >= 2):
settings.NETBOX_FEATURES['modules'] = True
def update_package(path: str, branch: str):
try:
repo = Repo(path)
if repo.remotes.origin.url.endswith('.git'):
repo.remotes.origin.pull()
repo.git.checkout(branch)
print(f"Pulled Repo {repo.remotes.origin.url}")
except exc.InvalidGitRepositoryError:
pass
def slugFormat(name):
@ -769,25 +758,7 @@ def main():
cwd = os.getcwd()
startTime = datetime.now()
VENDORS = settings.VENDORS
REPO_URL = settings.REPO_URL
SLUGS = settings.SLUGS
REPO_BRANCH = settings.REPO_BRANCH
parser = argparse.ArgumentParser(description='Import Netbox Device Types')
parser.add_argument('--vendors', nargs='+', default=VENDORS,
help="List of vendors to import eg. apc cisco")
parser.add_argument('--url', '--git', default=REPO_URL,
help="Git URL with valid Device Type YAML files")
parser.add_argument('--slugs', nargs='+', default=SLUGS,
help="List of device-type slugs to import eg. ap4431 ws-c3850-24t-l")
parser.add_argument('--branch', default=REPO_BRANCH,
help="Git branch to use from repo")
parser.add_argument('--verbose', action='store_true',
help="Print verbose output")
args = parser.parse_args()
args = settings.args
nbUrl = settings.NETBOX_URL
nbToken = settings.NETBOX_TOKEN
@ -795,28 +766,14 @@ def main():
try:
determine_features(nb)
except requests.exceptions.SSLError as e:
if args.verbose:
print(e)
except requests.exceptions.SSLError as ssl_exception:
if not settings.IGNORE_SSL_ERRORS:
print("IGNORE_SSL_ERRORS is False. SSL verification failed, exiting.")
sys.exit(1)
settings.handle.exception("SSLError", settings.IGNORE_SSL_ERRORS, ssl_exception)
print("IGNORE_SSL_ERRORS is True, catching exception and disabling SSL verification.")
requests.packages.urllib3.disable_warnings()
nb.http_session.verify = False
determine_features(nb)
try:
if os.path.isdir('./repo'):
print(f"Package devicetype-library is already installed, "
+ f"updating {os.path.join(cwd, 'repo')}")
update_package('./repo', branch=args.branch)
else:
repo = Repo.clone_from(args.url, os.path.join(cwd, 'repo'), branch=args.branch)
print(f"Package Installed {repo.remotes.origin.url}")
except exc.GitCommandError as error:
print("Couldn't clone {} ({})".format(args.url, error))
if not args.vendors:
print("No Vendors Specified, Gathering All Device-Types")
files, vendors = getFiles()

View File

@ -1,12 +1,18 @@
from argparse import ArgumentParser
from sys import exit as system_exit
import os
from exception_handler import ExceptionHandler
from gitcmd import GitCMD
from dotenv import load_dotenv
load_dotenv()
REPO_URL = os.getenv("REPO_URL")
REPO_BRANCH = os.getenv("REPO_BRANCH", "master")
REPO_URL = os.getenv("REPO_URL",
default="https://github.com/netbox-community/devicetype-library.git")
REPO_BRANCH = os.getenv("REPO_BRANCH", default="master")
NETBOX_URL = os.getenv("NETBOX_URL")
NETBOX_TOKEN = os.getenv("NETBOX_TOKEN")
IGNORE_SSL_ERRORS = (os.getenv("IGNORE_SSL_ERRORS", "False") == "True")
IGNORE_SSL_ERRORS = (os.getenv("IGNORE_SSL_ERRORS", default="False") == "True")
REPO_PATH = "./repo"
# optionally load vendors through a comma separated list as env var
VENDORS = list(filter(None, os.getenv("VENDORS", "").split(",")))
@ -18,8 +24,25 @@ NETBOX_FEATURES = {
'modules': False,
}
MANDATORY_ENV_VARS = ["REPO_URL", "NETBOX_URL", "NETBOX_TOKEN"]
parser = ArgumentParser(description='Import Netbox Device Types')
parser.add_argument('--vendors', nargs='+', default=VENDORS,
help="List of vendors to import eg. apc cisco")
parser.add_argument('--url', '--git', default=REPO_URL,
help="Git URL with valid Device Type YAML files")
parser.add_argument('--slugs', nargs='+', default=SLUGS,
help="List of device-type slugs to import eg. ap4431 ws-c3850-24t-l")
parser.add_argument('--branch', default=REPO_BRANCH,
help="Git branch to use from repo")
parser.add_argument('--verbose', action='store_true', default=False,
help="Print verbose output")
args = parser.parse_args()
handle = ExceptionHandler(args)
# Evaluate environment variables and exit if one of the mandatory ones are not set
MANDATORY_ENV_VARS = ["REPO_URL", "NETBOX_URL", "NETBOX_TOKEN"]
for var in MANDATORY_ENV_VARS:
if var not in os.environ:
raise EnvironmentError("Failed because {} is not set.".format(var))
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)}')
git_repo = GitCMD(args, REPO_PATH)