Skip to content

Commit

Permalink
adds support for proxies and NetBox client certs #140
Browse files Browse the repository at this point in the history
  • Loading branch information
bb-Ricardo committed May 24, 2022
1 parent 71c97de commit 99a10ac
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 16 deletions.
2 changes: 1 addition & 1 deletion module/common/misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ def do_error_exit(log_text):
the text to log as error
"""

print(log_text, file=sys.stderr)
print(f"ERROR: {log_text}", file=sys.stderr)
exit(1)


Expand Down
26 changes: 25 additions & 1 deletion module/netbox/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ class NetBoxHandler:
"port": None,
"disable_tls": False,
"validate_tls_certs": True,
"proxy": None,
"client_cert": None,
"client_cert_key": None,
"prune_enabled": False,
"prune_delay_in_days": 30,
"default_netbox_result_limit": 200,
Expand Down Expand Up @@ -178,6 +181,13 @@ def parse_config_settings(self, config_settings):
log.error(f"Config option '{setting}' in 'netbox' must be an integer.")
validation_failed = True

proxy = config_settings.get("proxy")
if proxy is not None:
if "://" not in proxy or (not proxy.startswith("http") and not proxy.startswith("socks5")):
log.error(f"Config option 'proxy' in 'netbox' must contain the schema "
f"http, https, socks5 or socks5h")
validation_failed = True

if validation_failed is True:
log.error("Config validation failed. Exit!")
exit(1)
Expand All @@ -203,6 +213,20 @@ def create_session(self):
session = requests.Session()
session.headers.update(header)

# adds proxy to the session
if self.proxy is not None:
session.proxies.update({
"http": self.proxy,
"https": self.proxy
})

# adds client cert to session
if self.client_cert is not None:
if self.client_cert_key is not None:
session.cert = (self.client_cert, self.client_cert_key)
else:
session.cert = self.client_cert

log.debug("Created new requests Session for NetBox.")

return session
Expand All @@ -222,7 +246,7 @@ def get_api_version(self):
timeout=self.timeout,
verify=self.validate_tls_certs)
except Exception as e:
do_error_exit(str(e))
do_error_exit(f"NetBox connection: {e}")

result = str(response.headers.get("API-Version"))

Expand Down
61 changes: 47 additions & 14 deletions module/sources/vmware/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

import urllib3
import requests
from pyVim.connect import SmartConnect, Disconnect
from pyVim import connect
from pyVmomi import vim
from pyVmomi.VmomiSupport import VmomiJSONEncoder

Expand Down Expand Up @@ -97,6 +97,8 @@ class VMWareHandler(SourceBase):
"username": None,
"password": None,
"validate_tls_certs": False,
"proxy_host": None,
"proxy_port": None,
"cluster_exclude_filter": None,
"cluster_include_filter": None,
"host_exclude_filter": None,
Expand Down Expand Up @@ -325,25 +327,49 @@ def create_sdk_session(self):
ssl_context.check_hostname = False
ssl_context.verify_mode = ssl.CERT_NONE

try:
instance = SmartConnect(
host=self.host_fqdn,
port=self.port,
connection_params = dict(
host=self.host_fqdn,
port=self.port,
sslContext=ssl_context
)

# uses connect.SmartStubAdapter
if self.proxy_host is not None and self.proxy_port is not None:
connection_params.update(
httpProxyHost=self.proxy_host,
httpProxyPort=int(self.proxy_port),
)

# uses connect.SmartConnect
else:
connection_params.update(
user=self.username,
pwd=self.password,
sslContext=ssl_context
)
atexit.register(Disconnect, instance)

def_exception_text = f"Unable to connect to vCenter instance '{self.host_fqdn}' on port {self.port}."

try:
if self.proxy_host is not None and self.proxy_port is not None:
smart_stub = connect.SmartStubAdapter(**connection_params)
instance = vim.ServiceInstance('ServiceInstance', smart_stub)
content = instance.RetrieveContent()
content.sessionManager.Login(self.username, self.password, None)
else:

instance = connect.SmartConnect(**connection_params)

atexit.register(connect.Disconnect, instance)
self.session = instance.RetrieveContent()

except (gaierror, OSError) as e:
log.error(
f"Unable to connect to vCenter instance '{self.host_fqdn}' on port {self.port}. "
f"Reason: {e}"
)
return False
except vim.fault.InvalidLogin as e:
log.error(f"Unable to connect to vCenter instance '{self.host_fqdn}' on port {self.port}. {e.msg}")
log.error(f"{def_exception_text} {e.msg}")
return False
except vim.fault.NoPermission as e:
log.error(f"{def_exception_text} User {self.username} does not have required permission. {e.msg}")
return False
except Exception as e:
log.error(f"{def_exception_text} Reason: {e}")
return False

log.info(f"Successfully connected to vCenter SDK '{self.host_fqdn}'")
Expand Down Expand Up @@ -383,6 +409,13 @@ def create_api_session(self):
if bool(self.validate_tls_certs) is False:
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

# adds proxy to the session
if self.proxy_host is not None and self.proxy_port is not None:
session.proxies.update({
"http": f"http://{self.proxy_host}:{self.proxy_port}",
"https": f"http://{self.proxy_host}:{self.proxy_port}",
})

try:
self.tag_session = create_vsphere_client(
server=f"{self.host_fqdn}:{self.port}",
Expand Down
15 changes: 15 additions & 0 deletions settings-example.ini
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,17 @@ host_fqdn = netbox.example.com
# web server certificate then this option needs to be changed
#validate_tls_certs = true

# Defines a proxy which will be used to connect to NetBox.
# proxy setting needs to include the scheme.
# proxy basic auth example: http://user:[email protected]:3128
#proxy = http://example.com:3128

# Specify a client certificate which can be used to authenticate to NetBox.
#client_cert = client.pem

# Specify the client certificate private key belonging to the client cert.
#client_cert_key = client.key

# Whether items which were created by this program but can't be found in any
# source anymore will be deleted or not.
#prune_enabled = false
Expand Down Expand Up @@ -113,6 +124,10 @@ host_fqdn = vcenter.example.com
# TCP port to connect to
#port = 443

# EXPERIMENTAL: Connect to a vCenter using a proxy (socks proxies are not supported)
#proxy_host = 10.10.1.10
#proxy_port = 3128

# Enforces TLS certificate validation. If vCenter uses a valid TLS certificate then
# this option should be set to 'true' to ensure a secure connection.
#validate_tls_certs = false
Expand Down

0 comments on commit 99a10ac

Please sign in to comment.