mirror of
https://github.com/valitydev/salt.git
synced 2024-11-06 16:45:27 +00:00
Merge branch '2016.11' into '2017.7'
Conflicts: - pkg/windows/buildenv/salt.bat - salt/modules/pillar.py - salt/utils/openstack/nova.py - tests/unit/cloud/clouds/test_dimensiondata.py - tests/unit/cloud/clouds/test_gce.py
This commit is contained in:
commit
16a2747d7d
@ -8,4 +8,6 @@ Set SaltDir=%SaltDir:~0,-1%
|
||||
Set Python=%SaltDir%\bin\python.exe
|
||||
Set Script=%SaltDir%\bin\Scripts\salt-call
|
||||
|
||||
:: Launch Script
|
||||
"%Python%" "%Script%" %*
|
||||
|
||||
|
@ -8,4 +8,6 @@ Set SaltDir=%SaltDir:~0,-1%
|
||||
Set Python=%SaltDir%\bin\python.exe
|
||||
Set Script=%SaltDir%\bin\Scripts\salt-cp
|
||||
|
||||
:: Launch Script
|
||||
"%Python%" "%Script%" %*
|
||||
|
||||
|
13
pkg/windows/buildenv/salt-key.bat
Normal file
13
pkg/windows/buildenv/salt-key.bat
Normal file
@ -0,0 +1,13 @@
|
||||
@ echo off
|
||||
:: Script for invoking salt-key
|
||||
:: Accepts all parameters that salt-key accepts
|
||||
|
||||
:: Define Variables
|
||||
Set SaltDir=%~dp0
|
||||
Set SaltDir=%SaltDir:~0,-1%
|
||||
Set Python=%SaltDir%\bin\python.exe
|
||||
Set Script=%SaltDir%\bin\Scripts\salt-key
|
||||
|
||||
:: Launch Script
|
||||
"%Python%" "%Script%" %*
|
||||
|
13
pkg/windows/buildenv/salt-master.bat
Normal file
13
pkg/windows/buildenv/salt-master.bat
Normal file
@ -0,0 +1,13 @@
|
||||
@ echo off
|
||||
:: Script for starting the Salt-Master
|
||||
:: Accepts all parameters that Salt-Master accepts
|
||||
|
||||
:: Define Variables
|
||||
Set SaltDir=%~dp0
|
||||
Set SaltDir=%SaltDir:~0,-1%
|
||||
Set Python=%SaltDir%\bin\python.exe
|
||||
Set Script=%SaltDir%\bin\Scripts\salt-master
|
||||
|
||||
:: Launch Script
|
||||
"%Python%" "%Script%" %*
|
||||
|
@ -8,6 +8,9 @@ Set SaltDir=%SaltDir:~0,-1%
|
||||
Set Python=%SaltDir%\bin\python.exe
|
||||
Set Script=%SaltDir%\bin\Scripts\salt-minion
|
||||
|
||||
:: Stop the Salt Minion service
|
||||
net stop salt-minion
|
||||
|
||||
:: Launch Script
|
||||
"%Python%" "%Script%" -l debug
|
||||
|
||||
|
@ -1 +1,2 @@
|
||||
net start salt-minion
|
||||
:: Start the Salt Minion service
|
||||
net start salt-minion
|
||||
|
@ -8,4 +8,6 @@ Set SaltDir=%SaltDir:~0,-1%
|
||||
Set Python=%SaltDir%\bin\python.exe
|
||||
Set Script=%SaltDir%\bin\Scripts\salt-minion
|
||||
|
||||
:: Launch Script
|
||||
"%Python%" "%Script%" %*
|
||||
|
||||
|
13
pkg/windows/buildenv/salt-run.bat
Normal file
13
pkg/windows/buildenv/salt-run.bat
Normal file
@ -0,0 +1,13 @@
|
||||
@ echo off
|
||||
:: Script for invoking salt-run
|
||||
:: Accepts all parameters that salt-run accepts
|
||||
|
||||
:: Define Variables
|
||||
Set SaltDir=%~dp0
|
||||
Set SaltDir=%SaltDir:~0,-1%
|
||||
Set Python=%SaltDir%\bin\python.exe
|
||||
Set Script=%SaltDir%\bin\Scripts\salt-run
|
||||
|
||||
:: Launch Script
|
||||
"%Python%" "%Script%" %*
|
||||
|
@ -33,14 +33,20 @@ import salt.config as config
|
||||
from salt.cloud.libcloudfuncs import * # pylint: disable=redefined-builtin,wildcard-import,unused-wildcard-import
|
||||
from salt.utils import namespaced_function
|
||||
from salt.exceptions import SaltCloudSystemExit
|
||||
from distutils.version import LooseVersion as _LooseVersion
|
||||
|
||||
# CloudStackNetwork will be needed during creation of a new node
|
||||
# pylint: disable=import-error
|
||||
try:
|
||||
from libcloud.compute.drivers.cloudstack import CloudStackNetwork
|
||||
# See https://github.com/saltstack/salt/issues/32743
|
||||
import libcloud.security
|
||||
libcloud.security.CA_CERTS_PATH.append('/etc/ssl/certs/YaST-CA.pem')
|
||||
# This work-around for Issue #32743 is no longer needed for libcloud >= 1.4.0.
|
||||
# However, older versions of libcloud must still be supported with this work-around.
|
||||
# This work-around can be removed when the required minimum version of libcloud is
|
||||
# 2.0.0 (See PR #40837 - which is implemented in Salt Oxygen).
|
||||
if _LooseVersion(libcloud.__version__) < _LooseVersion('1.4.0'):
|
||||
# See https://github.com/saltstack/salt/issues/32743
|
||||
import libcloud.security
|
||||
libcloud.security.CA_CERTS_PATH.append('/etc/ssl/certs/YaST-CA.pem')
|
||||
HAS_LIBS = True
|
||||
except ImportError:
|
||||
HAS_LIBS = False
|
||||
|
@ -27,9 +27,11 @@ from __future__ import absolute_import
|
||||
import logging
|
||||
import socket
|
||||
import pprint
|
||||
from distutils.version import LooseVersion as _LooseVersion
|
||||
|
||||
# Import libcloud
|
||||
try:
|
||||
import libcloud
|
||||
from libcloud.compute.base import NodeState
|
||||
from libcloud.compute.base import NodeAuthPassword
|
||||
from libcloud.compute.types import Provider
|
||||
@ -37,9 +39,15 @@ try:
|
||||
from libcloud.loadbalancer.base import Member
|
||||
from libcloud.loadbalancer.types import Provider as Provider_lb
|
||||
from libcloud.loadbalancer.providers import get_driver as get_driver_lb
|
||||
# See https://github.com/saltstack/salt/issues/32743
|
||||
import libcloud.security
|
||||
libcloud.security.CA_CERTS_PATH.append('/etc/ssl/certs/YaST-CA.pem')
|
||||
|
||||
# This work-around for Issue #32743 is no longer needed for libcloud >= 1.4.0.
|
||||
# However, older versions of libcloud must still be supported with this work-around.
|
||||
# This work-around can be removed when the required minimum version of libcloud is
|
||||
# 2.0.0 (See PR #40837 - which is implemented in Salt Oxygen).
|
||||
if _LooseVersion(libcloud.__version__) < _LooseVersion('1.4.0'):
|
||||
# See https://github.com/saltstack/salt/issues/32743
|
||||
import libcloud.security
|
||||
libcloud.security.CA_CERTS_PATH.append('/etc/ssl/certs/YaST-CA.pem')
|
||||
HAS_LIBCLOUD = True
|
||||
except ImportError:
|
||||
HAS_LIBCLOUD = False
|
||||
|
@ -3963,7 +3963,46 @@ def volume_create(**kwargs):
|
||||
|
||||
def create_volume(kwargs=None, call=None, wait_to_finish=False):
|
||||
'''
|
||||
Create a volume
|
||||
Create a volume.
|
||||
|
||||
zone
|
||||
The availability zone used to create the volume. Required. String.
|
||||
|
||||
size
|
||||
The size of the volume, in GiBs. Defaults to ``10``. Integer.
|
||||
|
||||
snapshot
|
||||
The snapshot-id from which to create the volume. Integer.
|
||||
|
||||
type
|
||||
The volume type. This can be gp2 for General Purpose SSD, io1 for Provisioned
|
||||
IOPS SSD, st1 for Throughput Optimized HDD, sc1 for Cold HDD, or standard for
|
||||
Magnetic volumes. String.
|
||||
|
||||
iops
|
||||
The number of I/O operations per second (IOPS) to provision for the volume,
|
||||
with a maximum ratio of 50 IOPS/GiB. Only valid for Provisioned IOPS SSD
|
||||
volumes. Integer.
|
||||
|
||||
This option will only be set if ``type`` is also specified as ``io1``.
|
||||
|
||||
encrypted
|
||||
Specifies whether the volume will be encrypted. Boolean.
|
||||
|
||||
If ``snapshot`` is also given in the list of kwargs, then this value is ignored
|
||||
since volumes that are created from encrypted snapshots are also automatically
|
||||
encrypted.
|
||||
|
||||
tags
|
||||
The tags to apply to the volume during creation. Dictionary.
|
||||
|
||||
call
|
||||
The ``create_volume`` function must be called with ``-f`` or ``--function``.
|
||||
String.
|
||||
|
||||
wait_to_finish
|
||||
Whether or not to wait for the volume to be available. Boolean. Defaults to
|
||||
``False``.
|
||||
|
||||
CLI Examples:
|
||||
|
||||
|
@ -54,10 +54,12 @@ import pprint
|
||||
import logging
|
||||
import msgpack
|
||||
from ast import literal_eval
|
||||
from distutils.version import LooseVersion as _LooseVersion
|
||||
|
||||
# Import 3rd-party libs
|
||||
# pylint: disable=import-error
|
||||
try:
|
||||
import libcloud
|
||||
from libcloud.compute.types import Provider
|
||||
from libcloud.compute.providers import get_driver
|
||||
from libcloud.loadbalancer.types import Provider as Provider_lb
|
||||
@ -66,9 +68,14 @@ try:
|
||||
ResourceInUseError,
|
||||
ResourceNotFoundError,
|
||||
)
|
||||
# See https://github.com/saltstack/salt/issues/32743
|
||||
import libcloud.security
|
||||
libcloud.security.CA_CERTS_PATH.append('/etc/ssl/certs/YaST-CA.pem')
|
||||
# This work-around for Issue #32743 is no longer needed for libcloud >= 1.4.0.
|
||||
# However, older versions of libcloud must still be supported with this work-around.
|
||||
# This work-around can be removed when the required minimum version of libcloud is
|
||||
# 2.0.0 (See PR #40837 - which is implemented in Salt Oxygen).
|
||||
if _LooseVersion(libcloud.__version__) < _LooseVersion('1.4.0'):
|
||||
# See https://github.com/saltstack/salt/issues/32743
|
||||
import libcloud.security
|
||||
libcloud.security.CA_CERTS_PATH.append('/etc/ssl/certs/YaST-CA.pem')
|
||||
HAS_LIBCLOUD = True
|
||||
except ImportError:
|
||||
HAS_LIBCLOUD = False
|
||||
|
@ -711,14 +711,29 @@ def request_instance(vm_=None, call=None):
|
||||
search_global=False,
|
||||
default={})
|
||||
if floating_ip_conf.get('auto_assign', False):
|
||||
pool = floating_ip_conf.get('pool', 'public')
|
||||
floating_ip = None
|
||||
for fl_ip, opts in six.iteritems(conn.floating_ip_list()):
|
||||
if opts['fixed_ip'] is None and opts['pool'] == pool:
|
||||
floating_ip = fl_ip
|
||||
break
|
||||
if floating_ip is None:
|
||||
floating_ip = conn.floating_ip_create(pool)['ip']
|
||||
if floating_ip_conf.get('ip_address', None) is not None:
|
||||
ip_address = floating_ip_conf.get('ip_address', None)
|
||||
try:
|
||||
fl_ip_dict = conn.floating_ip_show(ip_address)
|
||||
floating_ip = fl_ip_dict['ip']
|
||||
except Exception as err:
|
||||
raise SaltCloudSystemExit(
|
||||
'Error assigning floating_ip for {0} on Nova\n\n'
|
||||
'The following exception was thrown by libcloud when trying to '
|
||||
'assign a floating ip: {1}\n'.format(
|
||||
vm_['name'], err
|
||||
)
|
||||
)
|
||||
|
||||
else:
|
||||
pool = floating_ip_conf.get('pool', 'public')
|
||||
for fl_ip, opts in six.iteritems(conn.floating_ip_list()):
|
||||
if opts['fixed_ip'] is None and opts['pool'] == pool:
|
||||
floating_ip = fl_ip
|
||||
break
|
||||
if floating_ip is None:
|
||||
floating_ip = conn.floating_ip_create(pool)['ip']
|
||||
|
||||
def __query_node_data(vm_):
|
||||
try:
|
||||
@ -765,7 +780,7 @@ def request_instance(vm_=None, call=None):
|
||||
raise SaltCloudSystemExit(
|
||||
'Error assigning floating_ip for {0} on Nova\n\n'
|
||||
'The following exception was thrown by libcloud when trying to '
|
||||
'assing a floating ip: {1}\n'.format(
|
||||
'assign a floating ip: {1}\n'.format(
|
||||
vm_['name'], exc
|
||||
)
|
||||
)
|
||||
|
@ -143,9 +143,11 @@ import os
|
||||
import logging
|
||||
import socket
|
||||
import pprint
|
||||
from distutils.version import LooseVersion as _LooseVersion
|
||||
|
||||
# Import libcloud
|
||||
try:
|
||||
import libcloud
|
||||
from libcloud.compute.base import NodeState
|
||||
HAS_LIBCLOUD = True
|
||||
except ImportError:
|
||||
@ -156,9 +158,14 @@ HAS014 = False
|
||||
try:
|
||||
from libcloud.compute.drivers.openstack import OpenStackNetwork
|
||||
from libcloud.compute.drivers.openstack import OpenStack_1_1_FloatingIpPool
|
||||
# See https://github.com/saltstack/salt/issues/32743
|
||||
import libcloud.security
|
||||
libcloud.security.CA_CERTS_PATH.append('/etc/ssl/certs/YaST-CA.pem')
|
||||
# This work-around for Issue #32743 is no longer needed for libcloud >= 1.4.0.
|
||||
# However, older versions of libcloud must still be supported with this work-around.
|
||||
# This work-around can be removed when the required minimum version of libcloud is
|
||||
# 2.0.0 (See PR #40837 - which is implemented in Salt Oxygen).
|
||||
if _LooseVersion(libcloud.__version__) < _LooseVersion('1.4.0'):
|
||||
# See https://github.com/saltstack/salt/issues/32743
|
||||
import libcloud.security
|
||||
libcloud.security.CA_CERTS_PATH.append('/etc/ssl/certs/YaST-CA.pem')
|
||||
HAS014 = True
|
||||
except Exception:
|
||||
pass
|
||||
|
@ -518,7 +518,7 @@ def _virtual(osdata):
|
||||
'\'virtual\' grain.'
|
||||
)
|
||||
# Check if enable_lspci is True or False
|
||||
if __opts__.get('enable_lspci', True) is False:
|
||||
if __opts__.get('enable_lspci', True) is True:
|
||||
# /proc/bus/pci does not exists, lspci will fail
|
||||
if os.path.exists('/proc/bus/pci'):
|
||||
_cmds += ['lspci']
|
||||
|
@ -4,6 +4,11 @@ Connection module for Amazon VPC
|
||||
|
||||
.. versionadded:: 2014.7.0
|
||||
|
||||
:depends:
|
||||
|
||||
- boto >= 2.8.0
|
||||
- boto3 >= 1.2.6
|
||||
|
||||
:configuration: This module accepts explicit VPC credentials but can also
|
||||
utilize IAM roles assigned to the instance through Instance Profiles.
|
||||
Dynamic credentials are then automatically obtained from AWS API and no
|
||||
@ -69,8 +74,6 @@ Connection module for Amazon VPC
|
||||
error:
|
||||
message: error message
|
||||
|
||||
:depends: boto
|
||||
|
||||
.. versionadded:: 2016.11.0
|
||||
|
||||
Functions to request, accept, delete and describe VPC peering connections.
|
||||
|
@ -30,6 +30,7 @@ log = logging.getLogger(__name__)
|
||||
def get(key,
|
||||
default=KeyError,
|
||||
merge=False,
|
||||
merge_nested_lists=None,
|
||||
delimiter=DEFAULT_TARGET_DELIM,
|
||||
pillarenv=None,
|
||||
saltenv=None):
|
||||
@ -54,7 +55,7 @@ def get(key,
|
||||
|
||||
pkg:apache
|
||||
|
||||
merge : False
|
||||
merge : ``False``
|
||||
If ``True``, the retrieved values will be merged into the passed
|
||||
default. When the default and the retrieved value are both
|
||||
dictionaries, the dictionaries will be recursively merged.
|
||||
@ -65,6 +66,18 @@ def get(key,
|
||||
then merging will be skipped and the retrieved value will be
|
||||
returned. Earlier releases raised an error in these cases.
|
||||
|
||||
merge_nested_lists
|
||||
If set to ``False``, lists nested within the retrieved pillar
|
||||
dictionary will *overwrite* lists in ``default``. If set to ``True``,
|
||||
nested lists will be *merged* into lists in ``default``. If unspecified
|
||||
(the default), this option is inherited from the
|
||||
:conf_minion:`pillar_merge_lists` minion config option.
|
||||
|
||||
.. note::
|
||||
This option is ignored when ``merge`` is set to ``False``.
|
||||
|
||||
.. versionadded:: 2016.11.6
|
||||
|
||||
delimiter
|
||||
Specify an alternate delimiter to use when traversing a nested dict.
|
||||
This is useful for when the desired key contains a colon. See CLI
|
||||
@ -104,7 +117,8 @@ def get(key,
|
||||
if not __opts__.get('pillar_raise_on_missing'):
|
||||
if default is KeyError:
|
||||
default = ''
|
||||
opt_merge_lists = __opts__.get('pillar_merge_lists', False)
|
||||
opt_merge_lists = __opts__.get('pillar_merge_lists', False) if \
|
||||
merge_nested_lists is None else merge_nested_lists
|
||||
pillar_dict = __pillar__ \
|
||||
if all(x is None for x in (saltenv, pillarenv)) \
|
||||
else items(saltenv=saltenv, pillarenv=pillarenv)
|
||||
|
@ -712,7 +712,7 @@ def bootstrap(version='develop',
|
||||
|
||||
.. versionchanged:: 2016.11.0
|
||||
|
||||
.. deprecated:: 2016.11.0
|
||||
.. deprecated:: Oxygen
|
||||
|
||||
script_args
|
||||
Any additional arguments that you want to pass to the script.
|
||||
|
@ -983,9 +983,12 @@ class State(object):
|
||||
errors.append('Missing "name" data')
|
||||
if data['name'] and not isinstance(data['name'], six.string_types):
|
||||
errors.append(
|
||||
'ID \'{0}\' in SLS \'{1}\' is not formed as a string, but is '
|
||||
'a {2}'.format(
|
||||
data['name'], data['__sls__'], type(data['name']).__name__)
|
||||
'ID \'{0}\' {1}is not formed as a string, but is a {2}'.format(
|
||||
data['name'],
|
||||
'in SLS \'{0}\' '.format(data['__sls__'])
|
||||
if '__sls__' in data else '',
|
||||
type(data['name']).__name__
|
||||
)
|
||||
)
|
||||
if errors:
|
||||
return errors
|
||||
|
@ -584,7 +584,8 @@ def extracted(name,
|
||||
|
||||
.. versionchanged:: 2016.11.0
|
||||
If omitted, the archive format will be guessed based on the value
|
||||
of the ``source`` argument.
|
||||
of the ``source`` argument. If the minion is running a release
|
||||
older than 2016.11.0, this option is required.
|
||||
|
||||
.. _tarfile: https://docs.python.org/2/library/tarfile.html
|
||||
.. _zipfile: https://docs.python.org/2/library/zipfile.html
|
||||
|
@ -5,11 +5,14 @@ Manage VPCs
|
||||
|
||||
.. versionadded:: 2015.8.0
|
||||
|
||||
:depends:
|
||||
|
||||
- boto >= 2.8.0
|
||||
- boto3 >= 1.2.6
|
||||
|
||||
Create and destroy VPCs. Be aware that this interacts with Amazon's services,
|
||||
and so may incur charges.
|
||||
|
||||
This module uses ``boto``, which can be installed via package, or pip.
|
||||
|
||||
This module accepts explicit vpc credentials but can also utilize
|
||||
IAM roles assigned to the instance through Instance Profiles. Dynamic
|
||||
credentials are then automatically obtained from AWS API and no further
|
||||
@ -147,6 +150,8 @@ import logging
|
||||
import salt.ext.six as six
|
||||
import salt.utils.dictupdate as dictupdate
|
||||
|
||||
__virtualname__ = 'boto_vpc'
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@ -154,7 +159,14 @@ def __virtual__():
|
||||
'''
|
||||
Only load if boto is available.
|
||||
'''
|
||||
return 'boto_vpc' if 'boto_vpc.exists' in __salt__ else False
|
||||
boto_version = '2.8.0'
|
||||
boto3_version = '1.2.6'
|
||||
if 'boto_vpc.exists' in __salt__:
|
||||
return __virtualname__
|
||||
else:
|
||||
return False, 'The following libraries are required to run the boto_vpc state module: ' \
|
||||
'boto >= {0} and boto3 >= {1}.'.format(boto_version,
|
||||
boto3_version)
|
||||
|
||||
|
||||
def present(name, cidr_block, instance_tenancy=None, dns_support=None,
|
||||
|
@ -2178,19 +2178,31 @@ def parse_docstring(docstring):
|
||||
return ret
|
||||
|
||||
|
||||
def print_cli(msg):
|
||||
def print_cli(msg, retries=10, step=0.01):
|
||||
'''
|
||||
Wrapper around print() that suppresses tracebacks on broken pipes (i.e.
|
||||
when salt output is piped to less and less is stopped prematurely).
|
||||
'''
|
||||
try:
|
||||
while retries:
|
||||
try:
|
||||
print(msg)
|
||||
except UnicodeEncodeError:
|
||||
print(msg.encode('utf-8'))
|
||||
except IOError as exc:
|
||||
if exc.errno != errno.EPIPE:
|
||||
raise
|
||||
try:
|
||||
print(msg)
|
||||
except UnicodeEncodeError:
|
||||
print(msg.encode('utf-8'))
|
||||
except IOError as exc:
|
||||
err = "{0}".format(exc)
|
||||
if exc.errno != errno.EPIPE:
|
||||
if (
|
||||
("temporarily unavailable" in err or
|
||||
exc.errno in (errno.EAGAIN,)) and
|
||||
retries
|
||||
):
|
||||
time.sleep(step)
|
||||
retries -= 1
|
||||
continue
|
||||
else:
|
||||
raise
|
||||
break
|
||||
|
||||
|
||||
def safe_walk(top, topdown=True, onerror=None, followlinks=True, _seen=None):
|
||||
|
@ -27,8 +27,13 @@ def update(dest, upd, recursive_update=True, merge_lists=False):
|
||||
on a manual merge (helpful for non-dict types like FunctionWrapper)
|
||||
|
||||
If merge_lists=True, will aggregate list object types instead of replace.
|
||||
This behavior is only activated when recursive_update=True. By default
|
||||
merge_lists=False.
|
||||
The list in ``upd`` is added to the list in ``dest``, so the resulting list
|
||||
is ``dest[key] + upd[key]``. This behavior is only activated when
|
||||
recursive_update=True. By default merge_lists=False.
|
||||
|
||||
.. versionchanged: 2016.11.6
|
||||
When merging lists, duplicate values are removed. Values already
|
||||
present in the ``dest`` list are not added from the ``upd`` list.
|
||||
'''
|
||||
if (not isinstance(dest, collections.Mapping)) \
|
||||
or (not isinstance(upd, collections.Mapping)):
|
||||
@ -50,7 +55,9 @@ def update(dest, upd, recursive_update=True, merge_lists=False):
|
||||
elif isinstance(dest_subkey, list) \
|
||||
and isinstance(val, list):
|
||||
if merge_lists:
|
||||
dest[key] = dest.get(key, []) + val
|
||||
merged = copy.deepcopy(dest_subkey)
|
||||
merged.extend([x for x in val if x not in merged])
|
||||
dest[key] = merged
|
||||
else:
|
||||
dest[key] = upd[key]
|
||||
else:
|
||||
|
@ -45,6 +45,7 @@ log = logging.getLogger(__name__)
|
||||
|
||||
# Version added to novaclient.client.Client function
|
||||
NOVACLIENT_MINVER = '2.6.1'
|
||||
NOVACLIENT_MAXVER = '6.0.1'
|
||||
|
||||
# dict for block_device_mapping_v2
|
||||
CLIENT_BDM2_KEYS = {
|
||||
@ -65,8 +66,12 @@ def check_nova():
|
||||
if HAS_NOVA:
|
||||
novaclient_ver = _LooseVersion(novaclient.__version__)
|
||||
min_ver = _LooseVersion(NOVACLIENT_MINVER)
|
||||
if novaclient_ver >= min_ver:
|
||||
max_ver = _LooseVersion(NOVACLIENT_MAXVER)
|
||||
if novaclient_ver >= min_ver and novaclient_ver <= max_ver:
|
||||
return HAS_NOVA
|
||||
elif novaclient_ver > max_ver:
|
||||
log.debug('Older novaclient version required. Maximum: {0}'.format(NOVACLIENT_MAXVER))
|
||||
return False
|
||||
log.debug('Newer novaclient version required. Minimum: {0}'.format(NOVACLIENT_MINVER))
|
||||
return False
|
||||
|
||||
@ -1145,7 +1150,14 @@ class SaltNova(object):
|
||||
floating_ips = nt_ks.floating_ips.list()
|
||||
for floating_ip in floating_ips:
|
||||
if floating_ip.ip == ip:
|
||||
return floating_ip
|
||||
response = {
|
||||
'ip': floating_ip.ip,
|
||||
'fixed_ip': floating_ip.fixed_ip,
|
||||
'id': floating_ip.id,
|
||||
'instance_id': floating_ip.instance_id,
|
||||
'pool': floating_ip.pool
|
||||
}
|
||||
return response
|
||||
return {}
|
||||
|
||||
def floating_ip_create(self, pool=None):
|
||||
|
@ -887,21 +887,28 @@ class Schedule(object):
|
||||
try:
|
||||
# Only attempt to return data to the master
|
||||
# if the scheduled job is running on a minion.
|
||||
if '__role' in self.opts and self.opts['__role'] == 'minion':
|
||||
if 'return_job' in data and not data['return_job']:
|
||||
pass
|
||||
else:
|
||||
# Send back to master so the job is included in the job list
|
||||
mret = ret.copy()
|
||||
mret['jid'] = 'req'
|
||||
if data.get('return_job') == 'nocache':
|
||||
# overwrite 'req' to signal to master that this job shouldn't be stored
|
||||
mret['jid'] = 'nocache'
|
||||
event = salt.utils.event.get_event('minion', opts=self.opts, listen=False)
|
||||
load = {'cmd': '_return', 'id': self.opts['id']}
|
||||
for key, value in six.iteritems(mret):
|
||||
load[key] = value
|
||||
event.fire_event(load, '__schedule_return')
|
||||
if 'return_job' in data and not data['return_job']:
|
||||
pass
|
||||
else:
|
||||
# Send back to master so the job is included in the job list
|
||||
mret = ret.copy()
|
||||
mret['jid'] = 'req'
|
||||
if data.get('return_job') == 'nocache':
|
||||
# overwrite 'req' to signal to master that
|
||||
# this job shouldn't be stored
|
||||
mret['jid'] = 'nocache'
|
||||
load = {'cmd': '_return', 'id': self.opts['id']}
|
||||
for key, value in six.iteritems(mret):
|
||||
load[key] = value
|
||||
|
||||
if '__role' in self.opts and self.opts['__role'] == 'minion':
|
||||
event = salt.utils.event.get_event('minion',
|
||||
opts=self.opts,
|
||||
listen=False)
|
||||
elif '__role' in self.opts and self.opts['__role'] == 'master':
|
||||
event = salt.utils.event.get_master_event(self.opts,
|
||||
self.opts['sock_dir'])
|
||||
event.fire_event(load, '__schedule_return')
|
||||
|
||||
log.debug('schedule.handle_func: Removing {0}'.format(proc_fn))
|
||||
os.unlink(proc_fn)
|
||||
|
@ -2,6 +2,7 @@
|
||||
'''For running command line executables with a timeout'''
|
||||
from __future__ import absolute_import
|
||||
|
||||
import shlex
|
||||
import subprocess
|
||||
import threading
|
||||
import salt.exceptions
|
||||
@ -40,13 +41,29 @@ class TimedProc(object):
|
||||
try:
|
||||
self.process = subprocess.Popen(args, **kwargs)
|
||||
except TypeError:
|
||||
str_args = []
|
||||
for arg in args:
|
||||
if not isinstance(arg, six.string_types):
|
||||
str_args.append(str(arg))
|
||||
else:
|
||||
str_args.append(arg)
|
||||
args = str_args
|
||||
if not kwargs.get('shell', False):
|
||||
if not isinstance(args, (list, tuple)):
|
||||
try:
|
||||
args = shlex.split(args)
|
||||
except AttributeError:
|
||||
args = shlex.split(str(args))
|
||||
str_args = []
|
||||
for arg in args:
|
||||
if not isinstance(arg, six.string_types):
|
||||
str_args.append(str(arg))
|
||||
else:
|
||||
str_args.append(arg)
|
||||
args = str_args
|
||||
else:
|
||||
if not isinstance(args, (list, tuple, six.string_types)):
|
||||
# Handle corner case where someone does a 'cmd.run 3'
|
||||
args = str(args)
|
||||
# Ensure that environment variables are strings
|
||||
for key, val in six.iteritems(kwargs.get('env', {})):
|
||||
if not isinstance(val, six.string_types):
|
||||
kwargs['env'][key] = str(val)
|
||||
if not isinstance(key, six.string_types):
|
||||
kwargs['env'][str(key)] = kwargs['env'].pop(key)
|
||||
self.process = subprocess.Popen(args, **kwargs)
|
||||
self.command = args
|
||||
|
||||
|
@ -31,8 +31,13 @@ VM_NAME = 'winterfell'
|
||||
# Use certifi if installed
|
||||
try:
|
||||
if HAS_LIBCLOUD:
|
||||
import certifi
|
||||
libcloud.security.CA_CERTS_PATH.append(certifi.where())
|
||||
# This work-around for Issue #32743 is no longer needed for libcloud >= 1.4.0.
|
||||
# However, older versions of libcloud must still be supported with this work-around.
|
||||
# This work-around can be removed when the required minimum version of libcloud is
|
||||
# 2.0.0 (See PR #40837 - which is implemented in Salt Oxygen).
|
||||
if LooseVersion(libcloud.__version__) < LooseVersion('1.4.0'):
|
||||
import certifi
|
||||
libcloud.security.CA_CERTS_PATH.append(certifi.where())
|
||||
except (ImportError, NameError):
|
||||
pass
|
||||
|
||||
|
@ -36,8 +36,13 @@ DUMMY_TOKEN = {
|
||||
# Use certifi if installed
|
||||
try:
|
||||
if HAS_LIBCLOUD:
|
||||
import certifi
|
||||
libcloud.security.CA_CERTS_PATH.append(certifi.where())
|
||||
# This work-around for Issue #32743 is no longer needed for libcloud >= 1.4.0.
|
||||
# However, older versions of libcloud must still be supported with this work-around.
|
||||
# This work-around can be removed when the required minimum version of libcloud is
|
||||
# 2.0.0 (See PR #40837 - which is implemented in Salt Oxygen).
|
||||
if LooseVersion(libcloud.__version__) < LooseVersion('1.4.0'):
|
||||
import certifi
|
||||
libcloud.security.CA_CERTS_PATH.append(certifi.where())
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
|
@ -39,6 +39,14 @@ class UtilDictupdateTestCase(TestCase):
|
||||
mdict['A'] = [1, 2, 3, 4]
|
||||
self.assertEqual(res, mdict)
|
||||
|
||||
# level 1 value changes (list merge, remove duplicates, preserve order)
|
||||
mdict = copy.deepcopy(self.dict1)
|
||||
mdict['A'] = [1, 2]
|
||||
res = dictupdate.update(copy.deepcopy(mdict), {'A': [4, 3, 2, 1]},
|
||||
merge_lists=True)
|
||||
mdict['A'] = [1, 2, 4, 3]
|
||||
self.assertEqual(res, mdict)
|
||||
|
||||
# level 2 value changes
|
||||
mdict = copy.deepcopy(self.dict1)
|
||||
mdict['C']['D'] = 'Z'
|
||||
@ -61,6 +69,15 @@ class UtilDictupdateTestCase(TestCase):
|
||||
mdict['C']['D'] = ['a', 'b', 'c', 'd']
|
||||
self.assertEqual(res, mdict)
|
||||
|
||||
# level 2 value changes (list merge, remove duplicates, preserve order)
|
||||
mdict = copy.deepcopy(self.dict1)
|
||||
mdict['C']['D'] = ['a', 'b']
|
||||
res = dictupdate.update(copy.deepcopy(mdict),
|
||||
{'C': {'D': ['d', 'c', 'b', 'a']}},
|
||||
merge_lists=True)
|
||||
mdict['C']['D'] = ['a', 'b', 'd', 'c']
|
||||
self.assertEqual(res, mdict)
|
||||
|
||||
# level 3 value changes
|
||||
mdict = copy.deepcopy(self.dict1)
|
||||
mdict['C']['F']['G'] = 'Z'
|
||||
@ -86,6 +103,14 @@ class UtilDictupdateTestCase(TestCase):
|
||||
mdict['C']['F']['G'] = ['a', 'b', 'c', 'd']
|
||||
self.assertEqual(res, mdict)
|
||||
|
||||
# level 3 value changes (list merge, remove duplicates, preserve order)
|
||||
mdict = copy.deepcopy(self.dict1)
|
||||
mdict['C']['F']['G'] = ['a', 'b']
|
||||
res = dictupdate.update(copy.deepcopy(mdict),
|
||||
{'C': {'F': {'G': ['d', 'c', 'b', 'a']}}}, merge_lists=True)
|
||||
mdict['C']['F']['G'] = ['a', 'b', 'd', 'c']
|
||||
self.assertEqual(res, mdict)
|
||||
|
||||
# replace a sub-dictionary
|
||||
mdict = copy.deepcopy(self.dict1)
|
||||
mdict['C'] = 'Z'
|
||||
|
Loading…
Reference in New Issue
Block a user