forked from netbox-community/Device-Type-Library-Import
-
Notifications
You must be signed in to change notification settings - Fork 0
/
repo.py
106 lines (89 loc) · 4 KB
/
repo.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import os
from glob import glob
from re import sub as re_sub
from git import Repo, exc
import yaml
class DTLRepo:
def __new__(cls, *args, **kwargs):
return super().__new__(cls)
def __init__(self, args, repo_path, exception_handler):
self.handle = exception_handler
self.yaml_extensions = ['yaml', 'yml']
self.url = args.url
self.repo_path = repo_path
self.branch = args.branch
self.repo = None
self.cwd = os.getcwd()
if os.path.isdir(self.repo_path):
self.pull_repo()
else:
self.clone_repo()
def get_relative_path(self):
return self.repo_path
def get_absolute_path(self):
return os.path.join(self.cwd, self.repo_path)
def get_devices_path(self):
return os.path.join(self.get_absolute_path(), 'device-types')
def get_modules_path(self):
return os.path.join(self.get_absolute_path(), 'module-types')
def slug_format(self, name):
return re_sub('\W+', '-', name.lower())
def pull_repo(self):
try:
self.handle.log("Package devicetype-library is already installed, "
+ f"updating {self.get_absolute_path()}")
self.repo = Repo(self.repo_path)
if not self.repo.remotes.origin.url.endswith('.git'):
self.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)
self.handle.verbose_log(
f"Pulled Repo {self.repo.remotes.origin.url}")
except exc.GitCommandError as git_error:
self.handle.exception(
"GitCommandError", self.repo.remotes.origin.url, git_error)
except Exception as git_error:
self.handle.exception(
"Exception", 'Git Repository Error', git_error)
def clone_repo(self):
try:
self.repo = Repo.clone_from(
self.url, self.get_absolute_path(), branch=self.branch)
self.handle.log(
f"Package Installed {self.repo.remotes.origin.url}")
except exc.GitCommandError as git_error:
self.handle.exception("GitCommandError", self.url, git_error)
except Exception as git_error:
self.handle.exception(
"Exception", 'Git Repository Error', git_error)
def get_devices(self, base_path, vendors: list = None):
files = []
discovered_vendors = []
vendor_dirs = os.listdir(base_path)
for folder in [vendor for vendor in vendor_dirs if not vendors or vendor.casefold() in vendors]:
if folder.casefold() != "testing":
discovered_vendors.append({'name': folder,
'slug': self.slug_format(folder)})
for extension in self.yaml_extensions:
files.extend(glob(base_path + folder + f'/*.{extension}'))
return files, discovered_vendors
def parse_files(self, files: list, slugs: list = None):
deviceTypes = []
for file in files:
with open(file, 'r') as stream:
try:
data = yaml.safe_load(stream)
except yaml.YAMLError as excep:
self.handle.verbose_log(excep)
continue
manufacturer = data['manufacturer']
data['manufacturer'] = {
'name': manufacturer, 'slug': self.slug_format(manufacturer)}
# Save file location to resolve any relative paths for images
data['src'] = file
if slugs and True not in [True if s.casefold() in data['slug'].casefold() else False for s in slugs]:
self.handle.verbose_log(f"Skipping {data['model']}")
continue
deviceTypes.append(data)
return deviceTypes