/salt/modules/vsphere.py
Python | 4206 lines | 3448 code | 158 blank | 600 comment | 173 complexity | 15c137cf6ced75e692d988162a92f3ee MD5 | raw file
Possible License(s): Apache-2.0
Large files files are truncated, but you can click here to view the full file
- # -*- coding: utf-8 -*-
- '''
- Manage VMware vCenter servers and ESXi hosts.
- .. versionadded:: 2015.8.4
- :codeauthor: :email:`Alexandru Bleotu <alexandru.bleotu@morganstaley.com>`
- Dependencies
- ============
- - pyVmomi Python Module
- - ESXCLI
- pyVmomi
- -------
- PyVmomi can be installed via pip:
- .. code-block:: bash
- pip install pyVmomi
- .. note::
- Version 6.0 of pyVmomi has some problems with SSL error handling on certain
- versions of Python. If using version 6.0 of pyVmomi, Python 2.6,
- Python 2.7.9, or newer must be present. This is due to an upstream dependency
- in pyVmomi 6.0 that is not supported in Python versions 2.7 to 2.7.8. If the
- version of Python is not in the supported range, you will need to install an
- earlier version of pyVmomi. See `Issue #29537`_ for more information.
- .. _Issue #29537: https://github.com/saltstack/salt/issues/29537
- Based on the note above, to install an earlier version of pyVmomi than the
- version currently listed in PyPi, run the following:
- .. code-block:: bash
- pip install pyVmomi==5.5.0.2014.1.1
- The 5.5.0.2014.1.1 is a known stable version that this original vSphere Execution
- Module was developed against.
- ESXCLI
- ------
- Currently, about a third of the functions used in the vSphere Execution Module require
- the ESXCLI package be installed on the machine running the Proxy Minion process.
- The ESXCLI package is also referred to as the VMware vSphere CLI, or vCLI. VMware
- provides vCLI package installation instructions for `vSphere 5.5`_ and
- `vSphere 6.0`_.
- .. _vSphere 5.5: http://pubs.vmware.com/vsphere-55/index.jsp#com.vmware.vcli.getstart.doc/cli_install.4.2.html
- .. _vSphere 6.0: http://pubs.vmware.com/vsphere-60/index.jsp#com.vmware.vcli.getstart.doc/cli_install.4.2.html
- Once all of the required dependencies are in place and the vCLI package is
- installed, you can check to see if you can connect to your ESXi host or vCenter
- server by running the following command:
- .. code-block:: bash
- esxcli -s <host-location> -u <username> -p <password> system syslog config get
- If the connection was successful, ESXCLI was successfully installed on your system.
- You should see output related to the ESXi host's syslog configuration.
- .. note::
- Be aware that some functionality in this execution module may depend on the
- type of license attached to a vCenter Server or ESXi host(s).
- For example, certain services are only available to manipulate service state
- or policies with a VMware vSphere Enterprise or Enterprise Plus license, while
- others are available with a Standard license. The ``ntpd`` service is restricted
- to an Enterprise Plus license, while ``ssh`` is available via the Standard
- license.
- Please see the `vSphere Comparison`_ page for more information.
- .. _vSphere Comparison: https://www.vmware.com/products/vsphere/compare
- About
- =====
- This execution module was designed to be able to handle connections both to a
- vCenter Server, as well as to an ESXi host. It utilizes the pyVmomi Python
- library and the ESXCLI package to run remote execution functions against either
- the defined vCenter server or the ESXi host.
- Whether or not the function runs against a vCenter Server or an ESXi host depends
- entirely upon the arguments passed into the function. Each function requires a
- ``host`` location, ``username``, and ``password``. If the credentials provided
- apply to a vCenter Server, then the function will be run against the vCenter
- Server. For example, when listing hosts using vCenter credentials, you'll get a
- list of hosts associated with that vCenter Server:
- .. code-block:: bash
- # salt my-minion vsphere.list_hosts <vcenter-ip> <vcenter-user> <vcenter-password>
- my-minion:
- - esxi-1.example.com
- - esxi-2.example.com
- However, some functions should be used against ESXi hosts, not vCenter Servers.
- Functionality such as getting a host's coredump network configuration should be
- performed against a host and not a vCenter server. If the authentication information
- you're using is against a vCenter server and not an ESXi host, you can provide the
- host name that is associated with the vCenter server in the command, as a list, using
- the ``host_names`` or ``esxi_host`` kwarg. For example:
- .. code-block:: bash
- # salt my-minion vsphere.get_coredump_network_config <vcenter-ip> <vcenter-user> \
- <vcenter-password> esxi_hosts='[esxi-1.example.com, esxi-2.example.com]'
- my-minion:
- ----------
- esxi-1.example.com:
- ----------
- Coredump Config:
- ----------
- enabled:
- False
- esxi-2.example.com:
- ----------
- Coredump Config:
- ----------
- enabled:
- True
- host_vnic:
- vmk0
- ip:
- coredump-location.example.com
- port:
- 6500
- You can also use these functions against an ESXi host directly by establishing a
- connection to an ESXi host using the host's location, username, and password. If ESXi
- connection credentials are used instead of vCenter credentials, the ``host_names`` and
- ``esxi_hosts`` arguments are not needed.
- .. code-block:: bash
- # salt my-minion vsphere.get_coredump_network_config esxi-1.example.com root <host-password>
- local:
- ----------
- 10.4.28.150:
- ----------
- Coredump Config:
- ----------
- enabled:
- True
- host_vnic:
- vmk0
- ip:
- coredump-location.example.com
- port:
- 6500
- '''
- # Import Python Libs
- from __future__ import absolute_import
- import datetime
- import logging
- import sys
- import inspect
- from functools import wraps
- # Import Salt Libs
- import salt.ext.six as six
- import salt.utils
- import salt.utils.vmware
- import salt.utils.http
- from salt.utils import dictupdate
- from salt.exceptions import CommandExecutionError, VMwareSaltError
- from salt.utils.decorators import depends, ignores_kwargs
- from salt.utils import clean_kwargs
- # Import Third Party Libs
- try:
- from pyVmomi import vim, vmodl
- HAS_PYVMOMI = True
- except ImportError:
- HAS_PYVMOMI = False
- esx_cli = salt.utils.which('esxcli')
- if esx_cli:
- HAS_ESX_CLI = True
- else:
- HAS_ESX_CLI = False
- log = logging.getLogger(__name__)
- __virtualname__ = 'vsphere'
- __proxyenabled__ = ['esxi']
- def __virtual__():
- return __virtualname__
- def get_proxy_type():
- '''
- Returns the proxy type
- CLI Example:
- .. code-block:: bash
- salt '*' vsphere.get_proxy_type
- '''
- return __pillar__['proxy']['proxytype']
- def _get_proxy_connection_details():
- '''
- Returns the connection details of the following proxies: esxi
- '''
- proxytype = get_proxy_type()
- if proxytype == 'esxi':
- details = __salt__['esxi.get_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')
- def supports_proxies(*proxy_types):
- '''
- Decorator to specify which proxy types are supported by a function
- proxy_types:
- Arbitrary list of strings with the supported types of proxies
- '''
- def _supports_proxies(fn):
- def __supports_proxies(*args, **kwargs):
- proxy_type = get_proxy_type()
- if proxy_type not in proxy_types:
- raise CommandExecutionError(
- '\'{0}\' proxy is not supported by function {1}'
- ''.format(proxy_type, fn.__name__))
- return fn(*args, **clean_kwargs(**kwargs))
- return __supports_proxies
- return _supports_proxies
- def gets_service_instance_via_proxy(fn):
- '''
- Decorator that connects to a target system (vCenter or ESXi host) using the
- proxy details and passes the connection (vim.ServiceInstance) to
- the decorated function.
- Notes:
- 1. The decorated function must have a ``service_instance`` parameter
- or a ``**kwarg`` type argument (name of argument is not important);
- 2. If the ``service_instance`` parameter is already defined, the value
- is passed through to the decorated function;
- 3. If the ``service_instance`` parameter in not defined, the
- connection is created using the proxy details and the service instance
- is returned.
- CLI Example:
- None, this is a decorator
- '''
- fn_name = fn.__name__
- try:
- arg_names, args_name, kwargs_name, default_values, _, _, _ = \
- inspect.getfullargspec(fn)
- except AttributeError:
- # Fallback to Python 2.7
- arg_names, args_name, kwargs_name, default_values = \
- inspect.getargspec(fn)
- default_values = default_values if default_values is not None else []
- @wraps(fn)
- def _gets_service_instance_via_proxy(*args, **kwargs):
- if 'service_instance' not in arg_names and not kwargs_name:
- raise CommandExecutionError(
- 'Function {0} must have either a \'service_instance\', or a '
- '\'**kwargs\' type parameter'.format(fn_name))
- connection_details = _get_proxy_connection_details()
- # Figure out how to pass in the connection value
- local_service_instance = None
- if 'service_instance' in arg_names:
- idx = arg_names.index('service_instance')
- if idx >= len(arg_names) - len(default_values):
- # 'service_instance' has a default value:
- # we check if we need to instantiate it or
- # pass it through
- #
- # NOTE: if 'service_instance' doesn't have a default value
- # it must be explicitly set in the function call so we pass it
- # through
- # There are two cases:
- # 1. service_instance was passed in as a positional parameter
- # 2. service_instance was passed in as a named paramter
- if len(args) > idx:
- # 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)
- args[idx] = local_service_instance
- else:
- # case 2: Not enough positional parameters so
- # 'service_instance' must be a named parameter
- if not kwargs.get('service_instance'):
- local_service_instance = \
- salt.utils.vmware.get_service_instance(
- *connection_details)
- kwargs['service_instance'] = local_service_instance
- else:
- # 'service_instance' is not a paremter in the function definition
- # but it will be caught by the **kwargs parameter
- if not kwargs.get('service_instance'):
- local_service_instance = \
- salt.utils.vmware.get_service_instance(
- *connection_details)
- kwargs['service_instance'] = local_service_instance
- try:
- ret = fn(*args, **clean_kwargs(**kwargs))
- # Disconnect if connected in the decorator
- if local_service_instance:
- salt.utils.vmware.disconnect(local_service_instance)
- return ret
- except Exception as e:
- # Disconnect if connected in the decorator
- if local_service_instance:
- salt.utils.vmware.disconnect(local_service_instance)
- # raise original exception and traceback
- six.reraise(*sys.exc_info())
- return _gets_service_instance_via_proxy
- @supports_proxies('esxi')
- def get_service_instance_via_proxy(service_instance=None):
- '''
- Returns a service instance to the proxied endpoint (vCenter/ESXi host).
- Note:
- Should be used by state functions not invoked directly.
- CLI Example:
- See note above
- '''
- connection_details = _get_proxy_connection_details()
- return salt.utils.vmware.get_service_instance(*connection_details)
- @supports_proxies('esxi')
- def disconnect(service_instance):
- '''
- Disconnects from a vCenter or ESXi host
- Note:
- Should be used by state functions, not invoked directly.
- service_instance
- Service instance (vim.ServiceInstance)
- CLI Example:
- See note above.
- '''
- salt.utils.vmware.disconnect(service_instance)
- return True
- @depends(HAS_ESX_CLI)
- def esxcli_cmd(cmd_str, host=None, username=None, password=None, protocol=None, port=None, esxi_hosts=None, credstore=None):
- '''
- Run an ESXCLI command directly on the host or list of hosts.
- host
- The location of the host.
- username
- The username used to login to the host, such as ``root``.
- password
- The password used to login to the host.
- cmd_str
- The ESXCLI command to run. Note: This should not include the ``-s``, ``-u``,
- ``-p``, ``-h``, ``--protocol``, or ``--portnumber`` arguments that are
- frequently passed when using a bare ESXCLI command from the command line.
- Those arguments are handled by this function via the other args and kwargs.
- protocol
- Optionally set to alternate protocol if the host is not using the default
- protocol. Default protocol is ``https``.
- port
- Optionally set to alternate port if the host is not using the default
- port. Default port is ``443``.
- esxi_hosts
- If ``host`` is a vCenter host, then use esxi_hosts to execute this function
- on a list of one or more ESXi machines.
- credstore
- Optionally set to path to the credential store file.
- CLI Example:
- .. code-block:: bash
- # Used for ESXi host connection information
- salt '*' vsphere.esxcli_cmd my.esxi.host root bad-password \
- 'system coredump network get'
- # Used for connecting to a vCenter Server
- salt '*' vsphere.esxcli_cmd my.vcenter.location root bad-password \
- 'system coredump network get' esxi_hosts='[esxi-1.host.com, esxi-2.host.com]'
- '''
- ret = {}
- if esxi_hosts:
- if not isinstance(esxi_hosts, list):
- raise CommandExecutionError('\'esxi_hosts\' must be a list.')
- for esxi_host in esxi_hosts:
- response = salt.utils.vmware.esxcli(host, username, password, cmd_str,
- protocol=protocol, port=port,
- esxi_host=esxi_host, credstore=credstore)
- if response['retcode'] != 0:
- ret.update({esxi_host: {'Error': response.get('stdout')}})
- else:
- ret.update({esxi_host: response})
- else:
- # Handles a single host or a vCenter connection when no esxi_hosts are provided.
- response = salt.utils.vmware.esxcli(host, username, password, cmd_str,
- protocol=protocol, port=port,
- credstore=credstore)
- if response['retcode'] != 0:
- ret.update({host: {'Error': response.get('stdout')}})
- else:
- ret.update({host: response})
- return ret
- @depends(HAS_ESX_CLI)
- def get_coredump_network_config(host, username, password, protocol=None, port=None, esxi_hosts=None, credstore=None):
- '''
- Retrieve information on ESXi or vCenter network dump collection and
- format it into a dictionary.
- host
- The location of the host.
- username
- The username used to login to the host, such as ``root``.
- password
- The password used to login to the host.
- protocol
- Optionally set to alternate protocol if the host is not using the default
- protocol. Default protocol is ``https``.
- port
- Optionally set to alternate port if the host is not using the default
- port. Default port is ``443``.
- esxi_hosts
- If ``host`` is a vCenter host, then use esxi_hosts to execute this function
- on a list of one or more ESXi machines.
- credstore
- Optionally set to path to the credential store file.
- :return: A dictionary with the network configuration, or, if getting
- the network config failed, a an error message retrieved from the
- standard cmd.run_all dictionary, per host.
- CLI Example:
- .. code-block:: bash
- # Used for ESXi host connection information
- salt '*' vsphere.get_coredump_network_config my.esxi.host root bad-password
- # Used for connecting to a vCenter Server
- salt '*' vsphere.get_coredump_network_config my.vcenter.location root bad-password \
- esxi_hosts='[esxi-1.host.com, esxi-2.host.com]'
- '''
- cmd = 'system coredump network get'
- ret = {}
- if esxi_hosts:
- if not isinstance(esxi_hosts, list):
- raise CommandExecutionError('\'esxi_hosts\' must be a list.')
- for esxi_host in esxi_hosts:
- response = salt.utils.vmware.esxcli(host, username, password, cmd,
- protocol=protocol, port=port,
- esxi_host=esxi_host, credstore=credstore)
- if response['retcode'] != 0:
- ret.update({esxi_host: {'Error': response.get('stdout')}})
- else:
- # format the response stdout into something useful
- ret.update({esxi_host: {'Coredump Config': _format_coredump_stdout(response)}})
- else:
- # Handles a single host or a vCenter connection when no esxi_hosts are provided.
- response = salt.utils.vmware.esxcli(host, username, password, cmd,
- protocol=protocol, port=port,
- credstore=credstore)
- if response['retcode'] != 0:
- ret.update({host: {'Error': response.get('stdout')}})
- else:
- # format the response stdout into something useful
- stdout = _format_coredump_stdout(response)
- ret.update({host: {'Coredump Config': stdout}})
- return ret
- @depends(HAS_ESX_CLI)
- def coredump_network_enable(host, username, password, enabled, protocol=None, port=None, esxi_hosts=None, credstore=None):
- '''
- Enable or disable ESXi core dump collection. Returns ``True`` if coredump is enabled
- and returns ``False`` if core dump is not enabled. If there was an error, the error
- will be the value printed in the ``Error`` key dictionary for the given host.
- host
- The location of the host.
- username
- The username used to login to the host, such as ``root``.
- password
- The password used to login to the host.
- enabled
- Python True or False to enable or disable coredumps.
- protocol
- Optionally set to alternate protocol if the host is not using the default
- protocol. Default protocol is ``https``.
- port
- Optionally set to alternate port if the host is not using the default
- port. Default port is ``443``.
- esxi_hosts
- If ``host`` is a vCenter host, then use esxi_hosts to execute this function
- on a list of one or more ESXi machines.
- credstore
- Optionally set to path to the credential store file.
- CLI Example:
- .. code-block:: bash
- # Used for ESXi host connection information
- salt '*' vsphere.coredump_network_enable my.esxi.host root bad-password True
- # Used for connecting to a vCenter Server
- salt '*' vsphere.coredump_network_enable my.vcenter.location root bad-password True \
- esxi_hosts='[esxi-1.host.com, esxi-2.host.com]'
- '''
- if enabled:
- enable_it = 1
- else:
- enable_it = 0
- cmd = 'system coredump network set -e {0}'.format(enable_it)
- ret = {}
- if esxi_hosts:
- if not isinstance(esxi_hosts, list):
- raise CommandExecutionError('\'esxi_hosts\' must be a list.')
- for esxi_host in esxi_hosts:
- response = salt.utils.vmware.esxcli(host, username, password, cmd,
- protocol=protocol, port=port,
- esxi_host=esxi_host, credstore=credstore)
- if response['retcode'] != 0:
- ret.update({esxi_host: {'Error': response.get('stdout')}})
- else:
- ret.update({esxi_host: {'Coredump Enabled': enabled}})
- else:
- # Handles a single host or a vCenter connection when no esxi_hosts are provided.
- response = salt.utils.vmware.esxcli(host, username, password, cmd,
- protocol=protocol, port=port,
- credstore=credstore)
- if response['retcode'] != 0:
- ret.update({host: {'Error': response.get('stdout')}})
- else:
- ret.update({host: {'Coredump Enabled': enabled}})
- return ret
- @depends(HAS_ESX_CLI)
- def set_coredump_network_config(host,
- username,
- password,
- dump_ip,
- protocol=None,
- port=None,
- host_vnic='vmk0',
- dump_port=6500,
- esxi_hosts=None,
- credstore=None):
- '''
- Set the network parameters for a network coredump collection.
- Note that ESXi requires that the dumps first be enabled (see
- `coredump_network_enable`) before these parameters may be set.
- host
- The location of the host.
- username
- The username used to login to the host, such as ``root``.
- password
- The password used to login to the host.
- dump_ip
- IP address of host that will accept the dump.
- protocol
- Optionally set to alternate protocol if the host is not using the default
- protocol. Default protocol is ``https``.
- port
- Optionally set to alternate port if the host is not using the default
- port. Default port is ``443``.
- esxi_hosts
- If ``host`` is a vCenter host, then use esxi_hosts to execute this function
- on a list of one or more ESXi machines.
- host_vnic
- Host VNic port through which to communicate. Defaults to ``vmk0``.
- dump_port
- TCP port to use for the dump, defaults to ``6500``.
- credstore
- Optionally set to path to the credential store file.
- :return: A standard cmd.run_all dictionary with a `success` key added, per host.
- `success` will be True if the set succeeded, False otherwise.
- CLI Example:
- .. code-block:: bash
- # Used for ESXi host connection information
- salt '*' vsphere.set_coredump_network_config my.esxi.host root bad-password 'dump_ip.host.com'
- # Used for connecting to a vCenter Server
- salt '*' vsphere.set_coredump_network_config my.vcenter.location root bad-password 'dump_ip.host.com' \
- esxi_hosts='[esxi-1.host.com, esxi-2.host.com]'
- '''
- cmd = 'system coredump network set -v {0} -i {1} -o {2}'.format(host_vnic,
- dump_ip,
- dump_port)
- ret = {}
- if esxi_hosts:
- if not isinstance(esxi_hosts, list):
- raise CommandExecutionError('\'esxi_hosts\' must be a list.')
- for esxi_host in esxi_hosts:
- response = salt.utils.vmware.esxcli(host, username, password, cmd,
- protocol=protocol, port=port,
- esxi_host=esxi_host, credstore=credstore)
- if response['retcode'] != 0:
- response['success'] = False
- else:
- response['success'] = True
- # Update the cmd.run_all dictionary for each particular host.
- ret.update({esxi_host: response})
- else:
- # Handles a single host or a vCenter connection when no esxi_hosts are provided.
- response = salt.utils.vmware.esxcli(host, username, password, cmd,
- protocol=protocol, port=port,
- credstore=credstore)
- if response['retcode'] != 0:
- response['success'] = False
- else:
- response['success'] = True
- ret.update({host: response})
- return ret
- @depends(HAS_ESX_CLI)
- def get_firewall_status(host, username, password, protocol=None, port=None, esxi_hosts=None, credstore=None):
- '''
- Show status of all firewall rule sets.
- host
- The location of the host.
- username
- The username used to login to the host, such as ``root``.
- password
- The password used to login to the host.
- protocol
- Optionally set to alternate protocol if the host is not using the default
- protocol. Default protocol is ``https``.
- port
- Optionally set to alternate port if the host is not using the default
- port. Default port is ``443``.
- esxi_hosts
- If ``host`` is a vCenter host, then use esxi_hosts to execute this function
- on a list of one or more ESXi machines.
- credstore
- Optionally set to path to the credential store file.
- :return: Nested dictionary with two toplevel keys ``rulesets`` and ``success``
- ``success`` will be True or False depending on query success
- ``rulesets`` will list the rulesets and their statuses if ``success``
- was true, per host.
- CLI Example:
- .. code-block:: bash
- # Used for ESXi host connection information
- salt '*' vsphere.get_firewall_status my.esxi.host root bad-password
- # Used for connecting to a vCenter Server
- salt '*' vsphere.get_firewall_status my.vcenter.location root bad-password \
- esxi_hosts='[esxi-1.host.com, esxi-2.host.com]'
- '''
- cmd = 'network firewall ruleset list'
- ret = {}
- if esxi_hosts:
- if not isinstance(esxi_hosts, list):
- raise CommandExecutionError('\'esxi_hosts\' must be a list.')
- for esxi_host in esxi_hosts:
- response = salt.utils.vmware.esxcli(host, username, password, cmd,
- protocol=protocol, port=port,
- esxi_host=esxi_host, credstore=credstore)
- if response['retcode'] != 0:
- ret.update({esxi_host: {'Error': response['stdout'],
- 'success': False,
- 'rulesets': None}})
- else:
- # format the response stdout into something useful
- ret.update({esxi_host: _format_firewall_stdout(response)})
- else:
- # Handles a single host or a vCenter connection when no esxi_hosts are provided.
- response = salt.utils.vmware.esxcli(host, username, password, cmd,
- protocol=protocol, port=port,
- credstore=credstore)
- if response['retcode'] != 0:
- ret.update({host: {'Error': response['stdout'],
- 'success': False,
- 'rulesets': None}})
- else:
- # format the response stdout into something useful
- ret.update({host: _format_firewall_stdout(response)})
- return ret
- @depends(HAS_ESX_CLI)
- def enable_firewall_ruleset(host,
- username,
- password,
- ruleset_enable,
- ruleset_name,
- protocol=None,
- port=None,
- esxi_hosts=None,
- credstore=None):
- '''
- Enable or disable an ESXi firewall rule set.
- host
- The location of the host.
- username
- The username used to login to the host, such as ``root``.
- password
- The password used to login to the host.
- ruleset_enable
- True to enable the ruleset, false to disable.
- ruleset_name
- Name of ruleset to target.
- protocol
- Optionally set to alternate protocol if the host is not using the default
- protocol. Default protocol is ``https``.
- port
- Optionally set to alternate port if the host is not using the default
- port. Default port is ``443``.
- esxi_hosts
- If ``host`` is a vCenter host, then use esxi_hosts to execute this function
- on a list of one or more ESXi machines.
- credstore
- Optionally set to path to the credential store file.
- :return: A standard cmd.run_all dictionary, per host.
- CLI Example:
- .. code-block:: bash
- # Used for ESXi host connection information
- salt '*' vsphere.enable_firewall_ruleset my.esxi.host root bad-password True 'syslog'
- # Used for connecting to a vCenter Server
- salt '*' vsphere.enable_firewall_ruleset my.vcenter.location root bad-password True 'syslog' \
- esxi_hosts='[esxi-1.host.com, esxi-2.host.com]'
- '''
- cmd = 'network firewall ruleset set --enabled {0} --ruleset-id={1}'.format(
- ruleset_enable, ruleset_name
- )
- ret = {}
- if esxi_hosts:
- if not isinstance(esxi_hosts, list):
- raise CommandExecutionError('\'esxi_hosts\' must be a list.')
- for esxi_host in esxi_hosts:
- response = salt.utils.vmware.esxcli(host, username, password, cmd,
- protocol=protocol, port=port,
- esxi_host=esxi_host, credstore=credstore)
- ret.update({esxi_host: response})
- else:
- # Handles a single host or a vCenter connection when no esxi_hosts are provided.
- response = salt.utils.vmware.esxcli(host, username, password, cmd,
- protocol=protocol, port=port,
- credstore=credstore)
- ret.update({host: response})
- return ret
- @depends(HAS_ESX_CLI)
- def syslog_service_reload(host, username, password, protocol=None, port=None, esxi_hosts=None, credstore=None):
- '''
- Reload the syslog service so it will pick up any changes.
- host
- The location of the host.
- username
- The username used to login to the host, such as ``root``.
- password
- The password used to login to the host.
- protocol
- Optionally set to alternate protocol if the host is not using the default
- protocol. Default protocol is ``https``.
- port
- Optionally set to alternate port if the host is not using the default
- port. Default port is ``443``.
- esxi_hosts
- If ``host`` is a vCenter host, then use esxi_hosts to execute this function
- on a list of one or more ESXi machines.
- credstore
- Optionally set to path to the credential store file.
- :return: A standard cmd.run_all dictionary. This dictionary will at least
- have a `retcode` key. If `retcode` is 0 the command was successful.
- CLI Example:
- .. code-block:: bash
- # Used for ESXi host connection information
- salt '*' vsphere.syslog_service_reload my.esxi.host root bad-password
- # Used for connecting to a vCenter Server
- salt '*' vsphere.syslog_service_reload my.vcenter.location root bad-password \
- esxi_hosts='[esxi-1.host.com, esxi-2.host.com]'
- '''
- cmd = 'system syslog reload'
- ret = {}
- if esxi_hosts:
- if not isinstance(esxi_hosts, list):
- raise CommandExecutionError('\'esxi_hosts\' must be a list.')
- for esxi_host in esxi_hosts:
- response = salt.utils.vmware.esxcli(host, username, password, cmd,
- protocol=protocol, port=port,
- esxi_host=esxi_host, credstore=credstore)
- ret.update({esxi_host: response})
- else:
- # Handles a single host or a vCenter connection when no esxi_hosts are provided.
- response = salt.utils.vmware.esxcli(host, username, password, cmd,
- protocol=protocol, port=port,
- credstore=credstore)
- ret.update({host: response})
- return ret
- @depends(HAS_ESX_CLI)
- def set_syslog_config(host,
- username,
- password,
- syslog_config,
- config_value,
- protocol=None,
- port=None,
- firewall=True,
- reset_service=True,
- esxi_hosts=None,
- credstore=None):
- '''
- Set the specified syslog configuration parameter. By default, this function will
- reset the syslog service after the configuration is set.
- host
- ESXi or vCenter host to connect to.
- username
- User to connect as, usually root.
- password
- Password to connect with.
- syslog_config
- Name of parameter to set (corresponds to the command line switch for
- esxcli without the double dashes (--))
- Valid syslog_config values are ``logdir``, ``loghost``, ``default-rotate`,
- ``default-size``, ``default-timeout``, and ``logdir-unique``.
- config_value
- Value for the above parameter. For ``loghost``, URLs or IP addresses to
- use for logging. Multiple log servers can be specified by listing them,
- comma-separated, but without spaces before or after commas.
- (reference: https://blogs.vmware.com/vsphere/2012/04/configuring-multiple-syslog-servers-for-esxi-5.html)
- protocol
- Optionally set to alternate protocol if the host is not using the default
- protocol. Default protocol is ``https``.
- port
- Optionally set to alternate port if the host is not using the default
- port. Default port is ``443``.
- firewall
- Enable the firewall rule set for syslog. Defaults to ``True``.
- reset_service
- After a successful parameter set, reset the service. Defaults to ``True``.
- esxi_hosts
- If ``host`` is a vCenter host, then use esxi_hosts to execute this function
- on a list of one or more ESXi machines.
- credstore
- Optionally set to path to the credential store file.
- :return: Dictionary with a top-level key of 'success' which indicates
- if all the parameters were reset, and individual keys
- for each parameter indicating which succeeded or failed, per host.
- CLI Example:
- .. code-block:: bash
- # Used for ESXi host connection information
- salt '*' vsphere.set_syslog_config my.esxi.host root bad-password \
- loghost ssl://localhost:5432,tcp://10.1.0.1:1514
- # Used for connecting to a vCenter Server
- salt '*' vsphere.set_syslog_config my.vcenter.location root bad-password \
- loghost ssl://localhost:5432,tcp://10.1.0.1:1514 \
- esxi_hosts='[esxi-1.host.com, esxi-2.host.com]'
- '''
- ret = {}
- # First, enable the syslog firewall ruleset, for each host, if needed.
- if firewall and syslog_config == 'loghost':
- if esxi_hosts:
- if not isinstance(esxi_hosts, list):
- raise CommandExecutionError('\'esxi_hosts\' must be a list.')
- for esxi_host in esxi_hosts:
- response = enable_firewall_ruleset(host, username, password,
- ruleset_enable=True, ruleset_name='syslog',
- protocol=protocol, port=port,
- esxi_hosts=[esxi_host], credstore=credstore).get(esxi_host)
- if response['retcode'] != 0:
- ret.update({esxi_host: {'enable_firewall': {'message': response['stdout'],
- 'success': False}}})
- else:
- ret.update({esxi_host: {'enable_firewall': {'success': True}}})
- else:
- # Handles a single host or a vCenter connection when no esxi_hosts are provided.
- response = enable_firewall_ruleset(host, username, password,
- ruleset_enable=True, ruleset_name='syslog',
- protocol=protocol, port=port,
- credstore=credstore).get(host)
- if response['retcode'] != 0:
- ret.update({host: {'enable_firewall': {'message': response['stdout'],
- 'success': False}}})
- else:
- ret.update({host: {'enable_firewall': {'success': True}}})
- # Set the config value on each esxi_host, if provided.
- if esxi_hosts:
- if not isinstance(esxi_hosts, list):
- raise CommandExecutionError('\'esxi_hosts\' must be a list.')
- for esxi_host in esxi_hosts:
- response = _set_syslog_config_helper(host, username, password, syslog_config,
- config_value, protocol=protocol, port=port,
- reset_service=reset_service, esxi_host=esxi_host,
- credstore=credstore)
- # Ensure we don't overwrite any dictionary data already set
- # By updating the esxi_host directly.
- if ret.get(esxi_host) is None:
- ret.update({esxi_host: {}})
- ret[esxi_host].update(response)
- else:
- # Handles a single host or a vCenter connection when no esxi_hosts are provided.
- response = _set_syslog_config_helper(host, username, password, syslog_config,
- config_value, protocol=protocol, port=port,
- reset_service=reset_service, credstore=credstore)
- # Ensure we don't overwrite any dictionary data already set
- # By updating the host directly.
- if ret.get(host) is None:
- ret.update({host: {}})
- ret[host].update(response)
- return ret
- @depends(HAS_ESX_CLI)
- def get_syslog_config(host, username, password, protocol=None, port=None, esxi_hosts=None, credstore=None):
- '''
- Retrieve the syslog configuration.
- host
- The location of the host.
- username
- The username used to login to the host, such as ``root``.
- password
- The password used to login to the host.
- protocol
- Optionally set to alternate protocol if the host is not using the default
- protocol. Default protocol is ``https``.
- port
- Optionally set to alternate port if the host is not using the default
- port. Default port is ``443``.
- esxi_hosts
- If ``host`` is a vCenter host, then use esxi_hosts to execute this function
- on a list of one or more ESXi machines.
- credstore
- Optionally set to path to the credential store file.
- :return: Dictionary with keys and values corresponding to the
- syslog configuration, per host.
- CLI Example:
- .. code-block:: bash
- # Used for ESXi host connection information
- salt '*' vsphere.get_syslog_config my.esxi.host root bad-password
- # Used for connecting to a vCenter Server
- salt '*' vsphere.get_syslog_config my.vcenter.location root bad-password \
- esxi_hosts='[esxi-1.host.com, esxi-2.host.com]'
- '''
- cmd = 'system syslog config get'
- ret = {}
- if esxi_hosts:
- if not isinstance(esxi_hosts, list):
- raise CommandExecutionError('\'esxi_hosts\' must be a list.')
- for esxi_host in esxi_hosts:
- response = salt.utils.vmware.esxcli(host, username, password, cmd,
- protocol=protocol, port=port,
- esxi_host=esxi_host, credstore=credstore)
- # format the response stdout into something useful
- ret.update({esxi_host: _format_syslog_config(response)})
- else:
- # Handles a single host or a vCenter connection when no esxi_hosts are provided.
- response = salt.utils.vmware.esxcli(host, username, password, cmd,
- protocol=protocol, port=port,
- credstore=credstore)
- # format the response stdout into something useful
- ret.update({host: _format_syslog_config(response)})
- return ret
- @depends(HAS_ESX_CLI)
- def reset_syslog_config(host,
- username,
- password,
- protocol=None,
- port=None,
- syslog_config=None,
- esxi_hosts=None,
- credstore=None):
- '''
- Reset the syslog service to its default settings.
- Valid syslog_config values are ``logdir``, ``loghost``, ``logdir-unique``,
- ``default-rotate``, ``default-size``, ``default-timeout``,
- or ``all`` for all of these.
- host
- The location of the host.
- username
- The username used to login to the host, such as ``root``.
- password
- The password used to login to the host.
- protocol
- Optionally set to alternate protocol if the host is not using the default
- protocol. Default protocol is ``https``.
- port
- Optionally set to alternate port if the host is not using the default
- port. Default port is ``443``.
- syslog_config
- List of parameters to reset, provided as a comma-delimited string, or 'all' to
- reset all syslog configuration parameters. Required.
- esxi_hosts
- If ``host`` is a vCenter host, then use esxi_hosts to execute this function
- on a list of one or more ESXi machines.
- credstore
- Optionally set to path to the credential store file.
- :return: Dictionary with a top-level key of 'success' which indicates
- if all the parameters were reset, and individual keys
- for each parameter indicating which succeeded or failed, per host.
- CLI Example:
- ``syslog_config`` can be passed as a quoted, comma-separated string, e.g.
- .. code-block:: bash
- # Used for ESXi host connection information
- salt '*' vsphere.reset_syslog_config my.esxi.host root bad-password \
- syslog_config='logdir,loghost'
- # Used for connecting to a vCenter Server
- salt '*' vsphere.reset_syslog_config my.vcenter.location root bad-password \
- syslog_config='logdir,loghost' esxi_hosts='[esxi-1.host.com, esxi-2.host.com]'
- '''
- if not syslog_config:
- raise CommandExecutionError('The \'reset_syslog_config\' function requires a '
- '\'syslog_config\' setting.')
- valid_resets = ['logdir', 'loghost', 'default-rotate',
- 'default-size', 'default-timeout', 'logdir-unique']
- cmd = 'system syslog config set --reset='
- if ',' in syslog_config:
- resets = [ind_reset.strip() for ind_reset in syslog_config.split(',')]
- elif syslog_config == 'all':
- resets = valid_resets
- else:
- resets = [syslog_config]
- ret = {}
- if esxi_hosts:
- if not isinstance(esxi_hosts, list):
- raise CommandExecutionError('\'esxi_hosts\' must be a list.')
- for esxi_host in esxi_hosts:
- response_dict = _reset_syslog_config_params(host, username, password,
- cmd, resets, valid_resets,
- protocol=protocol, port=port,
- esxi_host=esxi_host, credstore=credstore)
- ret.update({esxi_host: response_dict})
- else:
- # Handles a single host or a vCenter connection when no esxi_hosts are provided.
- response_dict = _reset_syslog_config_params(host, username, password,
- cmd, resets, valid_resets,
- protocol=protocol, port=port,
- credstore=credstore)
- ret.update({host: response_dict})
- return ret
- @ignores_kwargs('credstore')
- def upload_ssh_key(host, username, password, ssh_key=None, ssh_key_file=None,
- protocol=None, port=None, certificate_verify=False):
- '''
- Upload an ssh key for root to an ESXi host via http PUT.
- This function only works for ESXi, not vCenter.
- Only one ssh key can be uploaded for root. Uploading a second key will
- replace any existing key.
- :param host: The location of the ESXi Host
- :param username: Username to connect as
- :param password: Password for the ESXi web endpoint
- :param ssh_key: Public SSH key, will be added to authorized_keys on ESXi
- :param ssh_key_file: File containing the SSH key. Use 'ssh_key' or
- ssh_key_file, but not both.
- :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
- :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.
- CLI Example:
- .. code-block:: bash
- salt '*' vsphere.upload_ssh_key my.esxi.host root bad-password ssh_key_file='/etc/salt/my_keys/my_key.pub'
- '''
- if protocol is None:
- protocol = 'https'
- if port is None:
- port = 443
- url = '{0}://{1}:{2}/host/ssh_root_authorized_keys'.format(protocol,
- host,
- port)
- ret = {}
- result = None
- try:
- if ssh_key:
- result = salt.utils.http.query(url,
- status=True,
- text=True,
- method='PUT',
- username=username,
- password=password,
- data=ssh_key,
- verify_ssl=certificate_verify)
- elif ssh_key_file:
- result = salt.utils.http.query(url,
- status=True,
- text=True,
- method='PUT',
- username=username,
- password=password,
- data_file=ssh_key_file,
- data_render=False,
- verify_ssl=certificate_verify)
- if result.get('status') == 200:
- ret['status'] = True
- else:
- ret['status'] = False
- ret['Error'] = result['error']
- except Exception as msg:
- ret['status'] = False
- ret['Error'] = msg
- return ret
- @ignores_kwargs('credstore')
- def get_ssh_key(host,
- username,
- password,
- protocol=None,
- port=None,
- certificate_verify=False):
- '''
- Retrieve the authorized_keys entry for root.
- This function only works for ESXi, not vCenter.
- :param host: The location of the ESXi Host
- :param username: Username to connect as
- :param password: Password for the ESXi web endpoint
- :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
- :return: True if upload is successful
- CLI Example:
- .. code-block:: bash
- salt '*' vsphere.get_ssh_key my.esxi.host root bad-password certificate_verify=True
- '''
- if protocol is None:
- protocol = 'https'
- if port is None:
- port = 443
- url = '{0}://{1}:{2}/host/ssh_root_authorized_keys'.format(protocol,
- host,
- port)
- ret = {}
- try:
- result = salt.utils.http.query(url,
- status…
Large files files are truncated, but you can click here to view the full file