Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add --replace-existing-images arg (default=False) #150

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
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
2 changes: 1 addition & 1 deletion nb-dt-import.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ def main():
device_types = settings.dtl_repo.parse_files(files, slugs=args.slugs)
settings.handle.log(f'{len(device_types)} Device-Types Found')
netbox.create_manufacturers(vendors)
netbox.create_device_types(device_types)
netbox.create_device_types(device_types, replace_existing_images=args.replace_existing_images)

if netbox.modules:
settings.handle.log("Modules Enabled. Creating Modules...")
Expand Down
49 changes: 38 additions & 11 deletions netbox_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,25 +79,25 @@ def create_manufacturers(self, vendors):
self.handle.log("Error creating manufacturers")
self.handle.verbose_log(f"Error during manufacturer creation. - {request_error.error}")

def create_device_types(self, device_types_to_add):
def create_device_types(self, device_types_to_add, replace_existing_images=True):
for device_type in device_types_to_add:

# Remove file base path
src_file = device_type["src"]
del device_type["src"]

# Pre-process front/rear_image flag, remove it if present
saved_images = {}
# Pre-process front/rear_image flag, remove flag if present
device_images_from_library = {}
image_base = os.path.dirname(src_file).replace("device-types","elevation-images")
for i in ["front_image","rear_image"]:
if i in device_type:
if device_type[i]:
image_glob = f"{image_base}/{device_type['slug']}.{i.split('_')[0]}.*"
images = glob.glob(image_glob, recursive=False)
if images:
saved_images[i] = images[0]
device_images_from_library[i] = images[0]
else:
self.handle.log(f"Error locating image file using '{image_glob}'")
self.handle.log(f"Error locating image file using '{image_glob}'")
del device_type[i]

try:
Expand Down Expand Up @@ -137,8 +137,8 @@ def create_device_types(self, device_types_to_add):
self.device_types.create_module_bays(device_type['module-bays'], dt.id)

# Finally, update images if any
if saved_images:
self.device_types.upload_images(self.url, self.token, saved_images, dt.id)
if device_images_from_library:
self.device_types.upload_images(self.url, self.token, device_images_from_library, dt.id, replace_existing_images=replace_existing_images)

def create_module_types(self, module_types):
all_module_types = {}
Expand Down Expand Up @@ -463,23 +463,50 @@ def create_module_front_ports(self, front_ports, module_type):
except pynetbox.RequestError as excep:
self.handle.log(f"Error '{excep.error}' creating Module Front Port")

def upload_images(self,baseurl,token,images,device_type):
'''Upload front_image and/or rear_image for the given device type


def upload_images(self, baseurl, token, images, device_type_id, replace_existing_images=False):
'''Upload front_image and/or rear_image for the given device type if they do not already exist, unless replace_existing_images is True.

Args:
baseurl: URL for Netbox instance
token: Token to access Netbox instance
images: map of front_image and/or rear_image filename
device_type: id for the device-type to update
device_type_id: id for the device-type to update
replace_existing_images: boolean flag, if True, forces upload even if images already exist

Returns:
None
'''
url = f"{baseurl}/api/dcim/device-types/{device_type}/"
# Fetch the current device type details using PyNetBox
device_type = self.netbox.dcim.device_types.get(device_type_id)

if not device_type:
self.handle.log(f"Device type with ID {device_type_id} not found in NetBox.")
return

# Check if images already exist
existing_images = {
"front_image": getattr(device_type, "front_image", None),
"rear_image": getattr(device_type, "rear_image", None)
}

# Filter out images that already exist unless replace_existing_images is True
images_to_upload = {
key: value for key, value in images.items()
if replace_existing_images or not existing_images.get(key)
}

if not images_to_upload:
self.handle.log(f"No new images to upload for device type {device_type}. Skipping.")
return

url = f"{baseurl}/api/dcim/device-types/{device_type_id}/"
headers = { "Authorization": f"Token {token}" }

files = { i: (os.path.basename(f), open(f,"rb") ) for i,f in images.items() }
response = requests.patch(url, headers=headers, files=files, verify=(not self.ignore_ssl))

self.handle.log( f'Images {images} updated at {url}: {response}' )
self.counter["images"] += len(images)

4 changes: 3 additions & 1 deletion settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,9 @@
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,
parser.add_argument('--replace-existing-images', action='store_true', default=False,
help="Force image upload replacing existing images")
parser.add_argument('--verbose', '-v', action='store_true', default=False,
help="Print verbose output")

args = parser.parse_args()
Expand Down