mirror of
https://github.com/valitydev/salt.git
synced 2024-11-08 09:23:56 +00:00
Merge branch 'develop' into add-aptly-exec-module
This commit is contained in:
commit
e6aba8a7c2
4
.github/stale.yml
vendored
4
.github/stale.yml
vendored
@ -1,8 +1,8 @@
|
||||
# Probot Stale configuration file
|
||||
|
||||
# Number of days of inactivity before an issue becomes stale
|
||||
# 1100 is approximately 3 years
|
||||
daysUntilStale: 1100
|
||||
# 1075 is approximately 2 years and 11 months
|
||||
daysUntilStale: 1075
|
||||
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilClose: 7
|
||||
|
@ -4,6 +4,11 @@
|
||||
"name": "ryan-lane",
|
||||
"files": ["salt/**/*boto*.py"],
|
||||
"skipTeamPrs": false
|
||||
},
|
||||
{
|
||||
"name": "tkwilliams",
|
||||
"files": ["salt/**/*boto*.py"],
|
||||
"skipTeamPrs": false
|
||||
}
|
||||
],
|
||||
"skipTitle": "Merge forward",
|
||||
|
12
README.rst
12
README.rst
@ -67,10 +67,11 @@ Engage SaltStack
|
||||
|
||||
`SaltConf`_, **User Groups and Meetups** - SaltStack has a vibrant and `global
|
||||
community`_ of customers, users, developers and enthusiasts. Connect with other
|
||||
Salted folks in your area of the world, or join `SaltConf16`_, the SaltStack
|
||||
annual user conference, April 19-21 in Salt Lake City. Please let us know if
|
||||
you would like to start a user group or if we should add your existing
|
||||
SaltStack user group to this list by emailing: info@saltstack.com
|
||||
Salted folks in your area of the world, or join `SaltConf`_, the SaltStack
|
||||
annual user conference held in Salt Lake City. Please visit the `SaltConf`_ site
|
||||
for details of our next conference. Also, please let us know if you would like
|
||||
to start a user group or if we should add your existing SaltStack user group to
|
||||
this list by emailing: info@saltstack.com
|
||||
|
||||
**SaltStack Training** - Get access to proprietary `SaltStack education
|
||||
offerings`_ through instructor-led training offered on-site, virtually or at
|
||||
@ -89,9 +90,8 @@ services`_ offerings.
|
||||
* LinkedIn Group - `<https://www.linkedin.com/groups/4877160>`_
|
||||
* Google+ - `<https://plus.google.com/b/112856352920437801867/+SaltStackInc/posts>`_
|
||||
|
||||
.. _SaltConf: http://www.youtube.com/user/saltstack
|
||||
.. _global community: http://www.meetup.com/pro/saltstack/
|
||||
.. _SaltConf16: http://saltconf.com/
|
||||
.. _SaltConf: http://saltconf.com/
|
||||
.. _SaltStack education offerings: http://saltstack.com/training/
|
||||
.. _SaltStack Certified Engineer (SSCE): http://saltstack.com/certification/
|
||||
.. _SaltStack professional services: http://saltstack.com/services/
|
||||
|
@ -260,6 +260,13 @@ The Salt development team will back-port bug fixes made to ``develop`` to the
|
||||
current release branch if the contributor cannot create the pull request
|
||||
against that branch.
|
||||
|
||||
Release Branches
|
||||
----------------
|
||||
|
||||
For each release a branch will be created when we are ready to tag. The branch will be the same name as the tag minus the v. For example, the v2017.7.1 release was created from the 2017.7.1 branch. This branching strategy will allow for more stability when there is a need for a re-tag during the testing phase of our releases.
|
||||
|
||||
Once the branch is created, the fixes required for a given release, as determined by the SaltStack release team, will be added to this branch. All commits in this branch will be merged forward into the parent branch as well.
|
||||
|
||||
Keeping Salt Forks in Sync
|
||||
==========================
|
||||
|
||||
|
@ -143,19 +143,6 @@ def _reconstruct_ppa_name(owner_name, ppa_name):
|
||||
return 'ppa:{0}/{1}'.format(owner_name, ppa_name)
|
||||
|
||||
|
||||
def _get_repo(**kwargs):
|
||||
'''
|
||||
Check the kwargs for either 'fromrepo' or 'repo' and return the value.
|
||||
'fromrepo' takes precedence over 'repo'.
|
||||
'''
|
||||
for key in ('fromrepo', 'repo'):
|
||||
try:
|
||||
return kwargs[key]
|
||||
except KeyError:
|
||||
pass
|
||||
return ''
|
||||
|
||||
|
||||
def _check_apt():
|
||||
'''
|
||||
Abort if python-apt is not installed
|
||||
@ -250,18 +237,11 @@ def latest_version(*names, **kwargs):
|
||||
'''
|
||||
refresh = salt.utils.is_true(kwargs.pop('refresh', True))
|
||||
show_installed = salt.utils.is_true(kwargs.pop('show_installed', False))
|
||||
|
||||
if 'repo' in kwargs:
|
||||
# Remember to kill _get_repo() too when removing this warning.
|
||||
salt.utils.versions.warn_until(
|
||||
'Hydrogen',
|
||||
'The \'repo\' argument to apt.latest_version is deprecated, and '
|
||||
'will be removed in Salt {version}. Please use \'fromrepo\' '
|
||||
'instead.'
|
||||
raise SaltInvocationError(
|
||||
'The \'repo\' argument is invalid, use \'fromrepo\' instead'
|
||||
)
|
||||
fromrepo = _get_repo(**kwargs)
|
||||
kwargs.pop('fromrepo', None)
|
||||
kwargs.pop('repo', None)
|
||||
fromrepo = kwargs.pop('fromrepo', None)
|
||||
cache_valid_time = kwargs.pop('cache_valid_time', 0)
|
||||
|
||||
if len(names) == 0:
|
||||
@ -1453,9 +1433,10 @@ def _get_upgradable(dist_upgrade=True, **kwargs):
|
||||
cmd.append('dist-upgrade')
|
||||
else:
|
||||
cmd.append('upgrade')
|
||||
fromrepo = _get_repo(**kwargs)
|
||||
if fromrepo:
|
||||
cmd.extend(['-o', 'APT::Default-Release={0}'.format(fromrepo)])
|
||||
try:
|
||||
cmd.extend(['-o', 'APT::Default-Release={0}'.format(kwargs['fromrepo'])])
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
call = __salt__['cmd.run_all'](cmd,
|
||||
python_shell=False,
|
||||
|
@ -202,45 +202,48 @@ def _get_snapshot_url(artifactory_url, repository, group_id, artifact_id, versio
|
||||
has_classifier = classifier is not None and classifier != ""
|
||||
|
||||
if snapshot_version is None:
|
||||
snapshot_version_metadata = _get_snapshot_version_metadata(artifactory_url=artifactory_url, repository=repository, group_id=group_id, artifact_id=artifact_id, version=version, headers=headers)
|
||||
try:
|
||||
snapshot_version_metadata = _get_snapshot_version_metadata(artifactory_url=artifactory_url, repository=repository, group_id=group_id, artifact_id=artifact_id, version=version, headers=headers)
|
||||
if packaging not in snapshot_version_metadata['snapshot_versions']:
|
||||
error_message = '''Cannot find requested packaging '{packaging}' in the snapshot version metadata.
|
||||
artifactory_url: {artifactory_url}
|
||||
repository: {repository}
|
||||
group_id: {group_id}
|
||||
artifact_id: {artifact_id}
|
||||
packaging: {packaging}
|
||||
classifier: {classifier}
|
||||
version: {version}'''.format(
|
||||
artifactory_url=artifactory_url,
|
||||
repository=repository,
|
||||
group_id=group_id,
|
||||
artifact_id=artifact_id,
|
||||
packaging=packaging,
|
||||
classifier=classifier,
|
||||
version=version)
|
||||
raise ArtifactoryError(error_message)
|
||||
|
||||
if packaging not in snapshot_version_metadata['snapshot_versions']:
|
||||
error_message = '''Cannot find requested packaging '{packaging}' in the snapshot version metadata.
|
||||
artifactory_url: {artifactory_url}
|
||||
repository: {repository}
|
||||
group_id: {group_id}
|
||||
artifact_id: {artifact_id}
|
||||
packaging: {packaging}
|
||||
classifier: {classifier}
|
||||
version: {version}'''.format(
|
||||
artifactory_url=artifactory_url,
|
||||
repository=repository,
|
||||
group_id=group_id,
|
||||
artifact_id=artifact_id,
|
||||
packaging=packaging,
|
||||
classifier=classifier,
|
||||
version=version)
|
||||
raise ArtifactoryError(error_message)
|
||||
if has_classifier and classifier not in snapshot_version_metadata['snapshot_versions']:
|
||||
error_message = '''Cannot find requested classifier '{classifier}' in the snapshot version metadata.
|
||||
artifactory_url: {artifactory_url}
|
||||
repository: {repository}
|
||||
group_id: {group_id}
|
||||
artifact_id: {artifact_id}
|
||||
packaging: {packaging}
|
||||
classifier: {classifier}
|
||||
version: {version}'''.format(
|
||||
artifactory_url=artifactory_url,
|
||||
repository=repository,
|
||||
group_id=group_id,
|
||||
artifact_id=artifact_id,
|
||||
packaging=packaging,
|
||||
classifier=classifier,
|
||||
version=version)
|
||||
raise ArtifactoryError(error_message)
|
||||
|
||||
if has_classifier and classifier not in snapshot_version_metadata['snapshot_versions']:
|
||||
error_message = '''Cannot find requested classifier '{classifier}' in the snapshot version metadata.
|
||||
artifactory_url: {artifactory_url}
|
||||
repository: {repository}
|
||||
group_id: {group_id}
|
||||
artifact_id: {artifact_id}
|
||||
packaging: {packaging}
|
||||
classifier: {classifier}
|
||||
version: {version}'''.format(
|
||||
artifactory_url=artifactory_url,
|
||||
repository=repository,
|
||||
group_id=group_id,
|
||||
artifact_id=artifact_id,
|
||||
packaging=packaging,
|
||||
classifier=classifier,
|
||||
version=version)
|
||||
raise ArtifactoryError(error_message)
|
||||
|
||||
snapshot_version = snapshot_version_metadata['snapshot_versions'][packaging]
|
||||
snapshot_version = snapshot_version_metadata['snapshot_versions'][packaging]
|
||||
except CommandExecutionError as err:
|
||||
log.error('Could not fetch maven-metadata.xml. Assuming snapshot_version=%s.', version)
|
||||
snapshot_version = version
|
||||
|
||||
group_url = __get_group_id_subpath(group_id, use_literal_group_id)
|
||||
|
||||
|
@ -72,11 +72,20 @@ def __virtual__():
|
||||
return True
|
||||
|
||||
|
||||
def create_target_group(name, protocol, port, vpc_id,
|
||||
region=None, key=None, keyid=None, profile=None,
|
||||
health_check_protocol='HTTP', health_check_port='traffic-port',
|
||||
health_check_path='/', health_check_interval_seconds=30,
|
||||
health_check_timeout_seconds=5, healthy_threshold_count=5,
|
||||
def create_target_group(name,
|
||||
protocol,
|
||||
port,
|
||||
vpc_id,
|
||||
region=None,
|
||||
key=None,
|
||||
keyid=None,
|
||||
profile=None,
|
||||
health_check_protocol='HTTP',
|
||||
health_check_port='traffic-port',
|
||||
health_check_path='/',
|
||||
health_check_interval_seconds=30,
|
||||
health_check_timeout_seconds=5,
|
||||
healthy_threshold_count=5,
|
||||
unhealthy_threshold_count=2):
|
||||
'''
|
||||
Create target group if not present.
|
||||
@ -125,36 +134,40 @@ def create_target_group(name, protocol, port, vpc_id,
|
||||
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
|
||||
if target_group_exists(name, region, key, keyid, profile):
|
||||
return True
|
||||
else:
|
||||
try:
|
||||
lb = conn.create_target_group(Name=name, Protocol=protocol, Port=port,
|
||||
VpcId=vpc_id, HealthCheckProtocol=health_check_protocol,
|
||||
HealthCheckPort=health_check_port,
|
||||
HealthCheckPath=health_check_path,
|
||||
HealthCheckIntervalSeconds=health_check_interval_seconds,
|
||||
HealthCheckTimeoutSeconds=health_check_timeout_seconds,
|
||||
HealthyThresholdCount=healthy_threshold_count,
|
||||
UnhealthyThresholdCount=unhealthy_threshold_count)
|
||||
if lb:
|
||||
log.info('Created ALB {0}: {1}'.format(name,
|
||||
lb['TargetGroups'][0]['TargetGroupArn']))
|
||||
return True
|
||||
else:
|
||||
log.error('Failed to create ALB {0}'.format(name))
|
||||
return False
|
||||
except ClientError as error:
|
||||
log.debug(error)
|
||||
log.error('Failed to create ALB {0}: {1}: {2}'.format(name,
|
||||
error.response['Error']['Code'],
|
||||
error.response['Error']['Message']))
|
||||
|
||||
try:
|
||||
alb = conn.create_target_group(Name=name, Protocol=protocol, Port=port,
|
||||
VpcId=vpc_id, HealthCheckProtocol=health_check_protocol,
|
||||
HealthCheckPort=health_check_port,
|
||||
HealthCheckPath=health_check_path,
|
||||
HealthCheckIntervalSeconds=health_check_interval_seconds,
|
||||
HealthCheckTimeoutSeconds=health_check_timeout_seconds,
|
||||
HealthyThresholdCount=healthy_threshold_count,
|
||||
UnhealthyThresholdCount=unhealthy_threshold_count)
|
||||
if alb:
|
||||
log.info('Created ALB {0}: {1}'.format(name,
|
||||
alb['TargetGroups'][0]['TargetGroupArn']))
|
||||
return True
|
||||
else:
|
||||
log.error('Failed to create ALB {0}'.format(name))
|
||||
return False
|
||||
except ClientError as error:
|
||||
log.debug(error)
|
||||
log.error('Failed to create ALB {0}: {1}: {2}'.format(name,
|
||||
error.response['Error']['Code'],
|
||||
error.response['Error']['Message']))
|
||||
|
||||
|
||||
def delete_target_group(name, region=None, key=None, keyid=None, profile=None):
|
||||
def delete_target_group(name,
|
||||
region=None,
|
||||
key=None,
|
||||
keyid=None,
|
||||
profile=None):
|
||||
'''
|
||||
Delete target group.
|
||||
|
||||
name
|
||||
(string) - The Amazon Resource Name (ARN) of the resource.
|
||||
(string) - Target Group Name or Amazon Resource Name (ARN).
|
||||
|
||||
returns
|
||||
(bool) - True on success, False on failure.
|
||||
@ -167,9 +180,20 @@ def delete_target_group(name, region=None, key=None, keyid=None, profile=None):
|
||||
'''
|
||||
conn = _get_conn(region=region, key=key, keyid=keyid, profile=profile)
|
||||
|
||||
if not target_group_exists(name, region, key, keyid, profile):
|
||||
return True
|
||||
|
||||
try:
|
||||
conn.delete_target_group(TargetGroupArn=name)
|
||||
log.info('Deleted target group {0}'.format(name))
|
||||
if name.startswith('arn:aws:elasticloadbalancing'):
|
||||
conn.delete_target_group(TargetGroupArn=name)
|
||||
log.info('Deleted target group {0}'.format(name))
|
||||
else:
|
||||
tg_info = conn.describe_target_groups(Names=[name])
|
||||
if len(tg_info['TargetGroups']) != 1:
|
||||
return False
|
||||
arn = tg_info['TargetGroups'][0]['TargetGroupArn']
|
||||
conn.delete_target_group(TargetGroupArn=arn)
|
||||
log.info('Deleted target group {0} ARN {1}'.format(name, arn))
|
||||
return True
|
||||
except ClientError as error:
|
||||
log.debug(error)
|
||||
@ -177,7 +201,11 @@ def delete_target_group(name, region=None, key=None, keyid=None, profile=None):
|
||||
return False
|
||||
|
||||
|
||||
def target_group_exists(name, region=None, key=None, keyid=None, profile=None):
|
||||
def target_group_exists(name,
|
||||
region=None,
|
||||
key=None,
|
||||
keyid=None,
|
||||
profile=None):
|
||||
'''
|
||||
Check to see if an target group exists.
|
||||
|
||||
@ -200,11 +228,16 @@ def target_group_exists(name, region=None, key=None, keyid=None, profile=None):
|
||||
log.warning('The target group does not exist in region {0}'.format(region))
|
||||
return False
|
||||
except ClientError as error:
|
||||
log.warning(error)
|
||||
log.warning('target_group_exists check for {0} returned: {1}'.format(name, error))
|
||||
return False
|
||||
|
||||
|
||||
def describe_target_health(name, targets=None, region=None, key=None, keyid=None, profile=None):
|
||||
def describe_target_health(name,
|
||||
targets=None,
|
||||
region=None,
|
||||
key=None,
|
||||
keyid=None,
|
||||
profile=None):
|
||||
'''
|
||||
Get the curret health check status for targets in a target group.
|
||||
|
||||
@ -234,8 +267,12 @@ def describe_target_health(name, targets=None, region=None, key=None, keyid=None
|
||||
return {}
|
||||
|
||||
|
||||
def register_targets(name, targets, region=None, key=None, keyid=None,
|
||||
profile=None):
|
||||
def register_targets(name,
|
||||
targets,
|
||||
region=None,
|
||||
key=None,
|
||||
keyid=None,
|
||||
profile=None):
|
||||
'''
|
||||
Register targets to a target froup of an ALB. ``targets`` is either a
|
||||
instance id string or a list of instance id's.
|
||||
@ -264,15 +301,18 @@ def register_targets(name, targets, region=None, key=None, keyid=None,
|
||||
registered_targets = conn.register_targets(TargetGroupArn=name, Targets=targetsdict)
|
||||
if registered_targets:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
return False
|
||||
except ClientError as error:
|
||||
log.warning(error)
|
||||
return False
|
||||
|
||||
|
||||
def deregister_targets(name, targets, region=None, key=None, keyid=None,
|
||||
profile=None):
|
||||
def deregister_targets(name,
|
||||
targets,
|
||||
region=None,
|
||||
key=None,
|
||||
keyid=None,
|
||||
profile=None):
|
||||
'''
|
||||
Deregister targets to a target froup of an ALB. ``targets`` is either a
|
||||
instance id string or a list of instance id's.
|
||||
@ -301,8 +341,7 @@ def deregister_targets(name, targets, region=None, key=None, keyid=None,
|
||||
registered_targets = conn.deregister_targets(TargetGroupArn=name, Targets=targetsdict)
|
||||
if registered_targets:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
return False
|
||||
except ClientError as error:
|
||||
log.warning(error)
|
||||
return False
|
||||
|
@ -23,6 +23,10 @@ import salt.utils.path
|
||||
import salt.utils.platform
|
||||
from salt.exceptions import CommandExecutionError
|
||||
|
||||
__func_alias__ = {
|
||||
'format_': 'format'
|
||||
}
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
HAS_HDPARM = salt.utils.path.which('hdparm') is not None
|
||||
|
@ -902,9 +902,14 @@ def compare_container(first, second, ignore=None):
|
||||
continue
|
||||
val1 = result1[conf_dict][item]
|
||||
val2 = result2[conf_dict].get(item)
|
||||
if item in ('OomKillDisable',):
|
||||
if item in ('OomKillDisable',) or (val1 is None or val2 is None):
|
||||
if bool(val1) != bool(val2):
|
||||
ret.setdefault(conf_dict, {})[item] = {'old': val1, 'new': val2}
|
||||
elif item == 'Image':
|
||||
image1 = inspect_image(val1)['Id']
|
||||
image2 = inspect_image(val2)['Id']
|
||||
if image1 != image2:
|
||||
ret.setdefault(conf_dict, {})[item] = {'old': image1, 'new': image2}
|
||||
else:
|
||||
if item == 'Links':
|
||||
val1 = _scrub_links(val1, first)
|
||||
@ -920,9 +925,14 @@ def compare_container(first, second, ignore=None):
|
||||
continue
|
||||
val1 = result1[conf_dict].get(item)
|
||||
val2 = result2[conf_dict][item]
|
||||
if item in ('OomKillDisable',):
|
||||
if item in ('OomKillDisable',) or (val1 is None or val2 is None):
|
||||
if bool(val1) != bool(val2):
|
||||
ret.setdefault(conf_dict, {})[item] = {'old': val1, 'new': val2}
|
||||
elif item == 'Image':
|
||||
image1 = inspect_image(val1)['Id']
|
||||
image2 = inspect_image(val2)['Id']
|
||||
if image1 != image2:
|
||||
ret.setdefault(conf_dict, {})[item] = {'old': image1, 'new': image2}
|
||||
else:
|
||||
if item == 'Links':
|
||||
val1 = _scrub_links(val1, first)
|
||||
|
@ -50,7 +50,152 @@ def __virtual__():
|
||||
'''
|
||||
Only load if boto is available.
|
||||
'''
|
||||
return 'boto_elbv2' if 'boto_elbv2.target_group_exists' in __salt__ else False
|
||||
if 'boto_elbv2.target_group_exists' in __salt__:
|
||||
return 'boto_elbv2'
|
||||
return (False, "The boto_elbv2 module cannot be loaded: boto3 library not found")
|
||||
|
||||
|
||||
def create_target_group(name, protocol, port, vpc_id,
|
||||
region=None, key=None, keyid=None, profile=None,
|
||||
health_check_protocol='HTTP', health_check_port='traffic-port',
|
||||
health_check_path='/', health_check_interval_seconds=30,
|
||||
health_check_timeout_seconds=5, healthy_threshold_count=5,
|
||||
unhealthy_threshold_count=2, **kwargs):
|
||||
|
||||
'''
|
||||
.. versionadded:: 2017.11.0
|
||||
|
||||
Create target group if not present.
|
||||
|
||||
name
|
||||
(string) - The name of the target group.
|
||||
protocol
|
||||
(string) - The protocol to use for routing traffic to the targets
|
||||
port
|
||||
(int) - The port on which the targets receive traffic. This port is used unless
|
||||
you specify a port override when registering the traffic.
|
||||
vpc_id
|
||||
(string) - The identifier of the virtual private cloud (VPC).
|
||||
health_check_protocol
|
||||
(string) - The protocol the load balancer uses when performing health check on
|
||||
targets. The default is the HTTP protocol.
|
||||
health_check_port
|
||||
(string) - The port the load balancer uses when performing health checks on
|
||||
targets. The default is 'traffic-port', which indicates the port on which each
|
||||
target receives traffic from the load balancer.
|
||||
health_check_path
|
||||
(string) - The ping path that is the destination on the targets for health
|
||||
checks. The default is /.
|
||||
health_check_interval_seconds
|
||||
(integer) - The approximate amount of time, in seconds, between health checks
|
||||
of an individual target. The default is 30 seconds.
|
||||
health_check_timeout_seconds
|
||||
(integer) - The amount of time, in seconds, during which no response from a
|
||||
target means a failed health check. The default is 5 seconds.
|
||||
healthy_threshold_count
|
||||
(integer) - The number of consecutive health checks successes required before
|
||||
considering an unhealthy target healthy. The default is 5.
|
||||
unhealthy_threshold_count
|
||||
(integer) - The number of consecutive health check failures required before
|
||||
considering a target unhealthy. The default is 2.
|
||||
|
||||
returns
|
||||
(bool) - True on success, False on failure.
|
||||
|
||||
CLI example:
|
||||
.. code-block:: yaml
|
||||
|
||||
create-target:
|
||||
boto_elb2.create_targets_group:
|
||||
- name: myALB
|
||||
- protocol: https
|
||||
- port: 443
|
||||
- vpc_id: myVPC
|
||||
'''
|
||||
ret = {'name': name, 'result': None, 'comment': '', 'changes': {}}
|
||||
|
||||
if __salt__['boto_elbv2.target_group_exists'](name, region, key, keyid, profile):
|
||||
ret['result'] = True
|
||||
ret['comment'] = 'Target Group {0} already exists'.format(name)
|
||||
return ret
|
||||
|
||||
if __opts__['test']:
|
||||
ret['comment'] = 'Target Group {0} will be created'.format(name)
|
||||
return ret
|
||||
|
||||
state = __salt__['boto_elbv2.create_target_group'](name,
|
||||
protocol,
|
||||
port,
|
||||
vpc_id,
|
||||
region=region,
|
||||
key=key,
|
||||
keyid=keyid,
|
||||
profile=profile,
|
||||
health_check_protocol=health_check_protocol,
|
||||
health_check_port=health_check_port,
|
||||
health_check_path=health_check_path,
|
||||
health_check_interval_seconds=health_check_interval_seconds,
|
||||
health_check_timeout_seconds=health_check_timeout_seconds,
|
||||
healthy_threshold_count=healthy_threshold_count,
|
||||
unhealthy_threshold_count=unhealthy_threshold_count,
|
||||
**kwargs)
|
||||
|
||||
if state:
|
||||
ret['changes']['target_group'] = name
|
||||
ret['result'] = True
|
||||
ret['comment'] = 'Target Group {0} created'.format(name)
|
||||
else:
|
||||
ret['result'] = False
|
||||
ret['comment'] = 'Target Group {0} creation failed'.format(name)
|
||||
return ret
|
||||
|
||||
|
||||
def delete_target_group(name, region=None, key=None, keyid=None, profile=None):
|
||||
'''
|
||||
Delete target group.
|
||||
|
||||
name
|
||||
(string) - The Amazon Resource Name (ARN) of the resource.
|
||||
|
||||
returns
|
||||
(bool) - True on success, False on failure.
|
||||
|
||||
CLI example:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
check-target:
|
||||
boto_elb2.delete_targets_group:
|
||||
- name: myALB
|
||||
- protocol: https
|
||||
- port: 443
|
||||
- vpc_id: myVPC
|
||||
'''
|
||||
ret = {'name': name, 'result': None, 'comment': '', 'changes': {}}
|
||||
|
||||
if not __salt__['boto_elbv2.target_group_exists'](name, region, key, keyid, profile):
|
||||
ret['result'] = True
|
||||
ret['comment'] = 'Target Group {0} does not exists'.format(name)
|
||||
return ret
|
||||
|
||||
if __opts__['test']:
|
||||
ret['comment'] = 'Target Group {0} will be deleted'.format(name)
|
||||
return ret
|
||||
|
||||
state = __salt__['boto_elbv2.delete_target_group'](name,
|
||||
region=region,
|
||||
key=key,
|
||||
keyid=keyid,
|
||||
profile=profile)
|
||||
|
||||
if state:
|
||||
ret['result'] = True
|
||||
ret['changes']['target_group'] = name
|
||||
ret['comment'] = 'Target Group {0} deleted'.format(name)
|
||||
else:
|
||||
ret['result'] = False
|
||||
ret['comment'] = 'Target Group {0} deletion failed'.format(name)
|
||||
return ret
|
||||
|
||||
|
||||
def targets_registered(name, targets, region=None, key=None, keyid=None,
|
||||
@ -77,10 +222,13 @@ def targets_registered(name, targets, region=None, key=None, keyid=None,
|
||||
- instance-id2
|
||||
'''
|
||||
ret = {'name': name, 'result': None, 'comment': '', 'changes': {}}
|
||||
tg = __salt__['boto_elbv2.target_group_exists'](name, region, key, keyid, profile)
|
||||
|
||||
if tg:
|
||||
health = __salt__['boto_elbv2.describe_target_health'](name, region=region, key=key, keyid=keyid, profile=profile)
|
||||
if __salt__['boto_elbv2.target_group_exists'](name, region, key, keyid, profile):
|
||||
health = __salt__['boto_elbv2.describe_target_health'](name,
|
||||
region=region,
|
||||
key=key,
|
||||
keyid=keyid,
|
||||
profile=profile)
|
||||
failure = False
|
||||
changes = False
|
||||
newhealth_mock = copy.copy(health)
|
||||
@ -99,10 +247,10 @@ def targets_registered(name, targets, region=None, key=None, keyid=None,
|
||||
else:
|
||||
state = __salt__['boto_elbv2.register_targets'](name,
|
||||
targets,
|
||||
region,
|
||||
key,
|
||||
keyid,
|
||||
profile)
|
||||
region=region,
|
||||
key=key,
|
||||
keyid=keyid,
|
||||
profile=profile)
|
||||
if state:
|
||||
changes = True
|
||||
ret['result'] = True
|
||||
@ -119,7 +267,11 @@ def targets_registered(name, targets, region=None, key=None, keyid=None,
|
||||
ret['changes']['new'] = newhealth_mock
|
||||
else:
|
||||
ret['comment'] = 'Target Group {0} has been changed'.format(name)
|
||||
newhealth = __salt__['boto_elbv2.describe_target_health'](name, region=region, key=key, keyid=keyid, profile=profile)
|
||||
newhealth = __salt__['boto_elbv2.describe_target_health'](name,
|
||||
region=region,
|
||||
key=key,
|
||||
keyid=keyid,
|
||||
profile=profile)
|
||||
ret['changes']['new'] = newhealth
|
||||
return ret
|
||||
else:
|
||||
@ -128,7 +280,7 @@ def targets_registered(name, targets, region=None, key=None, keyid=None,
|
||||
|
||||
|
||||
def targets_deregistered(name, targets, region=None, key=None, keyid=None,
|
||||
profile=None, **kwargs):
|
||||
profile=None, **kwargs):
|
||||
'''
|
||||
Remove targets to an Application Load Balancer target group.
|
||||
|
||||
@ -150,9 +302,12 @@ def targets_deregistered(name, targets, region=None, key=None, keyid=None,
|
||||
- instance-id2
|
||||
'''
|
||||
ret = {'name': name, 'result': None, 'comment': '', 'changes': {}}
|
||||
tg = __salt__['boto_elbv2.target_group_exists'](name, region, key, keyid, profile)
|
||||
if tg:
|
||||
health = __salt__['boto_elbv2.describe_target_health'](name, region=region, key=key, keyid=keyid, profile=profile)
|
||||
if __salt__['boto_elbv2.target_group_exists'](name, region, key, keyid, profile):
|
||||
health = __salt__['boto_elbv2.describe_target_health'](name,
|
||||
region=region,
|
||||
key=key,
|
||||
keyid=keyid,
|
||||
profile=profile)
|
||||
failure = False
|
||||
changes = False
|
||||
newhealth_mock = copy.copy(health)
|
||||
@ -168,11 +323,11 @@ def targets_deregistered(name, targets, region=None, key=None, keyid=None,
|
||||
newhealth_mock.update({target: "draining"})
|
||||
else:
|
||||
state = __salt__['boto_elbv2.deregister_targets'](name,
|
||||
targets,
|
||||
region,
|
||||
key,
|
||||
keyid,
|
||||
profile)
|
||||
targets,
|
||||
region=region,
|
||||
key=key,
|
||||
keyid=keyid,
|
||||
profile=profile)
|
||||
if state:
|
||||
changes = True
|
||||
ret['result'] = True
|
||||
@ -189,7 +344,11 @@ def targets_deregistered(name, targets, region=None, key=None, keyid=None,
|
||||
ret['changes']['new'] = newhealth_mock
|
||||
else:
|
||||
ret['comment'] = 'Target Group {0} has been changed'.format(name)
|
||||
newhealth = __salt__['boto_elbv2.describe_target_health'](name, region, key, keyid, profile)
|
||||
newhealth = __salt__['boto_elbv2.describe_target_health'](name,
|
||||
region=region,
|
||||
key=key,
|
||||
keyid=keyid,
|
||||
profile=profile)
|
||||
ret['changes']['new'] = newhealth
|
||||
return ret
|
||||
else:
|
||||
|
@ -627,7 +627,11 @@ def _clean_dir(root, keep, exclude_pat):
|
||||
while True:
|
||||
fn_ = os.path.dirname(fn_)
|
||||
real_keep.add(fn_)
|
||||
if fn_ in ['/', ''.join([os.path.splitdrive(fn_)[0], '\\\\'])]:
|
||||
if fn_ in [
|
||||
os.sep,
|
||||
''.join([os.path.splitdrive(fn_)[0], os.sep]),
|
||||
''.join([os.path.splitdrive(fn_)[0], os.sep, os.sep])
|
||||
]:
|
||||
break
|
||||
|
||||
def _delete_not_kept(nfn):
|
||||
|
@ -2238,13 +2238,18 @@ def detached(name,
|
||||
|
||||
local_commit_id = _get_local_rev_and_branch(target, user, password)[0]
|
||||
|
||||
if remote_rev_type is 'hash' \
|
||||
and __salt__['git.describe'](target,
|
||||
rev,
|
||||
user=user,
|
||||
password=password):
|
||||
# The rev is a hash and it exists locally so skip to checkout
|
||||
hash_exists_locally = True
|
||||
if remote_rev_type is 'hash':
|
||||
try:
|
||||
__salt__['git.describe'](target,
|
||||
rev,
|
||||
user=user,
|
||||
password=password,
|
||||
ignore_retcode=True)
|
||||
except CommandExecutionError:
|
||||
hash_exists_locally = False
|
||||
else:
|
||||
# The rev is a hash and it exists locally so skip to checkout
|
||||
hash_exists_locally = True
|
||||
else:
|
||||
# Check that remote is present and set to correct url
|
||||
remotes = __salt__['git.remotes'](target,
|
||||
|
@ -92,6 +92,13 @@ def managed(name,
|
||||
Use certain profiles to generate the config.
|
||||
If not specified, will use the platform default profile(s).
|
||||
|
||||
compliance_report: ``False``
|
||||
Return the compliance report in the comment.
|
||||
The compliance report structured object can be found however
|
||||
in the ``pchanges`` field of the output (not displayed on the CLI).
|
||||
|
||||
.. versionadded:: 2017.7.3
|
||||
|
||||
test: ``False``
|
||||
Dry run? If set as ``True``, will apply the config, discard
|
||||
and return the changes. Default: ``False`` and will commit
|
||||
@ -140,6 +147,7 @@ def managed(name,
|
||||
debug = kwargs.get('debug', False) or __opts__.get('debug', False)
|
||||
commit = kwargs.get('commit', True) or __opts__.get('commit', True)
|
||||
replace = kwargs.get('replace', False) or __opts__.get('replace', False)
|
||||
return_compliance_report = kwargs.get('compliance_report', False) or __opts__.get('compliance_report', False)
|
||||
profiles = kwargs.get('profiles', [])
|
||||
temp_file = __salt__['temp.file']()
|
||||
log.debug('Creating temp file: {0}'.format(temp_file))
|
||||
@ -180,7 +188,13 @@ def managed(name,
|
||||
log.debug('Loaded config result:')
|
||||
log.debug(loaded_changes)
|
||||
__salt__['file.remove'](temp_file)
|
||||
return salt.utils.napalm.loaded_ret(ret, loaded_changes, test, debug)
|
||||
loaded_changes['compliance_report'] = compliance_report
|
||||
return salt.utils.napalm.loaded_ret(ret,
|
||||
loaded_changes,
|
||||
test,
|
||||
debug,
|
||||
opts=__opts__,
|
||||
compliance_report=return_compliance_report)
|
||||
|
||||
|
||||
def configured(name,
|
||||
|
@ -1,6 +1,11 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
Some of the utils used by salt
|
||||
|
||||
NOTE: The dev team is working on splitting up this file for the Oxygen release.
|
||||
Please do not add any new functions to this file. New functions should be
|
||||
organized in other files under salt/utils/. Please consult the dev team if you
|
||||
are unsure where a new function should go.
|
||||
'''
|
||||
|
||||
# Import python libs
|
||||
|
@ -22,6 +22,7 @@ import importlib
|
||||
from functools import wraps
|
||||
|
||||
# Import Salt libs
|
||||
import salt.output
|
||||
import salt.utils.platform
|
||||
|
||||
# Import 3rd-party libs
|
||||
@ -432,58 +433,58 @@ def default_ret(name):
|
||||
return ret
|
||||
|
||||
|
||||
def loaded_ret(ret, loaded, test, debug):
|
||||
def loaded_ret(ret, loaded, test, debug, compliance_report=False, opts=None):
|
||||
'''
|
||||
Return the final state output.
|
||||
|
||||
ret
|
||||
The initial state output structure.
|
||||
|
||||
loaded
|
||||
The loaded dictionary.
|
||||
'''
|
||||
# Always get the comment
|
||||
ret.update({
|
||||
'comment': loaded.get('comment', '')
|
||||
})
|
||||
changes = {}
|
||||
pchanges = {}
|
||||
ret['comment'] = loaded['comment']
|
||||
if 'diff' in loaded:
|
||||
changes['diff'] = loaded['diff']
|
||||
pchanges['diff'] = loaded['diff']
|
||||
if 'compliance_report' in loaded:
|
||||
if compliance_report:
|
||||
changes['compliance_report'] = loaded['compliance_report']
|
||||
pchanges['compliance_report'] = loaded['compliance_report']
|
||||
if debug and 'loaded_config' in loaded:
|
||||
changes['loaded_config'] = loaded['loaded_config']
|
||||
pchanges['loaded_config'] = loaded['loaded_config']
|
||||
ret['pchanges'] = pchanges
|
||||
if changes.get('diff'):
|
||||
ret['comment'] = '{comment_base}\n\nConfiguration diff:\n\n{diff}'.format(comment_base=ret['comment'],
|
||||
diff=changes['diff'])
|
||||
if changes.get('loaded_config'):
|
||||
ret['comment'] = '{comment_base}\n\nLoaded config:\n\n{loaded_cfg}'.format(
|
||||
comment_base=ret['comment'],
|
||||
loaded_cfg=changes['loaded_config'])
|
||||
if changes.get('compliance_report'):
|
||||
ret['comment'] = '{comment_base}\n\nCompliance report:\n\n{compliance}'.format(
|
||||
comment_base=ret['comment'],
|
||||
compliance=salt.output.string_format(changes['compliance_report'], 'nested', opts=opts))
|
||||
if not loaded.get('result', False):
|
||||
# Failure of some sort
|
||||
return ret
|
||||
if debug:
|
||||
# Always check for debug
|
||||
pchanges.update({
|
||||
'loaded_config': loaded.get('loaded_config', '')
|
||||
})
|
||||
ret.update({
|
||||
"pchanges": pchanges
|
||||
})
|
||||
if not loaded.get('already_configured', True):
|
||||
# We're making changes
|
||||
pchanges.update({
|
||||
"diff": loaded.get('diff', '')
|
||||
})
|
||||
ret.update({
|
||||
'pchanges': pchanges
|
||||
})
|
||||
if test:
|
||||
for k, v in pchanges.items():
|
||||
ret.update({
|
||||
"comment": "{}:\n{}\n\n{}".format(k, v, ret.get("comment", ''))
|
||||
})
|
||||
ret.update({
|
||||
'result': None,
|
||||
})
|
||||
ret['result'] = None
|
||||
return ret
|
||||
# Not test, changes were applied
|
||||
ret.update({
|
||||
'result': True,
|
||||
'changes': pchanges,
|
||||
'comment': "Configuration changed!\n{}".format(ret.get('comment', ''))
|
||||
'changes': changes,
|
||||
'comment': "Configuration changed!\n{}".format(loaded['comment'])
|
||||
})
|
||||
return ret
|
||||
# No changes
|
||||
ret.update({
|
||||
'result': True
|
||||
'result': True,
|
||||
'changes': {}
|
||||
})
|
||||
return ret
|
||||
|
@ -104,8 +104,12 @@ def parse_pkginfo(line, osarch=None):
|
||||
if epoch not in ('(none)', '0'):
|
||||
version = ':'.join((epoch, version))
|
||||
|
||||
install_date = datetime.datetime.utcfromtimestamp(int(install_time)).isoformat() + "Z"
|
||||
install_date_time_t = int(install_time)
|
||||
if install_time:
|
||||
install_date = datetime.datetime.utcfromtimestamp(int(install_time)).isoformat() + "Z"
|
||||
install_date_time_t = int(install_time)
|
||||
else:
|
||||
install_date = None
|
||||
install_date_time_t = None
|
||||
|
||||
return pkginfo(name, version, arch, repoid, install_date, install_date_time_t)
|
||||
|
||||
|
@ -42,7 +42,7 @@ class NpmStateTest(ModuleCase, SaltReturnAssertsMixin):
|
||||
'''
|
||||
Determine if URL-referenced NPM module can be successfully installed.
|
||||
'''
|
||||
ret = self.run_state('npm.installed', name='git://github.com/request/request')
|
||||
ret = self.run_state('npm.installed', name='request/request#v2.81.1')
|
||||
self.assertSaltTrueReturn(ret)
|
||||
ret = self.run_state('npm.removed', name='git://github.com/request/request')
|
||||
self.assertSaltTrueReturn(ret)
|
||||
|
@ -722,3 +722,30 @@ class DockerTestCase(TestCase, LoaderModuleMockMixin):
|
||||
result = docker_mod.images()
|
||||
self.assertEqual(result,
|
||||
{'sha256:abcdefg': {'RepoTags': ['image:latest']}})
|
||||
|
||||
def test_compare_container_image_id_resolution(self):
|
||||
'''
|
||||
Test comparing two containers when one's inspect output is an ID and
|
||||
not formatted in image:tag notation.
|
||||
'''
|
||||
def _inspect_container_effect(id_):
|
||||
return {
|
||||
'container1': {'Config': {'Image': 'realimage:latest'},
|
||||
'HostConfig': {}},
|
||||
'container2': {'Config': {'Image': 'image_id'},
|
||||
'HostConfig': {}},
|
||||
}[id_]
|
||||
|
||||
def _inspect_image_effect(id_):
|
||||
return {
|
||||
'realimage:latest': {'Id': 'image_id'},
|
||||
'image_id': {'Id': 'image_id'},
|
||||
}[id_]
|
||||
|
||||
inspect_container_mock = MagicMock(side_effect=_inspect_container_effect)
|
||||
inspect_image_mock = MagicMock(side_effect=_inspect_image_effect)
|
||||
|
||||
with patch.object(docker_mod, 'inspect_container', inspect_container_mock):
|
||||
with patch.object(docker_mod, 'inspect_image', inspect_image_mock):
|
||||
ret = docker_mod.compare_container('container1', 'container2')
|
||||
self.assertEqual(ret, {})
|
||||
|
@ -13,33 +13,33 @@ from tests.support.unit import TestCase
|
||||
from tests.support.paths import CODE_DIR
|
||||
|
||||
EXCLUDED_DIRS = [
|
||||
'tests/pkg',
|
||||
'tests/perf',
|
||||
'tests/support',
|
||||
'tests/unit/utils/cache_mods',
|
||||
'tests/unit/modules/inspectlib',
|
||||
'tests/unit/modules/zypp/',
|
||||
'tests/unit/templates/files',
|
||||
'tests/integration/files/',
|
||||
'tests/integration/cloud/helpers',
|
||||
os.path.join('tests', 'pkg'),
|
||||
os.path.join('tests', 'perf'),
|
||||
os.path.join('tests', 'support'),
|
||||
os.path.join('tests', 'unit', 'utils', 'cache_mods'),
|
||||
os.path.join('tests', 'unit', 'modules', 'inspectlib'),
|
||||
os.path.join('tests', 'unit', 'modules', 'zypp'),
|
||||
os.path.join('tests', 'unit', 'templates', 'files'),
|
||||
os.path.join('tests', 'integration', 'files'),
|
||||
os.path.join('tests', 'integration', 'cloud', 'helpers'),
|
||||
]
|
||||
EXCLUDED_FILES = [
|
||||
'tests/eventlisten.py',
|
||||
'tests/buildpackage.py',
|
||||
'tests/saltsh.py',
|
||||
'tests/minionswarm.py',
|
||||
'tests/wheeltest.py',
|
||||
'tests/runtests.py',
|
||||
'tests/jenkins.py',
|
||||
'tests/salt-tcpdump.py',
|
||||
'tests/conftest.py',
|
||||
'tests/packdump.py',
|
||||
'tests/consist.py',
|
||||
'tests/modparser.py',
|
||||
'tests/committer_parser.py',
|
||||
'tests/zypp_plugin.py',
|
||||
'tests/unit/transport/mixins.py',
|
||||
'tests/integration/utils/testprogram.py',
|
||||
os.path.join('tests', 'eventlisten.py'),
|
||||
os.path.join('tests', 'buildpackage.py'),
|
||||
os.path.join('tests', 'saltsh.py'),
|
||||
os.path.join('tests', 'minionswarm.py'),
|
||||
os.path.join('tests', 'wheeltest.py'),
|
||||
os.path.join('tests', 'runtests.py'),
|
||||
os.path.join('tests', 'jenkins.py'),
|
||||
os.path.join('tests', 'salt-tcpdump.py'),
|
||||
os.path.join('tests', 'conftest.py'),
|
||||
os.path.join('tests', 'packdump.py'),
|
||||
os.path.join('tests', 'consist.py'),
|
||||
os.path.join('tests', 'modparser.py'),
|
||||
os.path.join('tests', 'committer_parser.py'),
|
||||
os.path.join('tests', 'zypp_plugin.py'),
|
||||
os.path.join('tests', 'unit', 'transport', 'mixins.py'),
|
||||
os.path.join('tests', 'integration', 'utils', 'testprogram.py'),
|
||||
]
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user