Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 27 additions & 0 deletions exception_handler.py
Original file line number Diff line number Diff line change
@@ -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 changes: 46 additions & 0 deletions gitcmd.py
Original file line number Diff line number Diff line change
@@ -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)

53 changes: 5 additions & 48 deletions nb-dt-import.py
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -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):
Expand Down Expand Up @@ -769,54 +758,22 @@ 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
nb = pynetbox.api(nbUrl, token=nbToken)

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()
Expand Down
33 changes: 28 additions & 5 deletions settings.py
Original file line number Diff line number Diff line change
@@ -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(",")))
Expand All @@ -18,8 +24,25 @@
'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)