Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12:Update
salt.21409
fix-for-some-cves-bsc1181550.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File fix-for-some-cves-bsc1181550.patch of Package salt.21409
From fccf31a57d37d6c67c2d596e52d2debc9e9c7978 Mon Sep 17 00:00:00 2001 From: "Daniel A. Wozniak" <dwozniak@vmware.com> Date: Tue, 26 Jan 2021 12:53:55 -0700 Subject: [PATCH] Fix for some cves bsc1181550 CVE-2020-28243 CVE-2020-28972 CVE-2020-35662 CVE-2021-3148 CVE-2021-3144 CVE-2021-25281 CVE-2021-25282 CVE-2021-25283 CVE-2021-25284 CVE-2021-3197 --- salt/auth/__init__.py | 1 + salt/client/mixins.py | 45 +- salt/client/ssh/client.py | 46 ++ salt/cloud/clouds/qingcloud.py | 6 +- salt/cloud/clouds/vmware.py | 16 +- salt/config/schemas/vcenter.py | 7 +- salt/master.py | 18 +- salt/modules/bigip.py | 2 +- salt/modules/cmdmod.py | 26 +- salt/modules/glassfish.py | 6 +- salt/modules/keystone.py | 7 +- salt/modules/restartcheck.py | 4 +- salt/modules/vsphere.py | 880 +++++++++++++++++++++------------ salt/modules/zenoss.py | 16 +- salt/pillar/vmware_pillar.py | 9 +- salt/proxy/cimc.py | 13 +- salt/proxy/panos.py | 10 +- salt/proxy/vcenter.py | 2 + salt/returners/splunk.py | 20 +- salt/runners/asam.py | 19 +- salt/states/esxi.py | 8 +- salt/utils/http.py | 20 + salt/utils/templates.py | 8 +- salt/utils/thin.py | 56 ++- salt/utils/vmware.py | 158 +++--- salt/wheel/__init__.py | 4 +- salt/wheel/pillar_roots.py | 6 +- 27 files changed, 937 insertions(+), 476 deletions(-) diff --git a/salt/auth/__init__.py b/salt/auth/__init__.py index ba9dbad509..230a9eccfe 100644 --- a/salt/auth/__init__.py +++ b/salt/auth/__init__.py @@ -267,6 +267,7 @@ class LoadAuth(object): if rm_tok: self.rm_token(tok) + return {} return tdata diff --git a/salt/client/mixins.py b/salt/client/mixins.py index 8ca8c7fbf6..d0b43b9ff5 100644 --- a/salt/client/mixins.py +++ b/salt/client/mixins.py @@ -461,10 +461,10 @@ class AsyncClientMixin(object): client = None tag_prefix = None - def _proc_function(self, fun, low, user, tag, jid, daemonize=True): + def _proc_function_remote(self, fun, low, user, tag, jid, daemonize=True): ''' - Run this method in a multiprocess target to execute the function in a - multiprocess and fire the return data on the event bus + Run this method in a multiprocess target to execute the function on the + master and fire the return data on the event bus ''' if daemonize and not salt.utils.platform.is_windows(): # Shutdown the multiprocessing before daemonizing @@ -480,7 +480,31 @@ class AsyncClientMixin(object): low['__user__'] = user low['__tag__'] = tag - return self.low(fun, low, full_return=False) + try: + return self.cmd_sync(low) + except salt.exceptions.EauthAuthenticationError as exc: + log.error(exc) + + def _proc_function(self, fun, low, user, tag, jid, daemonize=True): + ''' + Run this method in a multiprocess target to execute the function + locally and fire the return data on the event bus + ''' + if daemonize and not salt.utils.platform.is_windows(): + # Shutdown the multiprocessing before daemonizing + salt.log.setup.shutdown_multiprocessing_logging() + + salt.utils.process.daemonize() + + # Reconfigure multiprocessing logging after daemonizing + salt.log.setup.setup_multiprocessing_logging() + + # pack a few things into low + low["__jid__"] = jid + low["__user__"] = user + low["__tag__"] = tag + + return self.low(fun, low) def cmd_async(self, low): ''' @@ -508,16 +532,21 @@ class AsyncClientMixin(object): tag = salt.utils.event.tagify(jid, prefix=self.tag_prefix) return {'tag': tag, 'jid': jid} - def asynchronous(self, fun, low, user='UNKNOWN', pub=None): + def asynchronous(self, fun, low, user="UNKNOWN", pub=None, local=True): ''' Execute the function in a multiprocess and return the event tag to use to watch for the return ''' + if local: + proc_func = self._proc_function + else: + proc_func = self._proc_function_remote async_pub = pub if pub is not None else self._gen_async_pub() proc = salt.utils.process.SignalHandlingProcess( - target=self._proc_function, - name='ProcessFunc', - args=(fun, low, user, async_pub['tag'], async_pub['jid'])) + target=proc_func, + name="ProcessFunc", + args=(fun, low, user, async_pub["tag"], async_pub["jid"]), + ) with salt.utils.process.default_signals(signal.SIGINT, signal.SIGTERM): # Reset current signals before starting the process in # order not to inherit the current signal handlers diff --git a/salt/client/ssh/client.py b/salt/client/ssh/client.py index d4a89cf4fb..ae514d67b3 100644 --- a/salt/client/ssh/client.py +++ b/salt/client/ssh/client.py @@ -43,6 +43,51 @@ class SSHClient(object): # Salt API should never offer a custom roster! self.opts['__disable_custom_roster'] = disable_custom_roster + def sanitize_kwargs(self, kwargs): + roster_vals = [ + ('host', str), + ('ssh_user', str), + ('ssh_passwd', str), + ('ssh_port', int), + ('ssh_sudo', bool), + ('ssh_sudo_user', str), + ('ssh_priv', str), + ('ssh_priv_passwd', str), + ('ssh_identities_only', bool), + ('ssh_remote_port_forwards', str), + ('ssh_options', list), + ('roster_file', str), + ('rosters', list), + ('ignore_host_keys', bool), + ('raw_shell', bool), + ] + sane_kwargs = {} + for name, kind in roster_vals: + if name not in kwargs: + continue + try: + val = kind(kwargs[name]) + except ValueError: + log.warn("Unable to cast kwarg %s", name) + continue + if kind is bool or kind is int: + sane_kwargs[name] = val + elif kind is str: + if val.find('ProxyCommand') != -1: + log.warn("Filter unsafe value for kwarg %s", name) + continue + sane_kwargs[name] = val + elif kind is list: + sane_val = [] + for item in val: + # This assumes the values are strings + if item.find('ProxyCommand') != -1: + log.warn("Filter unsafe value for kwarg %s", name) + continue + sane_val.append(item) + sane_kwargs[name] = sane_val + return sane_kwargs + def _prep_ssh( self, tgt, @@ -55,6 +100,7 @@ class SSHClient(object): ''' Prepare the arguments ''' + kwargs = self.sanitize_kwargs(kwargs) opts = copy.deepcopy(self.opts) opts.update(kwargs) if timeout: diff --git a/salt/cloud/clouds/qingcloud.py b/salt/cloud/clouds/qingcloud.py index 319f6d236c..f1d7887055 100644 --- a/salt/cloud/clouds/qingcloud.py +++ b/salt/cloud/clouds/qingcloud.py @@ -141,6 +141,10 @@ def query(params=None): 'secret_access_key', get_configured_provider(), __opts__, search_global=False ) + verify_ssl = config.get_cloud_config_value( + 'verify_ssl', get_configured_provider(), __opts__, default=True, search_global=False + ) + # public interface parameters real_parameters = { 'access_key_id': access_key_id, @@ -171,7 +175,7 @@ def query(params=None): # print('parameters:') # pprint.pprint(real_parameters) - request = requests.get(path, params=real_parameters, verify=False) + request = requests.get(path, params=real_parameters, verify=verify_ssl) # print('url:') # print(request.url) diff --git a/salt/cloud/clouds/vmware.py b/salt/cloud/clouds/vmware.py index b53551730b..a24175ccec 100644 --- a/salt/cloud/clouds/vmware.py +++ b/salt/cloud/clouds/vmware.py @@ -253,12 +253,16 @@ def _get_si(): port = config.get_cloud_config_value( 'port', get_configured_provider(), __opts__, search_global=False, default=443 ) - - return salt.utils.vmware.get_service_instance(url, - username, - password, - protocol=protocol, - port=port) + verify_ssl = config.get_cloud_config_value( + "verify_ssl", + get_configured_provider(), + __opts__, + search_global=False, + default=True, + ) + return salt.utils.vmware.get_service_instance( + url, username, password, protocol=protocol, port=port, verify_ssl=verify_ssl + ) def _edit_existing_hard_disk_helper(disk, size_kb=None, size_gb=None, mode=None): diff --git a/salt/config/schemas/vcenter.py b/salt/config/schemas/vcenter.py index e46149665f..c40a4053c8 100644 --- a/salt/config/schemas/vcenter.py +++ b/salt/config/schemas/vcenter.py @@ -13,10 +13,7 @@ from __future__ import absolute_import, print_function, unicode_literals # Import Salt libs -from salt.utils.schema import (Schema, - ArrayItem, - IntegerItem, - StringItem) +from salt.utils.schema import ArrayItem, IntegerItem, Schema, StringItem, BooleanItem class VCenterEntitySchema(Schema): @@ -50,6 +47,8 @@ class VCenterProxySchema(Schema): passwords = ArrayItem(min_items=1, items=StringItem(), unique_items=True) + verify_ssl = BooleanItem() + ca_bundle = StringItem() domain = StringItem() principal = StringItem(default='host') diff --git a/salt/master.py b/salt/master.py index 04ff721cd9..8bccc00036 100644 --- a/salt/master.py +++ b/salt/master.py @@ -1984,7 +1984,8 @@ class ClearFuncs(TransportMethods): runner_client = salt.runner.RunnerClient(self.opts) return runner_client.asynchronous(fun, clear_load.get('kwarg', {}), - username) + username, + local=True) except Exception as exc: # pylint: disable=broad-except log.error('Exception occurred while introspecting %s: %s', fun, exc) return {'error': {'name': exc.__class__.__name__, @@ -1995,6 +1996,7 @@ class ClearFuncs(TransportMethods): ''' Send a master control function back to the wheel system ''' + jid = clear_load.get('__jid__', salt.utils.jid.gen_jid(self.opts)) # All wheel ops pass through eauth auth_type, err_name, key, sensitive_load_keys = self._prep_auth_info(clear_load) @@ -2004,6 +2006,8 @@ class ClearFuncs(TransportMethods): if error: # Authentication error occurred: do not continue. + data = {'error': error, 'jid': jid} + self.event.fire_event(data, tagify([jid, "new"], "wheel")) return {'error': error} # Authorize @@ -2015,9 +2019,14 @@ class ClearFuncs(TransportMethods): clear_load.get('kwarg', {}) ) if not wheel_check: - return {'error': {'name': err_name, - 'message': 'Authentication failure of type "{0}" occurred for ' - 'user {1}.'.format(auth_type, username)}} + err_data = { + 'name': err_name, + 'message': 'Authentication failure of type "{0}" occurred for ' + 'user {1}.'.format(auth_type, username) + } + data = {'error': err_data, 'jid': jid} + self.event.fire_event(data, tagify([jid, "new"], "wheel")) + return {'error': err_data} elif isinstance(wheel_check, dict) and 'error' in wheel_check: # A dictionary with an error name/message was handled by ckminions.wheel_check return wheel_check @@ -2035,7 +2044,6 @@ class ClearFuncs(TransportMethods): # Authorized. Do the job! try: - jid = salt.utils.jid.gen_jid(self.opts) fun = clear_load.pop('fun') tag = tagify(jid, prefix='wheel') data = {'fun': "wheel.{0}".format(fun), diff --git a/salt/modules/bigip.py b/salt/modules/bigip.py index 3737bf2ad9..4a2db598e1 100644 --- a/salt/modules/bigip.py +++ b/salt/modules/bigip.py @@ -47,7 +47,7 @@ def _build_session(username, password, trans_label=None): bigip = requests.session() bigip.auth = (username, password) - bigip.verify = False + bigip.verify = True bigip.headers.update({'Content-Type': 'application/json'}) if trans_label: diff --git a/salt/modules/cmdmod.py b/salt/modules/cmdmod.py index 0d2f720bbb..87476c1bde 100644 --- a/salt/modules/cmdmod.py +++ b/salt/modules/cmdmod.py @@ -76,6 +76,12 @@ def __virtual__(): return __virtualname__ +def _log_cmd(cmd): + if not isinstance(cmd, list): + return cmd.split()[0].strip() + return cmd[0].strip() + + def _check_cb(cb_): ''' If the callback is None or is not callable, return a lambda that returns @@ -370,23 +376,15 @@ def _run(cmd, 'Setting value to an empty string', bad_env_key) env[bad_env_key] = '' - def _get_stripped(cmd): - # Return stripped command string copies to improve logging. - if isinstance(cmd, list): - return [x.strip() if isinstance(x, six.string_types) else x for x in cmd] - elif isinstance(cmd, six.string_types): - return cmd.strip() - else: - return cmd - if output_loglevel is not None: # Always log the shell commands at INFO unless quiet logging is # requested. The command output is what will be controlled by the # 'loglevel' parameter. + msg = ( 'Executing command {0}{1}{0} {2}{3}in directory \'{4}\'{5}'.format( '\'' if not isinstance(cmd, list) else '', - _get_stripped(cmd), + _log_cmd(cmd), 'as user \'{0}\' '.format(runas) if runas else '', 'in group \'{0}\' '.format(group) if group else '', cwd, @@ -710,7 +708,7 @@ def _run(cmd, if output_loglevel != 'quiet': log.error( 'Failed to decode stdout from command %s, non-decodable ' - 'characters have been replaced', cmd + 'characters have been replaced', _log_cmd(cmd) ) try: @@ -728,7 +726,7 @@ def _run(cmd, if output_loglevel != 'quiet': log.error( 'Failed to decode stderr from command %s, non-decodable ' - 'characters have been replaced', cmd + 'characters have been replaced', _log_cmd(cmd) ) if rstrip: @@ -831,7 +829,7 @@ def _run(cmd, output_loglevel = LOG_LEVELS['error'] msg = ( 'Command \'{0}\' failed with return code: {1}'.format( - cmd, + _log_cmd(cmd), ret['retcode'] ) ) @@ -1187,7 +1185,7 @@ def run(cmd, lvl = LOG_LEVELS['error'] msg = ( 'Command \'{0}\' failed with return code: {1}'.format( - cmd, + _log_cmd(cmd), ret['retcode'] ) ) diff --git a/salt/modules/glassfish.py b/salt/modules/glassfish.py index f2824a2f67..8d6dafbc00 100644 --- a/salt/modules/glassfish.py +++ b/salt/modules/glassfish.py @@ -116,7 +116,7 @@ def _api_get(path, server=None): url=_get_url(server['ssl'], server['url'], server['port'], path), auth=_get_auth(server['user'], server['password']), headers=_get_headers(), - verify=False + verify=True ) return _api_response(response) @@ -131,7 +131,7 @@ def _api_post(path, data, server=None): auth=_get_auth(server['user'], server['password']), headers=_get_headers(), data=salt.utils.json.dumps(data), - verify=False + verify=True ) return _api_response(response) @@ -146,7 +146,7 @@ def _api_delete(path, data, server=None): auth=_get_auth(server['user'], server['password']), headers=_get_headers(), params=data, - verify=False + verify=True ) return _api_response(response) diff --git a/salt/modules/keystone.py b/salt/modules/keystone.py index b929be25ec..de8eeade49 100644 --- a/salt/modules/keystone.py +++ b/salt/modules/keystone.py @@ -13,6 +13,7 @@ Module for handling openstack keystone calls. keystone.tenant: admin keystone.tenant_id: f80919baedab48ec8931f200c65a50df keystone.auth_url: 'http://127.0.0.1:5000/v2.0/' + keystone.verify_ssl: True OR (for token based authentication) @@ -32,6 +33,7 @@ Module for handling openstack keystone calls. keystone.tenant: admin keystone.tenant_id: f80919baedab48ec8931f200c65a50df keystone.auth_url: 'http://127.0.0.1:5000/v2.0/' + keystone.verify_ssl: True openstack2: keystone.user: admin @@ -39,6 +41,7 @@ Module for handling openstack keystone calls. keystone.tenant: admin keystone.tenant_id: f80919baedab48ec8931f200c65a50df keystone.auth_url: 'http://127.0.0.2:5000/v2.0/' + keystone.verify_ssl: True With this configuration in place, any of the keystone functions can make use of a configuration profile by declaring it explicitly. @@ -117,6 +120,7 @@ def _get_kwargs(profile=None, **connection_args): endpoint = get('endpoint', 'http://127.0.0.1:35357/v2.0') user_domain_name = get('user_domain_name', 'Default') project_domain_name = get('project_domain_name', 'Default') + verify_ssl = get("verify_ssl", True) if token: kwargs = {'token': token, 'endpoint': endpoint} @@ -132,6 +136,7 @@ def _get_kwargs(profile=None, **connection_args): # this ensures it's only passed in when defined if insecure: kwargs['insecure'] = True + kwargs["verify_ssl"] = verify_ssl return kwargs @@ -149,7 +154,7 @@ def api_version(profile=None, **connection_args): auth_url = kwargs.get('auth_url', kwargs.get('endpoint', None)) try: return salt.utils.http.query(auth_url, decode=True, decode_type='json', - verify_ssl=False)['dict']['version']['id'] + verify_ssl=kwargs["verify_ssl"])['dict']['version']['id'] except KeyError: return None diff --git a/salt/modules/restartcheck.py b/salt/modules/restartcheck.py index 426a90e970..2ffeccf1b1 100644 --- a/salt/modules/restartcheck.py +++ b/salt/modules/restartcheck.py @@ -15,6 +15,7 @@ from __future__ import absolute_import, unicode_literals, print_function # Import python libs import os import re +import shlex import subprocess import sys import time @@ -548,7 +549,8 @@ def restartcheck(ignorelist=None, blacklist=None, excludepid=None, **kwargs): for package in packages: _check_timeout(start_time, timeout) cmd = cmd_pkg_query + package - paths = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE) + cmd = shlex.split(cmd) + paths = subprocess.Popen(cmd, stdout=subprocess.PIPE) while True: _check_timeout(start_time, timeout) diff --git a/salt/modules/vsphere.py b/salt/modules/vsphere.py index 3d77807820..7c5c1036f3 100644 --- a/salt/modules/vsphere.py +++ b/salt/modules/vsphere.py @@ -309,13 +309,19 @@ def _get_proxy_connection_details(): else: raise CommandExecutionError('\'{0}\' proxy is not supported' ''.format(proxytype)) - return \ - details.get('vcenter') if 'vcenter' in details \ - else details.get('host'), \ - details.get('username'), \ - details.get('password'), details.get('protocol'), \ - details.get('port'), details.get('mechanism'), \ - details.get('principal'), details.get('domain') + proxy_details = [ + details.get("vcenter") if "vcenter" in details else details.get("host"), + details.get("username"), + details.get("password"), + details.get("protocol"), + details.get("port"), + details.get("mechanism"), + details.get("principal"), + details.get("domain"), + ] + if "verify_ssl" in details: + proxy_details.append(details.get("verify_ssl")) + return tuple(proxy_details) def supports_proxies(*proxy_types): @@ -395,9 +401,9 @@ def gets_service_instance_via_proxy(fn): # case 1: The call was made with enough positional # parameters to include 'service_instance' if not args[idx]: - local_service_instance = \ - salt.utils.vmware.get_service_instance( - *connection_details) + local_service_instance = salt.utils.vmware.get_service_instance( # pylint: disable=no-value-for-parameter + *connection_details + ) # Tuples are immutable, so if we want to change what # was passed in, we need to first convert to a list. args = list(args) @@ -407,7 +413,7 @@ def gets_service_instance_via_proxy(fn): # 'service_instance' must be a named parameter if not kwargs.get('service_instance'): local_service_instance = \ - salt.utils.vmware.get_service_instance( + salt.utils.vmware.get_service_instance( # pylint: disable=no-value-for-parameter *connection_details) kwargs['service_instance'] = local_service_instance else: @@ -415,7 +421,7 @@ def gets_service_instance_via_proxy(fn): # but it will be caught by the **kwargs parameter if not kwargs.get('service_instance'): local_service_instance = \ - salt.utils.vmware.get_service_instance( + salt.utils.vmware.get_service_instance( # pylint: disable=no-value-for-parameter *connection_details) kwargs['service_instance'] = local_service_instance try: @@ -450,7 +456,9 @@ def get_service_instance_via_proxy(service_instance=None): See note above ''' connection_details = _get_proxy_connection_details() - return salt.utils.vmware.get_service_instance(*connection_details) + return salt.utils.vmware.get_service_instance( # pylint: disable=no-value-for-parameter + *connection_details + ) @depends(HAS_PYVMOMI) @@ -1326,7 +1334,7 @@ def reset_syslog_config(host, @ignores_kwargs('credstore') def upload_ssh_key(host, username, password, ssh_key=None, ssh_key_file=None, - protocol=None, port=None, certificate_verify=False): + protocol=None, port=None, certificate_verify=None): ''' Upload an ssh key for root to an ESXi host via http PUT. This function only works for ESXi, not vCenter. @@ -1342,7 +1350,7 @@ def upload_ssh_key(host, username, password, ssh_key=None, ssh_key_file=None, :param protocol: defaults to https, can be http if ssl is disabled on ESXi :param port: defaults to 443 for https :param certificate_verify: If true require that the SSL connection present - a valid certificate + a valid certificate. Default: True :return: Dictionary with a 'status' key, True if upload is successful. If upload is unsuccessful, 'status' key will be False and an 'Error' key will have an informative message. @@ -1358,6 +1366,8 @@ def upload_ssh_key(host, username, password, ssh_key=None, ssh_key_file=None, protocol = 'https' if port is None: port = 443 + if certificate_verify is None: + certificate_verify = True url = '{0}://{1}:{2}/host/ssh_root_authorized_keys'.format(protocol, host, @@ -1402,7 +1412,7 @@ def get_ssh_key(host, password, protocol=None, port=None, - certificate_verify=False): + certificate_verify=None): ''' Retrieve the authorized_keys entry for root. This function only works for ESXi, not vCenter. @@ -1413,7 +1423,7 @@ def get_ssh_key(host, :param protocol: defaults to https, can be http if ssl is disabled on ESXi :param port: defaults to 443 for https :param certificate_verify: If true require that the SSL connection present - a valid certificate + a valid certificate. Default: True :return: True if upload is successful CLI Example: @@ -1427,6 +1437,8 @@ def get_ssh_key(host, protocol = 'https' if port is None: port = 443 + if certificate_verify is None: + certificate_verify = True url = '{0}://{1}:{2}/host/ssh_root_authorized_keys'.format(protocol, host, @@ -1455,7 +1467,10 @@ def get_ssh_key(host, @depends(HAS_PYVMOMI) @ignores_kwargs('credstore') -def get_host_datetime(host, username, password, protocol=None, port=None, host_names=None): +def get_host_datetime( + host, username, password, protocol=None, port=None, host_names=None, + verify_ssl=True +): ''' Get the date/time information for a given host or list of host_names. @@ -1485,6 +1500,9 @@ def get_host_datetime(host, username, password, protocol=None, port=None, host_n ``host`` location instead. This is useful for when service instance connection information is used for a single ESXi host. + verify_ssl + Verify the SSL certificate. Default: True + CLI Example: .. code-block:: bash @@ -1496,11 +1514,10 @@ def get_host_datetime(host, username, password, protocol=None, port=None, host_n salt '*' vsphere.get_host_datetime my.vcenter.location root bad-password \ host_names='[esxi-1.host.com, esxi-2.host.com]' ''' - service_instance = salt.utils.vmware.get_service_instance(host=host, - username=username, - password=password, - protocol=protocol, - port=port) + service_instance = salt.utils.vmware.get_service_instance( + host=host, username=username, password=password, protocol=protocol, + port=port, verify_ssl=verify_ssl, + ) host_names = _check_hosts(service_instance, host, host_names) ret = {} for host_name in host_names: @@ -1514,7 +1531,8 @@ def get_host_datetime(host, username, password, protocol=None, port=None, host_n @depends(HAS_PYVMOMI) @ignores_kwargs('credstore') -def get_ntp_config(host, username, password, protocol=None, port=None, host_names=None): +def get_ntp_config(host, username, password, protocol=None, port=None, + host_names=None, verify_ssl=True): ''' Get the NTP configuration information for a given host or list of host_names. @@ -1544,6 +1562,9 @@ def get_ntp_config(host, username, password, protocol=None, port=None, host_name ``host`` location instead. This is useful for when service instance connection information is used for a single ESXi host. + verify_ssl + Verify the SSL certificate. Default: True + CLI Example: .. code-block:: bash @@ -1555,11 +1576,10 @@ def get_ntp_config(host, username, password, protocol=None, port=None, host_name salt '*' vsphere.get_ntp_config my.vcenter.location root bad-password \ host_names='[esxi-1.host.com, esxi-2.host.com]' ''' - service_instance = salt.utils.vmware.get_service_instance(host=host, - username=username, - password=password, - protocol=protocol, - port=port) + service_instance = salt.utils.vmware.get_service_instance( + host=host, username=username, password=password, protocol=protocol, + port=port, verify_ssl=verify_ssl, + ) host_names = _check_hosts(service_instance, host, host_names) ret = {} for host_name in host_names: @@ -1572,7 +1592,10 @@ def get_ntp_config(host, username, password, protocol=None, port=None, host_name @depends(HAS_PYVMOMI) @ignores_kwargs('credstore') -def get_service_policy(host, username, password, service_name, protocol=None, port=None, host_names=None): +def get_service_policy( + host, username, password, service_name, protocol=None, port=None, + host_names=None, verify_ssl=True, +): ''' Get the service name's policy for a given host or list of hosts. @@ -1618,6 +1641,9 @@ def get_service_policy(host, username, password, service_name, protocol=None, po for the ``host`` location instead. This is useful for when service instance connection information is used for a single ESXi host. + verify_ssl + Verify the SSL certificate. Default: True + CLI Example: .. code-block:: bash @@ -1629,13 +1655,26 @@ def get_service_policy(host, username, password, service_name, protocol=None, po salt '*' vsphere.get_service_policy my.vcenter.location root bad-password 'ntpd' \ host_names='[esxi-1.host.com, esxi-2.host.com]' ''' - service_instance = salt.utils.vmware.get_service_instance(host=host, - username=username, - password=password, - protocol=protocol, - port=port) - valid_services = ['DCUI', 'TSM', 'SSH', 'ssh', 'lbtd', 'lsassd', 'lwiod', 'netlogond', - 'ntpd', 'sfcbd-watchdog', 'snmpd', 'vprobed', 'vpxa', 'xorg'] + service_instance = salt.utils.vmware.get_service_instance( + host=host, username=username, password=password, protocol=protocol, + port=port, verify_ssl=verify_ssl, + ) + valid_services = [ + 'DCUI', + 'TSM', + 'SSH', + 'ssh', + 'lbtd', + 'lsassd', + 'lwiod', + 'netlogond', + 'ntpd', + 'sfcbd-watchdog', + 'snmpd', + 'vprobed', + 'vpxa', + 'xorg', + ] host_names = _check_hosts(service_instance, host, host_names) ret = {} @@ -1679,7 +1718,10 @@ def get_service_policy(host, username, password, service_name, protocol=None, po @depends(HAS_PYVMOMI) @ignores_kwargs('credstore') -def get_service_running(host, username, password, service_name, protocol=None, port=None, host_names=None): +def get_service_running( + host, username, password, service_name, protocol=None, port=None, + host_names=None, verify_ssl=True, +): ''' Get the service name's running state for a given host or list of hosts. @@ -1725,6 +1767,9 @@ def get_service_running(host, username, password, service_name, protocol=None, p for the ``host`` location instead. This is useful for when service instance connection information is used for a single ESXi host. + verify_ssl + Verify the SSL certificate. Default: True + CLI Example: .. code-block:: bash @@ -1736,13 +1781,26 @@ def get_service_running(host, username, password, service_name, protocol=None, p salt '*' vsphere.get_service_running my.vcenter.location root bad-password 'ntpd' \ host_names='[esxi-1.host.com, esxi-2.host.com]' ''' - service_instance = salt.utils.vmware.get_service_instance(host=host, - username=username, - password=password, - protocol=protocol, - port=port) - valid_services = ['DCUI', 'TSM', 'SSH', 'ssh', 'lbtd', 'lsassd', 'lwiod', 'netlogond', - 'ntpd', 'sfcbd-watchdog', 'snmpd', 'vprobed', 'vpxa', 'xorg'] + service_instance = salt.utils.vmware.get_service_instance( + host=host, username=username, password=password, protocol=protocol, + port=port, verify_ssl=verify_ssl, + ) + valid_services = [ + 'DCUI', + 'TSM', + 'SSH', + 'ssh', + 'lbtd', + 'lsassd', + 'lwiod', + 'netlogond', + 'ntpd', + 'sfcbd-watchdog', + 'snmpd', + 'vprobed', + 'vpxa', + 'xorg', + ] host_names = _check_hosts(service_instance, host, host_names) ret = {} @@ -1786,7 +1844,10 @@ def get_service_running(host, username, password, service_name, protocol=None, p @depends(HAS_PYVMOMI) @ignores_kwargs('credstore') -def get_vmotion_enabled(host, username, password, protocol=None, port=None, host_names=None): +def get_vmotion_enabled( + host, username, password, protocol=None, port=None, host_names=None, + verify_ssl=True, +): ''' Get the VMotion enabled status for a given host or a list of host_names. Returns ``True`` if VMotion is enabled, ``False`` if it is not enabled. @@ -1817,6 +1878,9 @@ def get_vmotion_enabled(host, username, password, protocol=None, port=None, host ``host`` location instead. This is useful for when service instance connection information is used for a single ESXi host. + verify_ssl + Verify the SSL certificate. Default: True + CLI Example: .. code-block:: bash @@ -1828,11 +1892,10 @@ def get_vmotion_enabled(host, username, password, protocol=None, port=None, host salt '*' vsphere.get_vmotion_enabled my.vcenter.location root bad-password \ host_names='[esxi-1.host.com, esxi-2.host.com]' ''' - service_instance = salt.utils.vmware.get_service_instance(host=host, - username=username, - password=password, - protocol=protocol, - port=port) + service_instance = salt.utils.vmware.get_service_instance( + host=host, username=username, password=password, protocol=protocol, + port=port, verify_ssl=verify_ssl, + ) host_names = _check_hosts(service_instance, host, host_names) ret = {} for host_name in host_names: @@ -1848,7 +1911,10 @@ def get_vmotion_enabled(host, username, password, protocol=None, port=None, host @depends(HAS_PYVMOMI) @ignores_kwargs('credstore') -def get_vsan_enabled(host, username, password, protocol=None, port=None, host_names=None): +def get_vsan_enabled( + host, username, password, protocol=None, port=None, host_names=None, + verify_ssl=True, +): ''' Get the VSAN enabled status for a given host or a list of host_names. Returns ``True`` if VSAN is enabled, ``False`` if it is not enabled, and ``None`` if a VSAN Host Config @@ -1880,6 +1946,9 @@ def get_vsan_enabled(host, username, password, protocol=None, port=None, host_na ``host`` location instead. This is useful for when service instance connection information is used for a single ESXi host. + verify_ssl + Verify the SSL certificate. Default: True + CLI Example: .. code-block:: bash @@ -1891,11 +1960,10 @@ def get_vsan_enabled(host, username, password, protocol=None, port=None, host_na salt '*' vsphere.get_vsan_enabled my.vcenter.location root bad-password \ host_names='[esxi-1.host.com, esxi-2.host.com]' ''' - service_instance = salt.utils.vmware.get_service_instance(host=host, - username=username, - password=password, - protocol=protocol, - port=port) + service_instance = salt.utils.vmware.get_service_instance( + host=host, username=username, password=password, protocol=protocol, + port=port, verify_ssl=verify_ssl, + ) host_names = _check_hosts(service_instance, host, host_names) ret = {} for host_name in host_names: @@ -1915,7 +1983,10 @@ def get_vsan_enabled(host, username, password, protocol=None, port=None, host_na @depends(HAS_PYVMOMI) @ignores_kwargs('credstore') -def get_vsan_eligible_disks(host, username, password, protocol=None, port=None, host_names=None): +def get_vsan_eligible_disks( + host, username, password, protocol=None, port=None, host_names=None, + verify_ssl=True, +): ''' Returns a list of VSAN-eligible disks for a given host or list of host_names. @@ -1945,6 +2016,9 @@ def get_vsan_eligible_disks(host, username, password, protocol=None, port=None, for the ``host`` location instead. This is useful for when service instance connection information is used for a single ESXi host. + verify_ssl + Verify the SSL certificate. Default: True + CLI Example: .. code-block:: bash @@ -1956,11 +2030,10 @@ def get_vsan_eligible_disks(host, username, password, protocol=None, port=None, salt '*' vsphere.get_vsan_eligible_disks my.vcenter.location root bad-password \ host_names='[esxi-1.host.com, esxi-2.host.com]' ''' - service_instance = salt.utils.vmware.get_service_instance(host=host, - username=username, - password=password, - protocol=protocol, - port=port) + service_instance = salt.utils.vmware.get_service_instance( + host=host, username=username, password=password, protocol=protocol, + port=port, verify_ssl=verify_ssl, + ) host_names = _check_hosts(service_instance, host, host_names) response = _get_vsan_eligible_disks(service_instance, host, host_names) @@ -2011,7 +2084,8 @@ def test_vcenter_connection(service_instance=None): @depends(HAS_PYVMOMI) @ignores_kwargs('credstore') -def system_info(host, username, password, protocol=None, port=None): +def system_info(host, username, password, protocol=None, port=None, + verify_ssl=True,): ''' Return system information about a VMware environment. @@ -2032,17 +2106,19 @@ def system_info(host, username, password, protocol=None, port=None): Optionally set to alternate port if the host is not using the default port. Default port is ``443``. + verify_ssl + Verify the SSL certificate. Default: True + CLI Example: .. code-block:: bash salt '*' vsphere.system_info 1.2.3.4 root bad-password ''' - service_instance = salt.utils.vmware.get_service_instance(host=host, - username=username, - password=password, - protocol=protocol, - port=port) + service_instance = salt.utils.vmware.get_service_instance( + host=host, username=username, password=password, protocol=protocol, + port=port, verify_ssl=verify_ssl, + ) ret = salt.utils.vmware.get_inventory(service_instance).about.__dict__ if 'apiType' in ret: if ret['apiType'] == 'HostAgent': @@ -2052,9 +2128,10 @@ def system_info(host, username, password, protocol=None, port=None): @depends(HAS_PYVMOMI) @ignores_kwargs('credstore') -def list_datacenters(host, username, password, protocol=None, port=None): +def list_datacenters(host, username, password, protocol=None, port=None, + verify_ssl=True): ''' - Returns a list of datacenters for the the specified host. + Returns a list of datacenters for the specified host. host The location of the host. @@ -2073,6 +2150,9 @@ def list_datacenters(host, username, password, protocol=None, port=None): Optionally set to alternate port if the host is not using the default port. Default port is ``443``. + verify_ssl + Verify the SSL certificate. Default: True + CLI Example: .. code-block:: bash @@ -2080,19 +2160,19 @@ def list_datacenters(host, username, password, protocol=None, port=None): salt '*' vsphere.list_datacenters 1.2.3.4 root bad-password ''' - service_instance = salt.utils.vmware.get_service_instance(host=host, - username=username, - password=password, - protocol=protocol, - port=port) + service_instance = salt.utils.vmware.get_service_instance( + host=host, username=username, password=password, protocol=protocol, + port=port, verify_ssl=verify_ssl, + ) return salt.utils.vmware.list_datacenters(service_instance) @depends(HAS_PYVMOMI) @ignores_kwargs('credstore') -def list_clusters(host, username, password, protocol=None, port=None): +def list_clusters(host, username, password, protocol=None, port=None, + verify_ssl=True): ''' - Returns a list of clusters for the the specified host. + Returns a list of clusters for the specified host. host The location of the host. @@ -2111,6 +2191,9 @@ def list_clusters(host, username, password, protocol=None, port=None): Optionally set to alternate port if the host is not using the default port. Default port is ``443``. + verify_ssl + Verify the SSL certificate. Default: True + CLI Example: .. code-block:: bash @@ -2118,19 +2201,19 @@ def list_clusters(host, username, password, protocol=None, port=None): salt '*' vsphere.list_clusters 1.2.3.4 root bad-password ''' - service_instance = salt.utils.vmware.get_service_instance(host=host, - username=username, - password=password, - protocol=protocol, - port=port) + service_instance = salt.utils.vmware.get_service_instance( + host=host, username=username, password=password, protocol=protocol, + port=port, verify_ssl=verify_ssl, + ) return salt.utils.vmware.list_clusters(service_instance) @depends(HAS_PYVMOMI) @ignores_kwargs('credstore') -def list_datastore_clusters(host, username, password, protocol=None, port=None): +def list_datastore_clusters(host, username, password, protocol=None, port=None, + verify_ssl=True): ''' - Returns a list of datastore clusters for the the specified host. + Returns a list of datastore clusters for the specified host. host The location of the host. @@ -2149,25 +2232,28 @@ def list_datastore_clusters(host, username, password, protocol=None, port=None): Optionally set to alternate port if the host is not using the default port. Default port is ``443``. + verify_ssl + Verify the SSL certificate. Default: True + CLI Example: .. code-block:: bash salt '*' vsphere.list_datastore_clusters 1.2.3.4 root bad-password ''' - service_instance = salt.utils.vmware.get_service_instance(host=host, - username=username, - password=password, - protocol=protocol, - port=port) + service_instance = salt.utils.vmware.get_service_instance( + host=host, username=username, password=password, protocol=protocol, + port=port, verify_ssl=verify_ssl, + ) return salt.utils.vmware.list_datastore_clusters(service_instance) @depends(HAS_PYVMOMI) @ignores_kwargs('credstore') -def list_datastores(host, username, password, protocol=None, port=None): +def list_datastores(host, username, password, protocol=None, port=None, + verify_ssl=True): ''' - Returns a list of datastores for the the specified host. + Returns a list of datastores for the specified host. host The location of the host. @@ -2186,25 +2272,28 @@ def list_datastores(host, username, password, protocol=None, port=None): Optionally set to alternate port if the host is not using the default port. Default port is ``443``. + verify_ssl + Verify the SSL certificate. Default: True + CLI Example: .. code-block:: bash salt '*' vsphere.list_datastores 1.2.3.4 root bad-password ''' - service_instance = salt.utils.vmware.get_service_instance(host=host, - username=username, - password=password, - protocol=protocol, - port=port) + service_instance = salt.utils.vmware.get_service_instance( + host=host, username=username, password=password, protocol=protocol, + port=port, verify_ssl=verify_ssl, + ) return salt.utils.vmware.list_datastores(service_instance) @depends(HAS_PYVMOMI) @ignores_kwargs('credstore') -def list_hosts(host, username, password, protocol=None, port=None): +def list_hosts(host, username, password, protocol=None, port=None, + verify_ssl=True): ''' - Returns a list of hosts for the the specified VMware environment. + Returns a list of hosts for the specified VMware environment. host The location of the host. @@ -2223,25 +2312,28 @@ def list_hosts(host, username, password, protocol=None, port=None): Optionally set to alternate port if the host is not using the default port. Default port is ``443``. + verify_ssl + Verify the SSL certificate. Default: True + CLI Example: .. code-block:: bash salt '*' vsphere.list_hosts 1.2.3.4 root bad-password ''' - service_instance = salt.utils.vmware.get_service_instance(host=host, - username=username, - password=password, - protocol=protocol, - port=port) + service_instance = salt.utils.vmware.get_service_instance( + host=host, username=username, password=password, protocol=protocol, + port=port, verify_ssl=verify_ssl, + ) return salt.utils.vmware.list_hosts(service_instance) @depends(HAS_PYVMOMI) @ignores_kwargs('credstore') -def list_resourcepools(host, username, password, protocol=None, port=None): +def list_resourcepools(host, username, password, protocol=None, port=None, + verify_ssl=True): ''' - Returns a list of resource pools for the the specified host. + Returns a list of resource pools for the specified host. host The location of the host. @@ -2260,25 +2352,28 @@ def list_resourcepools(host, username, password, protocol=None, port=None): Optionally set to alternate port if the host is not using the default port. Default port is ``443``. + verify_ssl + Verify the SSL certificate. Default: True + CLI Example: .. code-block:: bash salt '*' vsphere.list_resourcepools 1.2.3.4 root bad-password ''' - service_instance = salt.utils.vmware.get_service_instance(host=host, - username=username, - password=password, - protocol=protocol, - port=port) + service_instance = salt.utils.vmware.get_service_instance( + host=host, username=username, password=password, protocol=protocol, + port=port, verify_ssl=verify_ssl, + ) return salt.utils.vmware.list_resourcepools(service_instance) @depends(HAS_PYVMOMI) @ignores_kwargs('credstore') -def list_networks(host, username, password, protocol=None, port=None): +def list_networks(host, username, password, protocol=None, port=None, + verify_ssl=True): ''' - Returns a list of networks for the the specified host. + Returns a list of networks for the specified host. host The location of the host. @@ -2297,25 +2392,28 @@ def list_networks(host, username, password, protocol=None, port=None): Optionally set to alternate port if the host is not using the default port. Default port is ``443``. + verify_ssl + Verify the SSL certificate. Default: True + CLI Example: .. code-block:: bash salt '*' vsphere.list_networks 1.2.3.4 root bad-password ''' - service_instance = salt.utils.vmware.get_service_instance(host=host, - username=username, - password=password, - protocol=protocol, - port=port) + service_instance = salt.utils.vmware.get_service_instance( + host=host, username=username, password=password, protocol=protocol, + port=port, verify_ssl=verify_ssl, + ) return salt.utils.vmware.list_networks(service_instance) @depends(HAS_PYVMOMI) @ignores_kwargs('credstore') -def list_vms(host, username, password, protocol=None, port=None): +def list_vms(host, username, password, protocol=None, port=None, + verify_ssl=True): ''' - Returns a list of VMs for the the specified host. + Returns a list of VMs for the specified host. host The location of the host. @@ -2334,25 +2432,28 @@ def list_vms(host, username, password, protocol=None, port=None): Optionally set to alternate port if the host is not using the default port. Default port is ``443``. + verify_ssl + Verify the SSL certificate. Default: True + CLI Example: .. code-block:: bash salt '*' vsphere.list_vms 1.2.3.4 root bad-password ''' - service_instance = salt.utils.vmware.get_service_instance(host=host, - username=username, - password=password, - protocol=protocol, - port=port) + service_instance = salt.utils.vmware.get_service_instance( + host=host, username=username, password=password, protocol=protocol, + port=port, verify_ssl=verify_ssl, + ) return salt.utils.vmware.list_vms(service_instance) @depends(HAS_PYVMOMI) @ignores_kwargs('credstore') -def list_folders(host, username, password, protocol=None, port=None): +def list_folders(host, username, password, protocol=None, port=None, + verify_ssl=True): ''' - Returns a list of folders for the the specified host. + Returns a list of folders for the specified host. host The location of the host. @@ -2371,25 +2472,28 @@ def list_folders(host, username, password, protocol=None, port=None): Optionally set to alternate port if the host is not using the default port. Default port is ``443``. + verify_ssl + Verify the SSL certificate. Default: True + CLI Example: .. code-block:: bash salt '*' vsphere.list_folders 1.2.3.4 root bad-password ''' - service_instance = salt.utils.vmware.get_service_instance(host=host, - username=username, - password=password, - protocol=protocol, - port=port) + service_instance = salt.utils.vmware.get_service_instance( + host=host, username=username, password=password, protocol=protocol, + port=port, verify_ssl=verify_ssl, + ) return salt.utils.vmware.list_folders(service_instance) @depends(HAS_PYVMOMI) @ignores_kwargs('credstore') -def list_dvs(host, username, password, protocol=None, port=None): +def list_dvs(host, username, password, protocol=None, port=None, + verify_ssl=True): ''' - Returns a list of distributed virtual switches for the the specified host. + Returns a list of distributed virtual switches for the specified host. host The location of the host. @@ -2408,25 +2512,28 @@ def list_dvs(host, username, password, protocol=None, port=None): Optionally set to alternate port if the host is not using the default port. Default port is ``443``. + verify_ssl + Verify the SSL certificate. Default: True + CLI Example: .. code-block:: bash salt '*' vsphere.list_dvs 1.2.3.4 root bad-password ''' - service_instance = salt.utils.vmware.get_service_instance(host=host, - username=username, - password=password, - protocol=protocol, - port=port) + service_instance = salt.utils.vmware.get_service_instance( + host=host, username=username, password=password, protocol=protocol, + port=port, verify_ssl=verify_ssl, + ) return salt.utils.vmware.list_dvs(service_instance) @depends(HAS_PYVMOMI) @ignores_kwargs('credstore') -def list_vapps(host, username, password, protocol=None, port=None): +def list_vapps(host, username, password, protocol=None, port=None, + verify_ssl=True): ''' - Returns a list of vApps for the the specified host. + Returns a list of vApps for the specified host. host The location of the host. @@ -2445,6 +2552,9 @@ def list_vapps(host, username, password, protocol=None, port=None): Optionally set to alternate port if the host is not using the default port. Default port is ``443``. + verify_ssl + Verify the SSL certificate. Default: True + CLI Example: .. code-block:: bash @@ -2452,17 +2562,17 @@ def list_vapps(host, username, password, protocol=None, port=None): # List vapps from all minions salt '*' vsphere.list_vapps 1.2.3.4 root bad-password ''' - service_instance = salt.utils.vmware.get_service_instance(host=host, - username=username, - password=password, - protocol=protocol, - port=port) + service_instance = salt.utils.vmware.get_service_instance( + host=host, username=username, password=password, protocol=protocol, + port=port, verify_ssl=verify_ssl, + ) return salt.utils.vmware.list_vapps(service_instance) @depends(HAS_PYVMOMI) @ignores_kwargs('credstore') -def list_ssds(host, username, password, protocol=None, port=None, host_names=None): +def list_ssds(host, username, password, protocol=None, port=None, + host_names=None, verify_ssl=True): ''' Returns a list of SSDs for the given host or list of host_names. @@ -2492,6 +2602,9 @@ def list_ssds(host, username, password, protocol=None, port=None, host_names=Non ``host`` location instead. This is useful for when service instance connection information is used for a single ESXi host. + verify_ssl + Verify the SSL certificate. Default: True + CLI Example: .. code-block:: bash @@ -2503,11 +2616,10 @@ def list_ssds(host, username, password, protocol=None, port=None, host_names=Non salt '*' vsphere.list_ssds my.vcenter.location root bad-password \ host_names='[esxi-1.host.com, esxi-2.host.com]' ''' - service_instance = salt.utils.vmware.get_service_instance(host=host, - username=username, - password=password, - protocol=protocol, - port=port) + service_instance = salt.utils.vmware.get_service_instance( + host=host, username=username, password=password, protocol=protocol, + port=port, verify_ssl=verify_ssl, + ) host_names = _check_hosts(service_instance, host, host_names) ret = {} names = [] @@ -2523,7 +2635,8 @@ def list_ssds(host, username, password, protocol=None, port=None, host_names=Non @depends(HAS_PYVMOMI) @ignores_kwargs('credstore') -def list_non_ssds(host, username, password, protocol=None, port=None, host_names=None): +def list_non_ssds(host, username, password, protocol=None, port=None, + host_names=None, verify_ssl=True): ''' Returns a list of Non-SSD disks for the given host or list of host_names. @@ -2560,6 +2673,9 @@ def list_non_ssds(host, username, password, protocol=None, port=None, host_names ``host`` location instead. This is useful for when service instance connection information is used for a single ESXi host. + verify_ssl + Verify the SSL certificate. Default: True + CLI Example: .. code-block:: bash @@ -2571,11 +2687,10 @@ def list_non_ssds(host, username, password, protocol=None, port=None, host_names salt '*' vsphere.list_non_ssds my.vcenter.location root bad-password \ host_names='[esxi-1.host.com, esxi-2.host.com]' ''' - service_instance = salt.utils.vmware.get_service_instance(host=host, - username=username, - password=password, - protocol=protocol, - port=port) + service_instance = salt.utils.vmware.get_service_instance( + host=host, username=username, password=password, protocol=protocol, + port=port, verify_ssl=verify_ssl, + ) host_names = _check_hosts(service_instance, host, host_names) ret = {} names = [] @@ -2591,7 +2706,10 @@ def list_non_ssds(host, username, password, protocol=None, port=None, host_names @depends(HAS_PYVMOMI) @ignores_kwargs('credstore') -def set_ntp_config(host, username, password, ntp_servers, protocol=None, port=None, host_names=None): +def set_ntp_config( + host, username, password, ntp_servers, protocol=None, port=None, + host_names=None, verify_ssl=True +): ''' Set NTP configuration for a given host of list of host_names. @@ -2625,6 +2743,9 @@ def set_ntp_config(host, username, password, ntp_servers, protocol=None, port=No ``host`` location instead. This is useful for when service instance connection information is used for a single ESXi host. + verify_ssl + Verify the SSL certificate. Default: True + CLI Example: .. code-block:: bash @@ -2636,11 +2757,10 @@ def set_ntp_config(host, username, password, ntp_servers, protocol=None, port=No salt '*' vsphere.ntp_configure my.vcenter.location root bad-password '[192.174.1.100, 192.174.1.200]' \ host_names='[esxi-1.host.com, esxi-2.host.com]' ''' - service_instance = salt.utils.vmware.get_service_instance(host=host, - username=username, - password=password, - protocol=protocol, - port=port) + service_instance = salt.utils.vmware.get_service_instance( + host=host, username=username, password=password, protocol=protocol, + port=port, verify_ssl=verify_ssl, + ) if not isinstance(ntp_servers, list): raise CommandExecutionError('\'ntp_servers\' must be a list.') @@ -2671,13 +2791,10 @@ def set_ntp_config(host, username, password, ntp_servers, protocol=None, port=No @depends(HAS_PYVMOMI) @ignores_kwargs('credstore') -def service_start(host, - username, - password, - service_name, - protocol=None, - port=None, - host_names=None): +def service_start( + host, username, password, service_name, protocol=None, port=None, + host_names=None, verify_ssl=True +): ''' Start the named service for the given host or list of hosts. @@ -2723,6 +2840,9 @@ def service_start(host, location instead. This is useful for when service instance connection information is used for a single ESXi host. + verify_ssl + Verify the SSL certificate. Default: True + CLI Example: .. code-block:: bash @@ -2734,11 +2854,10 @@ def service_start(host, salt '*' vsphere.service_start my.vcenter.location root bad-password 'ntpd' \ host_names='[esxi-1.host.com, esxi-2.host.com]' ''' - service_instance = salt.utils.vmware.get_service_instance(host=host, - username=username, - password=password, - protocol=protocol, - port=port) + service_instance = salt.utils.vmware.get_service_instance( + host=host, username=username, password=password, protocol=protocol, + port=port, verify_ssl=verify_ssl, + ) host_names = _check_hosts(service_instance, host, host_names) valid_services = ['DCUI', 'TSM', 'SSH', 'ssh', 'lbtd', 'lsassd', 'lwiod', 'netlogond', 'ntpd', 'sfcbd-watchdog', 'snmpd', 'vprobed', 'vpxa', 'xorg'] @@ -2782,13 +2901,10 @@ def service_start(host, @depends(HAS_PYVMOMI) @ignores_kwargs('credstore') -def service_stop(host, - username, - password, - service_name, - protocol=None, - port=None, - host_names=None): +def service_stop( + host, username, password, service_name, protocol=None, port=None, + host_names=None, verify_ssl=True, +): ''' Stop the named service for the given host or list of hosts. @@ -2834,6 +2950,9 @@ def service_stop(host, location instead. This is useful for when service instance connection information is used for a single ESXi host. + verify_ssl + Verify the SSL certificate. Default: True + CLI Example: .. code-block:: bash @@ -2845,11 +2964,10 @@ def service_stop(host, salt '*' vsphere.service_stop my.vcenter.location root bad-password 'ssh' \ host_names='[esxi-1.host.com, esxi-2.host.com]' ''' - service_instance = salt.utils.vmware.get_service_instance(host=host, - username=username, - password=password, - protocol=protocol, - port=port) + service_instance = salt.utils.vmware.get_service_instance( + host=host, username=username, password=password, protocol=protocol, + port=port, verify_ssl=verify_ssl, + ) host_names = _check_hosts(service_instance, host, host_names) valid_services = ['DCUI', 'TSM', 'SSH', 'ssh', 'lbtd', 'lsassd', 'lwiod', 'netlogond', 'ntpd', 'sfcbd-watchdog', 'snmpd', 'vprobed', 'vpxa', 'xorg'] @@ -2893,13 +3011,10 @@ def service_stop(host, @depends(HAS_PYVMOMI) @ignores_kwargs('credstore') -def service_restart(host, - username, - password, - service_name, - protocol=None, - port=None, - host_names=None): +def service_restart( + host, username, password, service_name, protocol=None, port=None, + host_names=None, verify_ssl=True, +): ''' Restart the named service for the given host or list of hosts. @@ -2945,6 +3060,9 @@ def service_restart(host, location instead. This is useful for when service instance connection information is used for a single ESXi host. + verify_ssl + Verify the SSL certificate. Default: True + CLI Example: .. code-block:: bash @@ -2956,11 +3074,10 @@ def service_restart(host, salt '*' vsphere.service_restart my.vcenter.location root bad-password 'ntpd' \ host_names='[esxi-1.host.com, esxi-2.host.com]' ''' - service_instance = salt.utils.vmware.get_service_instance(host=host, - username=username, - password=password, - protocol=protocol, - port=port) + service_instance = salt.utils.vmware.get_service_instance( + host=host, username=username, password=password, protocol=protocol, + port=port, verify_ssl=verify_ssl, + ) host_names = _check_hosts(service_instance, host, host_names) valid_services = ['DCUI', 'TSM', 'SSH', 'ssh', 'lbtd', 'lsassd', 'lwiod', 'netlogond', 'ntpd', 'sfcbd-watchdog', 'snmpd', 'vprobed', 'vpxa', 'xorg'] @@ -3004,14 +3121,17 @@ def service_restart(host, @depends(HAS_PYVMOMI) @ignores_kwargs('credstore') -def set_service_policy(host, - username, - password, - service_name, - service_policy, - protocol=None, - port=None, - host_names=None): +def set_service_policy( + host, + username, + password, + service_name, + service_policy, + protocol=None, + port=None, + host_names=None, + verify_ssl=True +): ''' Set the service name's policy for a given host or list of hosts. @@ -3060,6 +3180,9 @@ def set_service_policy(host, for the ``host`` location instead. This is useful for when service instance connection information is used for a single ESXi host. + verify_ssl + Verify the SSL certificate. Default: True + CLI Example: .. code-block:: bash @@ -3071,11 +3194,10 @@ def set_service_policy(host, salt '*' vsphere.set_service_policy my.vcenter.location root bad-password 'ntpd' 'automatic' \ host_names='[esxi-1.host.com, esxi-2.host.com]' ''' - service_instance = salt.utils.vmware.get_service_instance(host=host, - username=username, - password=password, - protocol=protocol, - port=port) + service_instance = salt.utils.vmware.get_service_instance( + host=host, username=username, password=password, protocol=protocol, + port=port, verify_ssl=verify_ssl, + ) host_names = _check_hosts(service_instance, host, host_names) valid_services = ['DCUI', 'TSM', 'SSH', 'ssh', 'lbtd', 'lsassd', 'lwiod', 'netlogond', 'ntpd', 'sfcbd-watchdog', 'snmpd', 'vprobed', 'vpxa', 'xorg'] @@ -3133,7 +3255,10 @@ def set_service_policy(host, @depends(HAS_PYVMOMI) @ignores_kwargs('credstore') -def update_host_datetime(host, username, password, protocol=None, port=None, host_names=None): +def update_host_datetime( + host, username, password, protocol=None, port=None, host_names=None, + verify_ssl=True +): ''' Update the date/time on the given host or list of host_names. This function should be used with caution since network delays and execution delays can result in time skews. @@ -3164,6 +3289,9 @@ def update_host_datetime(host, username, password, protocol=None, port=None, hos location instead. This is useful for when service instance connection information is used for a single ESXi host. + verify_ssl + Verify the SSL certificate. Default: True + CLI Example: .. code-block:: bash @@ -3175,11 +3303,10 @@ def update_host_datetime(host, username, password, protocol=None, port=None, hos salt '*' vsphere.update_date_time my.vcenter.location root bad-password \ host_names='[esxi-1.host.com, esxi-2.host.com]' ''' - service_instance = salt.utils.vmware.get_service_instance(host=host, - username=username, - password=password, - protocol=protocol, - port=port) + service_instance = salt.utils.vmware.get_service_instance( + host=host, username=username, password=password, protocol=protocol, + port=port, verify_ssl=verify_ssl, + ) host_names = _check_hosts(service_instance, host, host_names) ret = {} for host_name in host_names: @@ -3200,7 +3327,10 @@ def update_host_datetime(host, username, password, protocol=None, port=None, hos @depends(HAS_PYVMOMI) @ignores_kwargs('credstore') -def update_host_password(host, username, password, new_password, protocol=None, port=None): +def update_host_password( + host, username, password, new_password, protocol=None, port=None, + verify_ssl=True +): ''' Update the password for a given host. @@ -3226,6 +3356,9 @@ def update_host_password(host, username, password, new_password, protocol=None, Optionally set to alternate port if the host is not using the default port. Default port is ``443``. + verify_ssl + Verify the SSL certificate. Default: True + CLI Example: .. code-block:: bash @@ -3233,11 +3366,10 @@ def update_host_password(host, username, password, new_password, protocol=None, salt '*' vsphere.update_host_password my.esxi.host root original-bad-password new-bad-password ''' - service_instance = salt.utils.vmware.get_service_instance(host=host, - username=username, - password=password, - protocol=protocol, - port=port) + service_instance = salt.utils.vmware.get_service_instance( + host=host, username=username, password=password, protocol=protocol, + port=port, verify_ssl=verify_ssl, + ) # Get LocalAccountManager object account_manager = salt.utils.vmware.get_inventory(service_instance).accountManager @@ -3263,7 +3395,10 @@ def update_host_password(host, username, password, new_password, protocol=None, @depends(HAS_PYVMOMI) @ignores_kwargs('credstore') -def vmotion_disable(host, username, password, protocol=None, port=None, host_names=None): +def vmotion_disable( + host, username, password, protocol=None, port=None, host_names=None, + verify_ssl=True +): ''' Disable vMotion for a given host or list of host_names. @@ -3293,6 +3428,9 @@ def vmotion_disable(host, username, password, protocol=None, port=None, host_nam location instead. This is useful for when service instance connection information is used for a single ESXi host. + verify_ssl + Verify the SSL certificate. Default: True + CLI Example: .. code-block:: bash @@ -3304,11 +3442,10 @@ def vmotion_disable(host, username, password, protocol=None, port=None, host_nam salt '*' vsphere.vmotion_disable my.vcenter.location root bad-password \ host_names='[esxi-1.host.com, esxi-2.host.com]' ''' - service_instance = salt.utils.vmware.get_service_instance(host=host, - username=username, - password=password, - protocol=protocol, - port=port) + service_instance = salt.utils.vmware.get_service_instance( + host=host, username=username, password=password, protocol=protocol, + port=port, verify_ssl=verify_ssl, + ) host_names = _check_hosts(service_instance, host, host_names) ret = {} for host_name in host_names: @@ -3332,7 +3469,10 @@ def vmotion_disable(host, username, password, protocol=None, port=None, host_nam @depends(HAS_PYVMOMI) @ignores_kwargs('credstore') -def vmotion_enable(host, username, password, protocol=None, port=None, host_names=None, device='vmk0'): +def vmotion_enable( + host, username, password, protocol=None, port=None, host_names=None, + device='vmk0', verify_ssl=True +): ''' Enable vMotion for a given host or list of host_names. @@ -3366,6 +3506,9 @@ def vmotion_enable(host, username, password, protocol=None, port=None, host_name The device that uniquely identifies the VirtualNic that will be used for VMotion for each host. Defaults to ``vmk0``. + verify_ssl + Verify the SSL certificate. Default: True + CLI Example: .. code-block:: bash @@ -3377,11 +3520,10 @@ def vmotion_enable(host, username, password, protocol=None, port=None, host_name salt '*' vsphere.vmotion_enable my.vcenter.location root bad-password \ host_names='[esxi-1.host.com, esxi-2.host.com]' ''' - service_instance = salt.utils.vmware.get_service_instance(host=host, - username=username, - password=password, - protocol=protocol, - port=port) + service_instance = salt.utils.vmware.get_service_instance( + host=host, username=username, password=password, protocol=protocol, + port=port, verify_ssl=verify_ssl, + ) host_names = _check_hosts(service_instance, host, host_names) ret = {} for host_name in host_names: @@ -3405,7 +3547,8 @@ def vmotion_enable(host, username, password, protocol=None, port=None, host_name @depends(HAS_PYVMOMI) @ignores_kwargs('credstore') -def vsan_add_disks(host, username, password, protocol=None, port=None, host_names=None): +def vsan_add_disks(host, username, password, protocol=None, port=None, + host_names=None, verify_ssl=True): ''' Add any VSAN-eligible disks to the VSAN System for the given host or list of host_names. @@ -3436,6 +3579,9 @@ def vsan_add_disks(host, username, password, protocol=None, port=None, host_name VSAN system for the ``host`` location instead. This is useful for when service instance connection information is used for a single ESXi host. + verify_ssl + Verify the SSL certificate. Default: True + CLI Example: .. code-block:: bash @@ -3447,11 +3593,10 @@ def vsan_add_disks(host, username, password, protocol=None, port=None, host_name salt '*' vsphere.vsan_add_disks my.vcenter.location root bad-password \ host_names='[esxi-1.host.com, esxi-2.host.com]' ''' - service_instance = salt.utils.vmware.get_service_instance(host=host, - username=username, - password=password, - protocol=protocol, - port=port) + service_instance = salt.utils.vmware.get_service_instance( + host=host, username=username, password=password, protocol=protocol, + port=port, verify_ssl=verify_ssl, + ) host_names = _check_hosts(service_instance, host, host_names) response = _get_vsan_eligible_disks(service_instance, host, host_names) @@ -3509,7 +3654,8 @@ def vsan_add_disks(host, username, password, protocol=None, port=None, host_name @depends(HAS_PYVMOMI) @ignores_kwargs('credstore') -def vsan_disable(host, username, password, protocol=None, port=None, host_names=None): +def vsan_disable(host, username, password, protocol=None, port=None, + host_names=None, verify_ssl=True): ''' Disable VSAN for a given host or list of host_names. @@ -3539,6 +3685,9 @@ def vsan_disable(host, username, password, protocol=None, port=None, host_names= location instead. This is useful for when service instance connection information is used for a single ESXi host. + verify_ssl + Verify the SSL certificate. Default: True + CLI Example: .. code-block:: bash @@ -3550,11 +3699,10 @@ def vsan_disable(host, username, password, protocol=None, port=None, host_names= salt '*' vsphere.vsan_disable my.vcenter.location root bad-password \ host_names='[esxi-1.host.com, esxi-2.host.com]' ''' - service_instance = salt.utils.vmware.get_service_instance(host=host, - username=username, - password=password, - protocol=protocol, - port=port) + service_instance = salt.utils.vmware.get_service_instance( + host=host, username=username, password=password, protocol=protocol, + port=port, verify_ssl=verify_ssl, + ) # Create a VSAN Configuration Object and set the enabled attribute to True vsan_config = vim.vsan.host.ConfigInfo() vsan_config.enabled = False @@ -3594,7 +3742,8 @@ def vsan_disable(host, username, password, protocol=None, port=None, host_names= @depends(HAS_PYVMOMI) @ignores_kwargs('credstore') -def vsan_enable(host, username, password, protocol=None, port=None, host_names=None): +def vsan_enable(host, username, password, protocol=None, port=None, + host_names=None, verify_ssl=True): ''' Enable VSAN for a given host or list of host_names. @@ -3624,6 +3773,9 @@ def vsan_enable(host, username, password, protocol=None, port=None, host_names=N location instead. This is useful for when service instance connection information is used for a single ESXi host. + verify_ssl + Verify the SSL certificate. Default: True + CLI Example: .. code-block:: bash @@ -3635,11 +3787,10 @@ def vsan_enable(host, username, password, protocol=None, port=None, host_names=N salt '*' vsphere.vsan_enable my.vcenter.location root bad-password \ host_names='[esxi-1.host.com, esxi-2.host.com]' ''' - service_instance = salt.utils.vmware.get_service_instance(host=host, - username=username, - password=password, - protocol=protocol, - port=port) + service_instance = salt.utils.vmware.get_service_instance( + host=host, username=username, password=password, protocol=protocol, + port=port, verify_ssl=verify_ssl, + ) # Create a VSAN Configuration Object and set the enabled attribute to True vsan_config = vim.vsan.host.ConfigInfo() vsan_config.enabled = True @@ -4866,7 +5017,7 @@ def create_storage_policy(policy_name, policy_dict, service_instance=None): .. code-block:: bash salt '*' vsphere.create_storage_policy policy_name='policy name' - policy_dict="$policy_dict" + policy_dict='$policy_dict' ''' log.trace('create storage policy \'{0}\', dict = {1}' ''.format(policy_name, policy_dict)) @@ -4906,7 +5057,7 @@ def update_storage_policy(policy, policy_dict, service_instance=None): .. code-block:: bash salt '*' vsphere.update_storage_policy policy='policy name' - policy_dict="$policy_dict" + policy_dict='$policy_dict' ''' log.trace('updating storage policy, dict = {0}'.format(policy_dict)) profile_manager = salt.utils.pbm.get_profile_manager(service_instance) @@ -6855,9 +7006,20 @@ def _set_syslog_config_helper(host, username, password, syslog_config, config_va @depends(HAS_PYVMOMI) @ignores_kwargs('credstore') -def add_host_to_dvs(host, username, password, vmknic_name, vmnic_name, - dvs_name, target_portgroup_name, uplink_portgroup_name, - protocol=None, port=None, host_names=None): +def add_host_to_dvs( + host, + username, + password, + vmknic_name, + vmnic_name, + dvs_name, + target_portgroup_name, + uplink_portgroup_name, + protocol=None, + port=None, + host_names=None, + verify_ssl=True, +): ''' Adds an ESXi host to a vSphere Distributed Virtual Switch and migrates the desired adapters to the DVS from the standard switch. @@ -6899,6 +7061,9 @@ def add_host_to_dvs(host, username, password, vmknic_name, vmnic_name, host_names: An array of VMware host names to migrate + verify_ssl + Verify the SSL certificate. Default: True + CLI Example: .. code-block:: bash @@ -6907,7 +7072,7 @@ def add_host_to_dvs(host, username, password, vmknic_name, vmnic_name, username='administrator@vsphere.corp.com' password='vsphere_password' vmknic_name='vmk0' vmnic_name='vnmic0' dvs_name='DSwitch' target_portgroup_name='DPortGroup' uplink_portgroup_name='DSwitch1-DVUplinks-181' - protocol='https' port='443', host_names="['esxi1.corp.com','esxi2.corp.com','esxi3.corp.com']" + protocol='https' port='443', host_names='['esxi1.corp.com','esxi2.corp.com','esxi3.corp.com']' Return Example: @@ -6970,7 +7135,7 @@ def add_host_to_dvs(host, username, password, vmknic_name, vmnic_name, says to create the DVS, create distributed portgroups, and then add the host to the DVS specifying which physical NIC to use as the port backing. However, if the physical NIC is in use as the only link from the host - to vSphere, this will fail with an unhelpful "busy" error. + to vSphere, this will fail with an unhelpful 'busy' error. There is, however, a Powershell PowerCLI cmdlet called Add-VDSwitchPhysicalNetworkAdapter that does what we want. I used Onyx (https://labs.vmware.com/flings/onyx) @@ -6979,8 +7144,8 @@ def add_host_to_dvs(host, username, password, vmknic_name, vmnic_name, .. code-block:: xml - <UpdateNetworkConfig xmlns="urn:vim25"> - <_this type="HostNetworkSystem">networkSystem-187</_this> + <UpdateNetworkConfig xmlns='urn:vim25'> + <_this type='HostNetworkSystem'>networkSystem-187</_this> <config> <vswitch> <changeOperation>edit</changeOperation> @@ -6993,7 +7158,7 @@ def add_host_to_dvs(host, username, password, vmknic_name, vmnic_name, <changeOperation>edit</changeOperation> <uuid>73 a4 05 50 b0 d2 7e b9-38 80 5d 24 65 8f da 70</uuid> <spec> - <backing xsi:type="DistributedVirtualSwitchHostMemberPnicBacking"> + <backing xsi:type='DistributedVirtualSwitchHostMemberPnicBacking'> <pnicSpec><pnicDevice>vmnic0</pnicDevice></pnicSpec> </backing> </spec> @@ -7025,11 +7190,10 @@ def add_host_to_dvs(host, username, password, vmknic_name, vmnic_name, ret = {} ret['success'] = True ret['message'] = [] - service_instance = salt.utils.vmware.get_service_instance(host=host, - username=username, - password=password, - protocol=protocol, - port=port) + service_instance = salt.utils.vmware.get_service_instance( + host=host, username=username, password=password, protocol=protocol, + port=port, verify_ssl=verify_ssl, + ) dvs = salt.utils.vmware._get_dvs(service_instance, dvs_name) if not dvs: ret['message'].append('No Distributed Virtual Switch found with name {0}'.format(dvs_name)) @@ -7729,7 +7893,7 @@ def _create_adapter_type(network_adapter, adapter_type, log.trace('Changing type of \'{0}\' from' ' \'{1}\' to \'{2}\''.format( network_adapter.deviceInfo.label, - type(network_adapter).__name__.rsplit(".", 1)[1][7:].lower(), + type(network_adapter).__name__.rsplit('.', 1)[1][7:].lower(), adapter_type)) else: # If device is edited and type not specified or does not match, @@ -8100,12 +8264,12 @@ def _apply_cd_drive(drive_label, key, device_type, operation, .. code-block:: bash cd: - adapter: "CD/DVD drive 1" + adapter: 'CD/DVD drive 1' device_type: datastore_iso_file or client_device client_device: mode: atapi or passthrough datastore_iso_file: - path: "[share] iso/disk.iso" + path: '[share] iso/disk.iso' connectable: start_connected: True allow_guest_control: @@ -9091,7 +9255,7 @@ def _delete_device(device): return device_spec -def _get_client(server, username, password): +def _get_client(server, username, password, verify_ssl=None, ca_bundle=None): ''' Establish client through proxy or with user provided credentials. @@ -9101,12 +9265,17 @@ def _get_client(server, username, password): Username associated with the vCenter center. :param basestring password: Password associated with the vCenter center. + :param boolean verify_ssl: + Verify the SSL certificate. Default: True + :param basestring ca_bundle: + Path to the ca bundle to use when verifying SSL certificates. :returns: vSphere Client instance. :rtype: vSphere.Client ''' # Get salted vSphere Client + details = None if not (server and username and password): # User didn't provide CLI args so use proxy information details = __salt__['vcenter.get_details']() @@ -9114,10 +9283,30 @@ def _get_client(server, username, password): username = details['username'] password = details['password'] + if verify_ssl is None: + if details is None: + details = __salt__['vcenter.get_details']() + verify_ssl = details.get('verify_ssl', True) + if verify_ssl is None: + verify_ssl = True + + if ca_bundle is None: + if details is None: + details = __salt__['vcenter.get_details']() + ca_bundle = details.get('ca_bundle', None) + + if verify_ssl is False and ca_bundle is not None: + log.error('Cannot set verify_ssl to False and ca_bundle together') + return False + + if ca_bundle: + ca_bundle = salt.utils.http.get_ca_bundle({'ca_bundle': ca_bundle}) + # Establish connection with client - client = salt.utils.vmware.get_vsphere_client(server=server, - username=username, - password=password) + client = salt.utils.vmware.get_vsphere_client( + server=server, username=username, password=password, + verify_ssl=verify_ssl, ca_bundle=ca_bundle, + ) # Will return None if utility function causes Unauthenticated error return client @@ -9125,8 +9314,10 @@ def _get_client(server, username, password): @depends(HAS_PYVMOMI, HAS_VSPHERE_SDK) @supports_proxies('vcenter') @gets_service_instance_via_proxy -def list_tag_categories(server=None, username=None, password=None, - service_instance=None): +def list_tag_categories( + server=None, username=None, password=None, service_instance=None, + verify_ssl=None, ca_bundle=None +): ''' List existing categories a user has access to. @@ -9142,13 +9333,18 @@ def list_tag_categories(server=None, username=None, password=None, Username associated with the vCenter center. :param basestring password: Password associated with the vCenter center. + :param boolean verify_ssl: + Verify the SSL certificate. Default: True + :param basestring ca_bundle: + Path to the ca bundle to use when verifying SSL certificates. :returns: Value(s) of category_id. :rtype: list of str ''' categories = None - client = _get_client(server, username, password) + client = _get_client(server, username, password, verify_ssl=verify_ssl, + ca_bundle=ca_bundle) if client: categories = client.tagging.Category.list() @@ -9158,8 +9354,8 @@ def list_tag_categories(server=None, username=None, password=None, @depends(HAS_PYVMOMI, HAS_VSPHERE_SDK) @supports_proxies('vcenter') @gets_service_instance_via_proxy -def list_tags(server=None, username=None, password=None, - service_instance=None): +def list_tags(server=None, username=None, password=None, service_instance=None, + verify_ssl=None, ca_bundle=None): ''' List existing tags a user has access to. @@ -9175,13 +9371,18 @@ def list_tags(server=None, username=None, password=None, Username associated with the vCenter center. :param basestring password: Password associated with the vCenter center. + :param boolean verify_ssl: + Verify the SSL certificate. Default: True + :param basestring ca_bundle: + Path to the ca bundle to use when verifying SSL certificates. :return: Value(s) of tag_id. :rtype: list of str ''' tags = None - client = _get_client(server, username, password) + client = _get_client(server, username, password, verify_ssl=verify_ssl, + ca_bundle=ca_bundle) if client: tags = client.tagging.Tag.list() @@ -9191,10 +9392,17 @@ def list_tags(server=None, username=None, password=None, @depends(HAS_PYVMOMI, HAS_VSPHERE_SDK) @supports_proxies('vcenter') @gets_service_instance_via_proxy -def attach_tag(object_id, tag_id, - managed_obj='ClusterComputeResource', - server=None, username=None, password=None, - service_instance=None): +def attach_tag( + object_id, + tag_id, + managed_obj='ClusterComputeResource', + server=None, + username=None, + password=None, + service_instance=None, + verify_ssl=None, + ca_bundle=None, +): ''' Attach an existing tag to an input object. @@ -9226,6 +9434,10 @@ def attach_tag(object_id, tag_id, Username associated with the vCenter center. :param basestring password: Password associated with the vCenter center. + :param boolean verify_ssl: + Verify the SSL certificate. Default: True + :param basestring ca_bundle: + Path to the ca bundle to use when verifying SSL certificates. :return: The list of all tag identifiers that correspond to the tags attached to the given object. @@ -9237,7 +9449,8 @@ def attach_tag(object_id, tag_id, if the user can not be authenticated. ''' tag_attached = None - client = _get_client(server, username, password) + client = _get_client(server, username, password, verify_ssl=verify_ssl, + ca_bundle=ca_bundle) if client: # Create dynamic id object associated with a type and an id. @@ -9260,10 +9473,16 @@ def attach_tag(object_id, tag_id, @depends(HAS_PYVMOMI, HAS_VSPHERE_SDK) @supports_proxies('vcenter') @gets_service_instance_via_proxy -def list_attached_tags(object_id, - managed_obj='ClusterComputeResource', - server=None, username=None, password=None, - service_instance=None): +def list_attached_tags( + object_id, + managed_obj='ClusterComputeResource', + server=None, + username=None, + password=None, + service_instance=None, + verify_ssl=None, + ca_bundle=None, +): ''' List existing tags a user has access to. @@ -9285,6 +9504,10 @@ def list_attached_tags(object_id, Username associated with the vCenter center. :param basestring password: Password associated with the vCenter center. + :param boolean verify_ssl: + Verify the SSL certificate. Default: True + :param basestring ca_bundle: + Path to the ca bundle to use when verifying SSL certificates. :return: The list of all tag identifiers that correspond to the tags attached to the given object. @@ -9296,7 +9519,8 @@ def list_attached_tags(object_id, if the user can not be authenticated. ''' attached_tags = None - client = _get_client(server, username, password) + client = _get_client(server, username, password, verify_ssl=verify_ssl, + ca_bundle=ca_bundle) if client: # Create dynamic id object associated with a type and an id. @@ -9319,9 +9543,17 @@ def list_attached_tags(object_id, @depends(HAS_PYVMOMI, HAS_VSPHERE_SDK) @supports_proxies('vcenter') @gets_service_instance_via_proxy -def create_tag_category(name, description, cardinality, - server=None, username=None, password=None, - service_instance=None): +def create_tag_category( + name, + description, + cardinality, + server=None, + username=None, + password=None, + service_instance=None, + verify_ssl=None, + ca_bundle=None, +): ''' Create a category with given cardinality. @@ -9343,6 +9575,10 @@ def create_tag_category(name, description, cardinality, Username associated with the vCenter center. :param basestring password: Password associated with the vCenter center. + :param boolean verify_ssl: + Verify the SSL certificate. Default: True + :param basestring ca_bundle: + Path to the ca bundle to use when verifying SSL certificates. :return: Identifier of the created category. :rtype: @@ -9356,7 +9592,8 @@ def create_tag_category(name, description, cardinality, if you do not have the privilege to create a category. ''' category_created = None - client = _get_client(server, username, password) + client = _get_client(server, username, password, verify_ssl=verify_ssl, + ca_bundle=ca_bundle) if client: if cardinality == 'SINGLE': @@ -9384,9 +9621,10 @@ def create_tag_category(name, description, cardinality, @depends(HAS_PYVMOMI, HAS_VSPHERE_SDK) @supports_proxies('vcenter') @gets_service_instance_via_proxy -def delete_tag_category(category_id, - server=None, username=None, password=None, - service_instance=None): +def delete_tag_category( + category_id, server=None, username=None, password=None, + service_instance=None, verify_ssl=None, ca_bundle=None +): ''' Delete a category. @@ -9406,6 +9644,10 @@ def delete_tag_category(category_id, Username associated with the vCenter center. :param basestring password: Password associated with the vCenter center. + :param boolean verify_ssl: + Verify the SSL certificate. Default: True + :param basestring ca_bundle: + Path to the ca bundle to use when verifying SSL certificates. :raise: NotFound if the tag for the given tag_id does not exist in the system. :raise: Unauthorized @@ -9414,7 +9656,8 @@ def delete_tag_category(category_id, if the user can not be authenticated. ''' category_deleted = None - client = _get_client(server, username, password) + client = _get_client(server, username, password, verify_ssl=verify_ssl, + ca_bundle=ca_bundle) if client: try: @@ -9428,9 +9671,17 @@ def delete_tag_category(category_id, @depends(HAS_PYVMOMI, HAS_VSPHERE_SDK) @supports_proxies('vcenter') @gets_service_instance_via_proxy -def create_tag(name, description, category_id, - server=None, username=None, password=None, - service_instance=None): +def create_tag( + name, + description, + category_id, + server=None, + username=None, + password=None, + service_instance=None, + verify_ssl=None, + ca_bundle=None, +): ''' Create a tag under a category with given description. @@ -9452,6 +9703,10 @@ def create_tag(name, description, category_id, Given description of tag category. :param str category_id: Value of category_id representative of the category created previously. + :param boolean verify_ssl: + Verify the SSL certificate. Default: True + :param basestring ca_bundle: + Path to the ca bundle to use when verifying SSL certificates. :return: The identifier of the created tag. :rtype: @@ -9468,7 +9723,8 @@ def create_tag(name, description, category_id, if you do not have the privilege to create tag. ''' tag_created = None - client = _get_client(server, username, password) + client = _get_client(server, username, password, verify_ssl=verify_ssl, + ca_bundle=ca_bundle) if client: create_spec = client.tagging.Tag.CreateSpec() @@ -9486,9 +9742,10 @@ def create_tag(name, description, category_id, @depends(HAS_PYVMOMI, HAS_VSPHERE_SDK) @supports_proxies('vcenter') @gets_service_instance_via_proxy -def delete_tag(tag_id, - server=None, username=None, password=None, - service_instance=None): +def delete_tag( + tag_id, server=None, username=None, password=None, service_instance=None, + verify_ssl=None, ca_bundle=None +): ''' Delete a tag. @@ -9508,6 +9765,10 @@ def delete_tag(tag_id, Username associated with the vCenter center. :param basestring password: Password associated with the vCenter center. + :param boolean verify_ssl: + Verify the SSL certificate. Default: True + :param basestring ca_bundle: + Path to the ca bundle to use when verifying SSL certificates. :raise: AlreadyExists if the name provided in the create_spec is the name of an already existing category. @@ -9517,7 +9778,8 @@ def delete_tag(tag_id, if you do not have the privilege to create a category. ''' tag_deleted = None - client = _get_client(server, username, password) + client = _get_client(server, username, password, verify_ssl=verify_ssl, + ca_bundle=ca_bundle) if client: try: diff --git a/salt/modules/zenoss.py b/salt/modules/zenoss.py index 50711f34cd..f7fcc69b92 100644 --- a/salt/modules/zenoss.py +++ b/salt/modules/zenoss.py @@ -16,6 +16,8 @@ Module for working with the Zenoss API hostname: https://zenoss.example.com username: admin password: admin123 + verify_ssl: True + ca_bundle: /etc/ssl/certs/ca-certificates.crt ''' @@ -24,12 +26,13 @@ import re import logging try: - import requests + import requests # pylint: disable=unused-import HAS_LIBS = True except ImportError: HAS_LIBS = False import salt.utils.json +import salt.utils.http # Disable INFO level logs from requests/urllib3 urllib3_logger = logging.getLogger('urllib3') @@ -69,13 +72,12 @@ def _session(): ''' Create a session to be used when connecting to Zenoss. ''' - config = __salt__['config.option']('zenoss') - session = requests.session() - session.auth = (config.get('username'), config.get('password')) - session.verify = False - session.headers.update({'Content-type': 'application/json; charset=utf-8'}) - return session + return salt.utils.http.session(user=config.get("username"), + password=config.get("password"), + verify_ssl=config.get("verify_ssl", True), + ca_bundle=config.get("ca_bundle"), + headers={"Content-type": "application/json; charset=utf-8"}) def _router_request(router, method, data=None): diff --git a/salt/pillar/vmware_pillar.py b/salt/pillar/vmware_pillar.py index a4ed67ccdc..79132ea110 100644 --- a/salt/pillar/vmware_pillar.py +++ b/salt/pillar/vmware_pillar.py @@ -426,11 +426,10 @@ def ext_pillar(minion_id, if virtualgrain == 'vmware' or osgrain == 'vmware esxi' or osgrain == 'esxi': vmware_pillar[pillar_key] = {} try: - _conn = salt.utils.vmware.get_service_instance(host, - username, - password, - protocol, - port) + _conn = salt.utils.vmware.get_service_instance( + host, username, password, protocol, port, + verify_ssl=kwargs.get("verify_ssl", True) + ) if _conn: data = None for prop_type in property_types: diff --git a/salt/proxy/cimc.py b/salt/proxy/cimc.py index ef1f0412b4..cb15809ae9 100644 --- a/salt/proxy/cimc.py +++ b/salt/proxy/cimc.py @@ -40,6 +40,7 @@ the ID. host: <ip or dns name of cimc host> username: <cimc username> password: <cimc password> + verify_ssl: True proxytype ^^^^^^^^^ @@ -120,6 +121,10 @@ def init(opts): DETAILS['host'] = opts['proxy']['host'] DETAILS['username'] = opts['proxy'].get('username') DETAILS['password'] = opts['proxy'].get('password') + verify_ssl = opts['proxy'].get('verify_ssl') + if verify_ssl is None: + verify_ssl = True + DETAILS["verify_ssl"] = verify_ssl # Ensure connectivity to the device log.debug("Attempting to connect to cimc proxy host.") @@ -148,7 +153,7 @@ def set_config_modify(dn=None, inconfig=None, hierarchical=False): method='POST', decode_type='plain', decode=True, - verify_ssl=False, + verify_ssl=DETAILS["verify_ssl"], raise_error=True, headers=DETAILS['headers']) answer = re.findall(r'(<[\s\S.]*>)', r['text'])[0] @@ -177,7 +182,7 @@ def get_config_resolver_class(cid=None, hierarchical=False): method='POST', decode_type='plain', decode=True, - verify_ssl=False, + verify_ssl=DETAILS["verify_ssl"], raise_error=True, headers=DETAILS['headers']) @@ -200,7 +205,7 @@ def logon(): method='POST', decode_type='plain', decode=True, - verify_ssl=False, + verify_ssl=DETAILS["verify_ssl"], raise_error=False, headers=DETAILS['headers']) answer = re.findall(r'(<[\s\S.]*>)', r['text'])[0] @@ -224,7 +229,7 @@ def logout(cookie=None): method='POST', decode_type='plain', decode=True, - verify_ssl=False, + verify_ssl=DETAILS["verify_ssl"], raise_error=True, headers=DETAILS['headers']) return diff --git a/salt/proxy/panos.py b/salt/proxy/panos.py index 969661cc6d..f9d243cd8e 100644 --- a/salt/proxy/panos.py +++ b/salt/proxy/panos.py @@ -53,6 +53,7 @@ the device with username and password. host: <ip or dns name of panos host> username: <panos username> password: <panos password> + verify_ssl: True proxytype ^^^^^^^^^ @@ -273,6 +274,7 @@ def init(opts): # Set configuration details DETAILS['host'] = opts['proxy']['host'] + DETAILS["verify_ssl"] = opts["proxy"].get("verify_ssl", True) if 'serial' in opts['proxy']: DETAILS['serial'] = opts['proxy'].get('serial') if 'apikey' in opts['proxy']: @@ -319,7 +321,7 @@ def call(payload=None): method='POST', decode_type='plain', decode=True, - verify_ssl=False, + verify_ssl=DETAILS["verify_ssl"], status=True, raise_error=True) elif DETAILS['method'] == 'dev_pass': @@ -331,7 +333,7 @@ def call(payload=None): method='POST', decode_type='plain', decode=True, - verify_ssl=False, + verify_ssl=DETAILS["verify_ssl"], status=True, raise_error=True) elif DETAILS['method'] == 'pan_key': @@ -344,7 +346,7 @@ def call(payload=None): method='POST', decode_type='plain', decode=True, - verify_ssl=False, + verify_ssl=DETAILS["verify_ssl"], status=True, raise_error=True) elif DETAILS['method'] == 'pan_pass': @@ -358,7 +360,7 @@ def call(payload=None): method='POST', decode_type='plain', decode=True, - verify_ssl=False, + verify_ssl=DETAILS["verify_ssl"], status=True, raise_error=True) except KeyError as err: diff --git a/salt/proxy/vcenter.py b/salt/proxy/vcenter.py index d09d9416ef..bbd103c95e 100644 --- a/salt/proxy/vcenter.py +++ b/salt/proxy/vcenter.py @@ -271,6 +271,8 @@ def init(opts): # Save optional DETAILS['protocol'] = proxy_conf.get('protocol') DETAILS['port'] = proxy_conf.get('port') + DETAILS['verify_ssl'] = proxy_conf.get('verify_ssl') + DETAILS['ca_bundle'] = proxy_conf.get('ca_bundle') # Test connection if DETAILS['mechanism'] == 'userpass': diff --git a/salt/returners/splunk.py b/salt/returners/splunk.py index ad03096b9b..f82030d33f 100644 --- a/salt/returners/splunk.py +++ b/salt/returners/splunk.py @@ -11,6 +11,7 @@ Requires the following config values to be specified in config or pillar: indexer: <hostname/IP of Splunk indexer> sourcetype: <Destination sourcetype for data> index: <Destination index for data> + verify_ssl: true Run a test by using ``salt-call test.ping --return splunk`` @@ -31,7 +32,6 @@ import salt.utils.json from salt.ext import six _max_content_bytes = 100000 -http_event_collector_SSL_verify = False http_event_collector_debug = False log = logging.getLogger(__name__) @@ -60,10 +60,13 @@ def _get_options(): indexer = __salt__['config.get']('splunk_http_forwarder:indexer') sourcetype = __salt__['config.get']('splunk_http_forwarder:sourcetype') index = __salt__['config.get']('splunk_http_forwarder:index') + verify_ssl = __salt__["config.get"]( + "splunk_http_forwarder:verify_ssl", default=True + ) except Exception: # pylint: disable=broad-except log.error("Splunk HTTP Forwarder parameters not present in config.") return None - splunk_opts = {"token": token, "indexer": indexer, "sourcetype": sourcetype, "index": index} + splunk_opts = {"token": token, "indexer": indexer, "sourcetype": sourcetype, "index": index, "verify_ssl": verify_ssl} return splunk_opts @@ -80,8 +83,9 @@ def _send_splunk(event, index_override=None, sourcetype_override=None): salt.utils.json.dumps(opts)) http_event_collector_key = opts['token'] http_event_collector_host = opts['indexer'] + http_event_collector_verify_ssl = opts["verify_ssl"] # Set up the collector - splunk_event = http_event_collector(http_event_collector_key, http_event_collector_host) + splunk_event = http_event_collector(http_event_collector_key, http_event_collector_host, verify_ssl=http_event_collector_verify_ssl) # init the payload payload = {} @@ -114,13 +118,15 @@ class http_event_collector(object): host="", http_event_port='8088', http_event_server_ssl=True, - max_bytes=_max_content_bytes): + max_bytes=_max_content_bytes, + verify_ssl=True): self.token = token self.batchEvents = [] self.maxByteLength = max_bytes self.currentByteLength = 0 + self.verify_ssl = verify_ssl - # Set host to specified value or default to localhostname if no value provided + # Set host to specified value or default to localhostname if no value provided if host: self.host = host else: @@ -163,7 +169,7 @@ class http_event_collector(object): r = requests.post(self.server_uri, data=salt.utils.json.dumps(data), headers=headers, - verify=http_event_collector_SSL_verify) + verify=self.verify_ssl) # Print debug info if flag set if http_event_collector_debug: @@ -203,6 +209,6 @@ class http_event_collector(object): if len(self.batchEvents) > 0: headers = {'Authorization': 'Splunk '+self.token} - r = requests.post(self.server_uri, data=" ".join(self.batchEvents), headers=headers, verify=http_event_collector_SSL_verify) + r = requests.post(self.server_uri, data=" ".join(self.batchEvents), headers=headers, verify=self.verify_ssl) self.batchEvents = [] self.currentByteLength = 0 diff --git a/salt/runners/asam.py b/salt/runners/asam.py index 6df9a9d163..58a63d8b6e 100644 --- a/salt/runners/asam.py +++ b/salt/runners/asam.py @@ -18,9 +18,11 @@ master configuration at ``/etc/salt/master`` or ``/etc/salt/master.d/asam.conf`` prov1.domain.com username: "testuser" password: "verybadpass" + verify_ssl: true prov2.domain.com username: "testuser" password: "verybadpass" + verify_ssl: true .. note:: @@ -88,6 +90,10 @@ def _get_asam_configuration(driver_url=''): password = service_config.get('password', None) protocol = service_config.get('protocol', 'https') port = service_config.get('port', 3451) + verify_ssl = service_config.get("verify_ssl") + + if verify_ssl is None: + verify_ssl = True if not username or not password: log.error( @@ -102,7 +108,8 @@ def _get_asam_configuration(driver_url=''): 'platformset_edit_url': "{0}://{1}:{2}/config/PlatformSetEdit.html".format(protocol, asam_server, port), 'platformset_config_url': "{0}://{1}:{2}/config/PlatformSetConfig.html".format(protocol, asam_server, port), 'username': username, - 'password': password + 'password': password, + "verify_ssl": verify_ssl } if (not driver_url) or (driver_url == asam_server): @@ -201,7 +208,7 @@ def remove_platform(name, server_url): ) try: - html_content = _make_post_request(url, data, auth, verify=False) + html_content = _make_post_request(url, data, auth, verify=config["verify_ssl"]) except Exception as exc: # pylint: disable=broad-except err_msg = "Failed to look up existing platforms on {0}".format(server_url) log.error('%s:\n%s', err_msg, exc) @@ -217,7 +224,7 @@ def remove_platform(name, server_url): data['postType'] = 'platformRemove' data['Submit'] = 'Yes' try: - html_content = _make_post_request(url, data, auth, verify=False) + html_content = _make_post_request(url, data, auth, verify=config["verify_ssl"]) except Exception as exc: # pylint: disable=broad-except err_msg = "Failed to delete platform from {1}".format(server_url) log.error('%s:\n%s', err_msg, exc) @@ -259,7 +266,7 @@ def list_platforms(server_url): ) try: - html_content = _make_post_request(url, data, auth, verify=False) + html_content = _make_post_request(url, data, auth, verify=config["verify_ssl"]) except Exception as exc: # pylint: disable=broad-except err_msg = "Failed to look up existing platforms" log.error('%s:\n%s', err_msg, exc) @@ -300,7 +307,7 @@ def list_platform_sets(server_url): ) try: - html_content = _make_post_request(url, data, auth, verify=False) + html_content = _make_post_request(url, data, auth, verify=config["verify_ssl"]) except Exception as exc: # pylint: disable=broad-except err_msg = "Failed to look up existing platform sets" log.error('%s:\n%s', err_msg, exc) @@ -355,7 +362,7 @@ def add_platform(name, platform_set, server_url): ) try: - html_content = _make_post_request(url, data, auth, verify=False) + html_content = _make_post_request(url, data, auth, verify=config["verify_ssl"]) except Exception as exc: # pylint: disable=broad-except err_msg = "Failed to add platform on {0}".format(server_url) log.error('%s:\n%s', err_msg, exc) diff --git a/salt/states/esxi.py b/salt/states/esxi.py index 8728224716..2bcb3ebe9a 100644 --- a/salt/states/esxi.py +++ b/salt/states/esxi.py @@ -672,7 +672,7 @@ def ssh_configured(name, ssh_key_file=None, service_policy=None, service_restart=False, - certificate_verify=False): + certificate_verify=None): ''' Manage the SSH configuration for a host including whether or not SSH is running or the presence of a given SSH key. Note: Only one ssh key can be uploaded for root. @@ -712,7 +712,7 @@ def ssh_configured(name, certificate_verify If set to ``True``, the SSL connection must present a valid certificate. - Default is ``False``. + Default is ``True``. Example: @@ -731,6 +731,10 @@ def ssh_configured(name, 'result': False, 'changes': {}, 'comment': ''} + + if certificate_verify is None: + certificate_verify = True + esxi_cmd = 'esxi.cmd' host = __pillar__['proxy']['host'] ssh = 'ssh' diff --git a/salt/utils/http.py b/salt/utils/http.py index c2fdffb266..8ead0fe27d 100644 --- a/salt/utils/http.py +++ b/salt/utils/http.py @@ -1003,3 +1003,23 @@ def _sanitize_url_components(comp_list, field): ret = '{0}&'.format(comp_list[0]) comp_list.remove(comp_list[0]) return ret + _sanitize_url_components(comp_list, field) + + +def session(user=None, password=None, verify_ssl=True, ca_bundle=None, headers=None): + """ + create a requests session + """ + session = requests.session() + if user and password: + session.auth = (user, password) + if ca_bundle and not verify_ssl: + log.error("You cannot use both ca_bundle and verify_ssl False together") + return False + if ca_bundle: + opts = {"ca_bundle": ca_bundle} + session.verify = get_ca_bundle(opts) + if not verify_ssl: + session.verify = False + if headers: + session.headers.update(headers) + return session diff --git a/salt/utils/templates.py b/salt/utils/templates.py index 98092a9d79..fe8bac95d1 100644 --- a/salt/utils/templates.py +++ b/salt/utils/templates.py @@ -16,6 +16,7 @@ import sys # Import 3rd-party libs import jinja2 import jinja2.ext +import jinja2.sandbox from salt.ext import six if sys.version_info[:2] >= (3, 5): @@ -354,9 +355,9 @@ def render_jinja_tmpl(tmplstr, context, tmplpath=None): opt_jinja_env_helper(opt_jinja_env, 'jinja_env') if opts.get('allow_undefined', False): - jinja_env = jinja2.Environment(**env_args) + jinja_env = jinja2.sandbox.SandboxedEnvironment(**env_args) else: - jinja_env = jinja2.Environment(undefined=jinja2.StrictUndefined, + jinja_env = jinja2.sandbox.SandboxedEnvironment(undefined=jinja2.StrictUndefined, **env_args) tojson_filter = jinja_env.filters.get('tojson') @@ -403,7 +404,8 @@ def render_jinja_tmpl(tmplstr, context, tmplpath=None): exc, out), buf=tmplstr) except (jinja2.exceptions.TemplateRuntimeError, - jinja2.exceptions.TemplateSyntaxError) as exc: + jinja2.exceptions.TemplateSyntaxError, + jinja2.exceptions.SecurityError) as exc: trace = traceback.extract_tb(sys.exc_info()[2]) line, out = _get_jinja_error(trace, context=decoded_context) if not line: diff --git a/salt/utils/thin.py b/salt/utils/thin.py index 0ff31cef39..641e35a493 100644 --- a/salt/utils/thin.py +++ b/salt/utils/thin.py @@ -404,8 +404,8 @@ def gen_thin(cachedir, extra_mods='', overwrite=False, so_mods='', if not salt.utils.path.which(python2_bin): log.debug('%s binary does not exist. Will not detect Python 2 version', python2_bin) else: - py_shell_cmd = "{} -c 'import sys;sys.stdout.write(\"%s.%s\\n\" % sys.version_info[:2]);'".format(python2_bin) - cmd = subprocess.Popen(py_shell_cmd, stdout=subprocess.PIPE, shell=True) + py_shell_cmd = [python2_bin, "-c", "import sys;sys.stdout.write(\"%s.%s\\n\" % sys.version_info[:2]);"] + cmd = subprocess.Popen(py_shell_cmd, stdout=subprocess.PIPE) stdout, _ = cmd.communicate() if cmd.returncode == 0: py2_version = tuple(int(n) for n in stdout.decode('utf-8').strip().split('.')) @@ -430,9 +430,9 @@ def gen_thin(cachedir, extra_mods='', overwrite=False, so_mods='', if not salt.utils.path.which(python3_bin): log.debug(python_check_msg, python3_bin, '3') else: - py_shell_cmd = "{0} -c 'import salt.utils.thin as t;print(t.gte())' '{1}'".format( - python3_bin, salt.utils.json.dumps({'extra_mods': extra_mods, 'so_mods': so_mods})) - cmd = subprocess.Popen(py_shell_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) + py_shell_cmd = [python3_bin, "-c", "import salt.utils.thin as t;print(t.gte())", + salt.utils.json.dumps({'extra_mods': extra_mods, 'so_mods': so_mods})] + cmd = subprocess.Popen(py_shell_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = cmd.communicate() if cmd.returncode == 0: try: @@ -451,9 +451,9 @@ def gen_thin(cachedir, extra_mods='', overwrite=False, so_mods='', if not salt.utils.path.which(python2_bin): log.debug(python_check_msg, python2_bin, '2') else: - py_shell_cmd = "{0} -c 'import salt.utils.thin as t;print(t.gte())' '{1}'".format( - python2_bin, salt.utils.json.dumps({'extra_mods': extra_mods, 'so_mods': so_mods})) - cmd = subprocess.Popen(py_shell_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) + py_shell_cmd = [python2_bin, "-c", "import salt.utils.thin as t;print(t.gte())", + salt.utils.json.dumps({'extra_mods': extra_mods, 'so_mods': so_mods})] + cmd = subprocess.Popen(py_shell_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = cmd.communicate() if cmd.returncode == 0: try: @@ -637,11 +637,12 @@ def gen_min(cachedir, extra_mods='', overwrite=False, so_mods='', return mintar if _six.PY3: # Let's check for the minimum python 2 version requirement, 2.6 - py_shell_cmd = ( - python2_bin + ' -c \'from __future__ import print_function; import sys; ' - 'print("{0}.{1}".format(*(sys.version_info[:2])));\'' - ) - cmd = subprocess.Popen(py_shell_cmd, stdout=subprocess.PIPE, shell=True) + py_shell_cmd = [ + python2_bin, '-c', + 'from __future__ import print_function; import sys;print("{0}.{1}".format(*(sys.version_info[:2])));' + ] + + cmd = subprocess.Popen(py_shell_cmd, stdout=subprocess.PIPE) stdout, _ = cmd.communicate() if cmd.returncode == 0: py2_version = tuple(int(n) for n in stdout.decode('utf-8').strip().split('.')) @@ -670,12 +671,14 @@ def gen_min(cachedir, extra_mods='', overwrite=False, so_mods='', # This would reduce the min size. if _six.PY2 and sys.version_info[0] == 2: # Get python 3 tops - py_shell_cmd = ( - python3_bin + ' -c \'import sys; import json; import salt.utils.thin; ' - 'print(json.dumps(salt.utils.thin.get_tops(**(json.loads(sys.argv[1]))), ensure_ascii=False)); exit(0);\' ' - '\'{0}\''.format(salt.utils.json.dumps({'extra_mods': extra_mods, 'so_mods': so_mods})) - ) - cmd = subprocess.Popen(py_shell_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) + py_shell_cmd = [ + python3_bin, "-c", + "import sys; import json; import salt.utils.thin;" + "print(json.dumps(salt.utils.thin.get_tops(**(json.loads(sys.argv[1]))), ensure_ascii=False)); exit(0);", + salt.utils.json.dumps({'extra_mods': extra_mods, 'so_mods': so_mods}) + ] + + cmd = subprocess.Popen(py_shell_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = cmd.communicate() if cmd.returncode == 0: try: @@ -685,13 +688,14 @@ def gen_min(cachedir, extra_mods='', overwrite=False, so_mods='', pass if _six.PY3 and sys.version_info[0] == 3: # Get python 2 tops - py_shell_cmd = ( - python2_bin + ' -c \'from __future__ import print_function; ' - 'import sys; import json; import salt.utils.thin; ' - 'print(json.dumps(salt.utils.thin.get_tops(**(json.loads(sys.argv[1]))), ensure_ascii=False)); exit(0);\' ' - '\'{0}\''.format(salt.utils.json.dumps({'extra_mods': extra_mods, 'so_mods': so_mods})) - ) - cmd = subprocess.Popen(py_shell_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) + py_shell_cmd = [ + python2_bin, "-c", + "from __future__ import print_function; import sys; import json; import salt.utils.thin;" + "print(json.dumps(salt.utils.thin.get_tops(**(json.loads(sys.argv[1]))), ensure_ascii=False)); exit(0);", + salt.utils.json.dumps({'extra_mods': extra_mods, 'so_mods': so_mods}) + ] + + cmd = subprocess.Popen(py_shell_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) stdout, stderr = cmd.communicate() if cmd.returncode == 0: try: diff --git a/salt/utils/vmware.py b/salt/utils/vmware.py index 92210f48db..c8eea51f2c 100644 --- a/salt/utils/vmware.py +++ b/salt/utils/vmware.py @@ -79,7 +79,6 @@ import atexit import errno import logging import time -import requests import sys import ssl @@ -189,7 +188,9 @@ def esxcli(host, user, pwd, cmd, protocol=None, port=None, esxi_host=None, creds return ret -def get_vsphere_client(server, username, password, session=None): +def get_vsphere_client( + server, username, password, session=None, verify_ssl=True, ca_bundle=None +): ''' Internal helper method to create an instance of the vSphere API client. Please provide username and password to authenticate. @@ -203,6 +204,10 @@ def get_vsphere_client(server, username, password, session=None): :param Session session: Request HTTP session instance. If not specified, one is automatically created and used + :param boolean verify_ssl: + Verify the SSL certificate. Default: True + :param basestring ca_bundle: + Path to the ca bundle to use when verifying SSL certificates. :returns: Vsphere Client instance @@ -211,9 +216,7 @@ def get_vsphere_client(server, username, password, session=None): ''' if not session: # Create an https session to be used for a vSphere client - session = requests.session() - # If client uses own SSL cert, session should not verify - session.verify = False + session = salt.utils.http.session(verify_ssl=verify_ssl, ca_bundle=ca_bundle) client = None try: client = create_vsphere_client(server=server, @@ -225,8 +228,17 @@ def get_vsphere_client(server, username, password, session=None): return client -def _get_service_instance(host, username, password, protocol, - port, mechanism, principal, domain): +def _get_service_instance( + host, + username, + password, + protocol, + port, + mechanism, + principal, + domain, + verify_ssl=True, +): ''' Internal method to authenticate with a vCenter server or ESX/ESXi host and return the service instance object. @@ -254,18 +266,28 @@ def _get_service_instance(host, username, password, protocol, raise salt.exceptions.CommandExecutionError(err_msg) else: raise salt.exceptions.CommandExecutionError( - 'Unsupported mechanism: \'{0}\''.format(mechanism)) + "Unsupported mechanism: '{0}'".format(mechanism) + ) + + log.trace( + "Connecting using the '%s' mechanism, with username '%s'", mechanism, username, + ) + default_msg = ( + "Could not connect to host '{0}'. " + "Please check the debug log for more information.".format(host) + ) + try: - log.trace('Connecting using the \'%s\' mechanism, with username \'%s\'', - mechanism, username) - service_instance = SmartConnect( - host=host, - user=username, - pwd=password, - protocol=protocol, - port=port, - b64token=token, - mechanism=mechanism) + if verify_ssl: + service_instance = SmartConnect( + host=host, + user=username, + pwd=password, + protocol=protocol, + port=port, + b64token=token, + mechanism=mechanism, + ) except TypeError as exc: if 'unexpected keyword argument' in exc.message: log.error('Initial connect to the VMware endpoint failed with %s', exc.message) @@ -274,26 +296,33 @@ def _get_service_instance(host, username, password, protocol, raise except Exception as exc: # pylint: disable=broad-except # pyVmomi's SmartConnect() actually raises Exception in some cases. - default_msg = 'Could not connect to host \'{0}\'. ' \ - 'Please check the debug log for more information.'.format(host) + if ( + isinstance(exc, vim.fault.HostConnectFault) + and "[SSL: CERTIFICATE_VERIFY_FAILED]" in exc.msg + ) or "[SSL: CERTIFICATE_VERIFY_FAILED]" in str(exc): + err_msg = ( + "Could not verify the SSL certificate. You can use " + "verify_ssl: False if you do not want to verify the " + "SSL certificate. This is not recommended as it is " + "considered insecure." + ) + else: + log.exception(exc) + err_msg = exc.msg if hasattr(exc, "msg") else default_msg + raise salt.exceptions.VMwareConnectionError(err_msg) + if not verify_ssl: try: - if (isinstance(exc, vim.fault.HostConnectFault) and - '[SSL: CERTIFICATE_VERIFY_FAILED]' in exc.msg) or \ - '[SSL: CERTIFICATE_VERIFY_FAILED]' in six.text_type(exc): - service_instance = SmartConnect( - host=host, - user=username, - pwd=password, - protocol=protocol, - port=port, - sslContext=getattr(ssl, '_create_unverified_context', getattr(ssl, '_create_stdlib_context'))(), - b64token=token, - mechanism=mechanism) - else: - log.exception(exc) - err_msg = exc.msg if hasattr(exc, 'msg') else default_msg - raise salt.exceptions.VMwareConnectionError(err_msg) + service_instance = SmartConnect( + host=host, + user=username, + pwd=password, + protocol=protocol, + port=port, + sslContext=getattr(ssl, '_create_unverified_context', getattr(ssl, '_create_stdlib_context'))(), + b64token=token, + mechanism=mechanism, + ) except Exception as exc: # pylint: disable=broad-except # pyVmomi's SmartConnect() actually raises Exception in some cases. if 'certificate verify failed' in six.text_type(exc): @@ -320,6 +349,7 @@ def _get_service_instance(host, username, password, protocol, err_msg = exc.msg if hasattr(exc, 'msg') else default_msg log.trace(exc) raise salt.exceptions.VMwareConnectionError(err_msg) + atexit.register(Disconnect, service_instance) return service_instance @@ -361,9 +391,17 @@ def get_mor_using_container_view(si, obj_type, obj_name): return None -def get_service_instance(host, username=None, password=None, protocol=None, - port=None, mechanism='userpass', principal=None, - domain=None): +def get_service_instance( + host, + username=None, + password=None, + protocol=None, + port=None, + mechanism="userpass", + principal=None, + domain=None, + verify_ssl=True, +): ''' Authenticate with a vCenter server or ESX/ESXi host and return the service instance object. @@ -395,8 +433,10 @@ def get_service_instance(host, username=None, password=None, protocol=None, domain Kerberos user domain. Required if mechanism is ``sspi`` - ''' + verify_ssl + Verify the SSL certificate. Default: True + ''' if protocol is None: protocol = 'https' if port is None: @@ -418,14 +458,17 @@ def get_service_instance(host, username=None, password=None, protocol=None, return service_instance if not service_instance: - service_instance = _get_service_instance(host, - username, - password, - protocol, - port, - mechanism, - principal, - domain) + service_instance = _get_service_instance( + host, + username, + password, + protocol, + port, + mechanism, + principal, + domain, + verify_ssl=verify_ssl, + ) # Test if data can actually be retrieved or connection has gone stale log.trace('Checking connection is still authenticated') @@ -434,14 +477,17 @@ def get_service_instance(host, username=None, password=None, protocol=None, except vim.fault.NotAuthenticated: log.trace('Session no longer authenticating. Reconnecting') Disconnect(service_instance) - service_instance = _get_service_instance(host, - username, - password, - protocol, - port, - mechanism, - principal, - domain) + service_instance = _get_service_instance( + host, + username, + password, + protocol, + port, + mechanism, + principal, + domain, + verify_ssl=verify_ssl, + ) except vim.fault.NoPermission as exc: log.exception(exc) raise salt.exceptions.VMwareApiError( diff --git a/salt/wheel/__init__.py b/salt/wheel/__init__.py index 7eeac71678..27ea3d59c0 100644 --- a/salt/wheel/__init__.py +++ b/salt/wheel/__init__.py @@ -123,8 +123,8 @@ class WheelClient(salt.client.mixins.SyncClientMixin, }) {'jid': '20131219224744416681', 'tag': 'salt/wheel/20131219224744416681'} ''' - fun = low.pop('fun') - return self.asynchronous(fun, low) + fun = low.get("fun") + return self.asynchronous(fun, low, local=False) def cmd(self, fun, arg=None, pub_data=None, kwarg=None, print_event=True, full_return=False): # pylint: disable=useless-super-delegation ''' diff --git a/salt/wheel/pillar_roots.py b/salt/wheel/pillar_roots.py index bb24f92f7b..fdeefab718 100644 --- a/salt/wheel/pillar_roots.py +++ b/salt/wheel/pillar_roots.py @@ -11,6 +11,7 @@ import os # Import salt libs import salt.utils.files import salt.utils.path +import salt.utils.verify # Import 3rd-party libs from salt.ext import six @@ -108,7 +109,10 @@ def write(data, path, saltenv='base', index=0): if os.path.isabs(path): return ('The path passed in {0} is not relative to the environment ' '{1}').format(path, saltenv) - dest = os.path.join(__opts__['pillar_roots'][saltenv][index], path) + roots_dir = __opts__['pillar_roots'][saltenv][index] + dest = os.path.join(roots_dir, path) + if not salt.utils.verify.clean_path(roots_dir, dest): + return 'Invalid path' dest_dir = os.path.dirname(dest) if not os.path.isdir(dest_dir): os.makedirs(dest_dir) -- 2.30.1
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor