forked from bb-Ricardo/netbox-sync
-
Notifications
You must be signed in to change notification settings - Fork 0
/
netbox-sync.py
executable file
·145 lines (104 loc) · 4.41 KB
/
netbox-sync.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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Copyright (c) 2020 - 2021 Ricardo Bartels. All rights reserved.
#
# netbox-sync.py
#
# This work is licensed under the terms of the MIT license.
# For a copy, see file LICENSE.txt included in this
# repository or visit: <https://opensource.org/licenses/MIT>.
self_description = """
Sync objects from various sources to NetBox
"""
from datetime import datetime
from module.common.misc import grab, get_relative_time
from module.common.cli_parser import parse_command_line
from module.common.logging import setup_logging
from module.common.configuration import get_config_file, open_config_file, get_config
from module.netbox.connection import NetBoxHandler
from module.netbox.inventory import NetBoxInventory
from module.netbox.object_classes import *
from module.sources import instantiate_sources
__version__ = "1.1.0"
__version_date__ = "2021-06-30"
__author__ = "Ricardo Bartels <[email protected]>"
__description__ = "NetBox Sync"
__license__ = "MIT"
__url__ = "https://github.com/bb-ricardo/netbox-sync"
default_log_level = "INFO"
default_config_file_path = "./settings.ini"
def main():
start_time = datetime.now()
# parse command line
args = parse_command_line(self_description=self_description,
version=__version__,
version_date=__version_date__,
default_config_file_path=default_config_file_path)
# get config file path
config_file = get_config_file(args.config_file)
# get config handler
config_handler = open_config_file(config_file)
# get logging configuration
# set log level
log_level = default_log_level
# config overwrites default
log_level = config_handler.get("common", "log_level", fallback=log_level)
# cli option overwrites config file
log_level = grab(args, "log_level", fallback=log_level)
log_file = None
if bool(config_handler.getboolean("common", "log_to_file", fallback=False)) is True:
log_file = config_handler.get("common", "log_file", fallback=None)
# setup logging
log = setup_logging(log_level, log_file)
# now we are ready to go
log.info("Starting " + __description__)
log.debug(f"Using config file: {config_file}")
# initialize an empty inventory which will be used to hold and reference all objects
inventory = NetBoxInventory()
# get config for NetBox handler
netbox_settings = get_config(config_handler, section="netbox", valid_settings=NetBoxHandler.settings)
# establish NetBox connection
nb_handler = NetBoxHandler(settings=netbox_settings, inventory=inventory)
# if purge was selected we go ahead and remove all items which were managed by this tools
if args.purge is True:
if args.dry_run is True:
do_error_exit("Purge not available with option 'dry_run'")
nb_handler.just_delete_all_the_things()
# that's it, we are done here
exit(0)
# instantiate source handlers and get attributes
log.info("Initializing sources")
sources = instantiate_sources(config_handler, inventory)
# all sources are unavailable
if len(sources) == 0:
log.error("No working sources found. Exit.")
exit(1)
# collect all dependent object classes
log.info("Querying necessary objects from Netbox. This might take a while.")
for source in sources:
nb_handler.query_current_data(source.dependent_netbox_objects)
log.info("Finished querying necessary objects from Netbox")
# resolve object relations within the initial inventory
inventory.resolve_relations()
# initialize basic data needed for syncing
nb_handler.initialize_basic_data()
# loop over sources and patch netbox data
for source in sources:
source.apply()
# add/remove tags to/from all inventory items
inventory.tag_all_the_things(nb_handler)
# update all IP addresses
inventory.query_ptr_records_for_all_ips()
if args.dry_run is True:
log.info("This is a dry run and we stop here. Running time: %s" %
get_relative_time(datetime.now() - start_time))
exit(0)
# update data in NetBox
nb_handler.update_instance()
# prune orphaned objects from NetBox
nb_handler.prune_data()
# finish
log.info("Completed NetBox Sync in %s" % get_relative_time(datetime.now() - start_time))
if __name__ == "__main__":
main()
# EOF