From 225fa5d09229bd673ea76f8b8bc8e7d8b50d2399 Mon Sep 17 00:00:00 2001 From: Toshio Kuratomi Date: Sat, 22 Jul 2017 18:15:46 -0700 Subject: [PATCH] Fix undefined variables, basestring usage, and some associated python3 issues --- contrib/inventory/apstra_aos.py | 10 +- contrib/inventory/rax.py | 4 +- contrib/inventory/vmware.py | 8 +- contrib/inventory/vmware_inventory.py | 31 +- hacking/conf2yaml.py | 124 ----- lib/ansible/constants.py | 8 +- lib/ansible/galaxy/login.py | 3 +- lib/ansible/module_utils/api.py | 3 +- lib/ansible/module_utils/netapp.py | 5 +- lib/ansible/module_utils/pycompat24.py | 5 +- lib/ansible/module_utils/vmware.py | 17 +- .../modules/cloud/amazon/ec2_vpc_endpoint.py | 3 +- .../modules/cloud/amazon/ec2_vpc_igw.py | 2 +- .../modules/cloud/amazon/ec2_vpc_net_facts.py | 6 +- .../modules/cloud/amazon/iam_policy.py | 10 +- .../modules/cloud/amazon/rds_param_group.py | 43 +- lib/ansible/modules/cloud/amazon/s3_sync.py | 17 +- .../cloud/azure/azure_rm_securitygroup.py | 7 +- .../modules/cloud/docker/docker_container.py | 17 +- .../modules/cloud/docker/docker_image.py | 12 +- .../modules/cloud/google/gcp_url_map.py | 16 +- lib/ansible/modules/cloud/google/gcspanner.py | 3 +- .../modules/cloud/lxc/lxc_container.py | 1 + lib/ansible/modules/cloud/misc/rhevm.py | 6 +- lib/ansible/modules/cloud/misc/virt_net.py | 3 +- .../openstack/os_keystone_domain_facts.py | 7 +- .../cloud/openstack/os_server_actions.py | 23 +- .../cloud/ovh/ovh_ip_loadbalancing_backend.py | 2 +- .../cloud/profitbricks/profitbricks.py | 34 +- .../cloud/profitbricks/profitbricks_volume.py | 26 +- lib/ansible/modules/cloud/rackspace/rax.py | 20 +- .../modules/cloud/rackspace/rax_clb_nodes.py | 4 +- .../modules/cloud/rackspace/rax_meta.py | 14 +- .../cloud/rackspace/rax_scaling_group.py | 16 +- lib/ansible/modules/cloud/smartos/vmadm.py | 25 +- lib/ansible/modules/cloud/softlayer/sl_vm.py | 26 +- lib/ansible/modules/cloud/vmware/vca_fw.py | 4 +- .../modules/cloud/vmware/vsphere_guest.py | 85 ++-- lib/ansible/modules/clustering/consul.py | 15 +- lib/ansible/modules/clustering/consul_acl.py | 18 +- .../modules/database/mongodb/mongodb_user.py | 21 +- .../database/postgresql/postgresql_privs.py | 50 +- .../modules/monitoring/boundary_meter.py | 14 +- .../modules/monitoring/librato_annotation.py | 9 +- .../monitoring/statusio_maintenance.py | 22 +- lib/ansible/modules/net_tools/dnsmadeeasy.py | 27 +- .../modules/net_tools/ldap/ldap_entry.py | 26 +- lib/ansible/modules/network/aos/aos_device.py | 6 +- .../modules/network/asa/asa_command.py | 3 + .../modules/network/cloudengine/ce_command.py | 15 +- .../modules/network/cloudengine/ce_ntp.py | 4 +- .../network/cloudengine/ce_ntp_auth.py | 5 +- .../network/dellos10/dellos10_command.py | 3 +- .../network/dellos10/dellos10_facts.py | 14 +- .../network/dellos6/dellos6_command.py | 5 +- .../network/dellos9/dellos9_command.py | 5 +- lib/ansible/modules/network/f5/bigip_ucs.py | 2 +- .../network/nxos/nxos_pim_interface.py | 9 +- .../network/ordnance/ordnance_facts.py | 9 +- .../modules/network/panos/panos_restart.py | 17 +- lib/ansible/modules/packaging/os/homebrew.py | 17 +- .../modules/packaging/os/homebrew_cask.py | 17 +- .../modules/packaging/os/portinstall.py | 17 +- .../remote_management/hpilo/hponcfg.py | 2 +- .../remote_management/stacki/stacki_host.py | 20 +- .../storage/netapp/netapp_e_flashcache.py | 19 +- lib/ansible/modules/system/alternatives.py | 8 +- lib/ansible/modules/system/osx_defaults.py | 8 +- lib/ansible/modules/system/seboolean.py | 16 +- .../modules/utilities/helper/_accelerate.py | 4 +- lib/ansible/parsing/yaml/objects.py | 4 +- lib/ansible/playbook/play_context.py | 8 +- lib/ansible/plugins/callback/logentries.py | 19 +- lib/ansible/plugins/connection/accelerate.py | 2 +- lib/ansible/plugins/lookup/shelvefile.py | 4 +- lib/ansible/plugins/strategy/debug.py | 1 - lib/ansible/utils/unsafe_proxy.py | 3 +- test/integration/cleanup_ec2.py | 6 +- test/integration/cleanup_gce.py | 4 +- test/integration/cleanup_rax.py | 4 +- .../targets/module_utils/library/test.py | 4 +- .../ansible-var-precedence-check.py | 2 +- test/sanity/pep8/legacy-files.txt | 3 - test/units/playbook/test_play_context.py | 474 ++++++------------ 84 files changed, 652 insertions(+), 963 deletions(-) delete mode 100755 hacking/conf2yaml.py diff --git a/contrib/inventory/apstra_aos.py b/contrib/inventory/apstra_aos.py index 52445a33723..2b30b318113 100755 --- a/contrib/inventory/apstra_aos.py +++ b/contrib/inventory/apstra_aos.py @@ -49,14 +49,16 @@ This script has been inspired by the cobbler.py inventory. thanks Author: Damien Garros (@dgarros) Version: 0.2.0 """ +import json import os -import argparse import re +import sys try: - import json + import argparse + HAS_ARGPARSE = True except ImportError: - import simplejson as json + HAS_ARGPARSE = False try: from apstra.aosom.session import Session @@ -292,6 +294,8 @@ class AosInventory(object): if not HAS_AOS_PYEZ: raise Exception('aos-pyez is not installed. Please see details here: https://github.com/Apstra/aos-pyez') + if not HAS_ARGPARSE: + raise Exception('argparse is not installed. Please install the argparse library or upgrade to python-2.7') # Initialize inventory self.inventory = dict() # A list of groups and the hosts in that group diff --git a/contrib/inventory/rax.py b/contrib/inventory/rax.py index 9704852ca33..dc3a8ed9838 100755 --- a/contrib/inventory/rax.py +++ b/contrib/inventory/rax.py @@ -170,9 +170,9 @@ from time import time from ansible.constants import get_config from ansible.module_utils.parsing.convert_bool import boolean +from ansible.module_utils.six import text_type - -NON_CALLABLES = (basestring, bool, dict, int, list, type(None)) +NON_CALLABLES = (text_type, str, bool, dict, int, list, type(None)) def load_config_file(): diff --git a/contrib/inventory/vmware.py b/contrib/inventory/vmware.py index 2419ddf8142..b52dd559a4b 100755 --- a/contrib/inventory/vmware.py +++ b/contrib/inventory/vmware.py @@ -38,9 +38,9 @@ import os import ssl import sys import time -import ConfigParser -from six import text_type, string_types +from six import integer_types, text_type, string_types +from six.moves import configparser # Disable logging message trigged by pSphere/suds. try: @@ -64,7 +64,7 @@ from suds.sudsobject import Object as SudsObject class VMwareInventory(object): def __init__(self, guests_only=None): - self.config = ConfigParser.SafeConfigParser() + self.config = configparser.SafeConfigParser() if os.environ.get('VMWARE_INI', ''): config_files = [os.environ['VMWARE_INI']] else: @@ -210,7 +210,7 @@ class VMwareInventory(object): if obj_info != (): l.append(obj_info) return l - elif isinstance(obj, (type(None), bool, int, long, float, string_types)): + elif isinstance(obj, (type(None), bool, float) + string_types + integer_types): return obj else: return () diff --git a/contrib/inventory/vmware_inventory.py b/contrib/inventory/vmware_inventory.py index 575e3459a67..655a6100052 100755 --- a/contrib/inventory/vmware_inventory.py +++ b/contrib/inventory/vmware_inventory.py @@ -23,22 +23,27 @@ $ jq '._meta.hostvars[].config' data.json | head from __future__ import print_function -import argparse import atexit import datetime import getpass +import json import os import re -import six import ssl import sys import uuid - from collections import defaultdict -from six.moves import configparser from time import time -from jinja2 import Environment +import six +from jinja2 import Environment +from six import integer_types, string_types +from six.moves import configparser + +try: + import argparse +except ImportError: + sys.exit('Error: This inventory script required "argparse" python module. Please install it or upgrade to python-2.7') try: from pyVmomi import vim, vmodl @@ -46,11 +51,6 @@ try: except ImportError: sys.exit("ERROR: This inventory script required 'pyVmomi' Python module, it was not able to load it") -try: - import json -except ImportError: - import simplejson as json - hasvcr = False try: import vcr @@ -97,10 +97,7 @@ class VMWareInventory(object): skip_keys = [] groupby_patterns = [] - if sys.version_info > (3, 0): - safe_types = [int, bool, str, float, None] - else: - safe_types = [int, long, bool, str, float, None] + safe_types = [bool, str, float, None] + list(integer_types) iter_types = [dict, list] bad_types = ['Array', 'disabledMethod', 'declaredAlarmState'] @@ -489,7 +486,7 @@ class VMWareInventory(object): for k, v in inventory['_meta']['hostvars'].items(): if 'customvalue' in v: for tv in v['customvalue']: - if not isinstance(tv['value'], str) and not isinstance(tv['value'], unicode): + if not isinstance(tv['value'], string_types): continue newkey = None @@ -665,12 +662,10 @@ class VMWareInventory(object): rdata = vobj.decode('ascii', 'ignore') elif issubclass(type(vobj), bool) or isinstance(vobj, bool): rdata = vobj - elif issubclass(type(vobj), int) or isinstance(vobj, int): + elif issubclass(type(vobj), integer_types) or isinstance(vobj, integer_types): rdata = vobj elif issubclass(type(vobj), float) or isinstance(vobj, float): rdata = vobj - elif issubclass(type(vobj), long) or isinstance(vobj, long): - rdata = vobj elif issubclass(type(vobj), list) or issubclass(type(vobj), tuple): rdata = [] try: diff --git a/hacking/conf2yaml.py b/hacking/conf2yaml.py deleted file mode 100755 index d8fc8bcc3b9..00000000000 --- a/hacking/conf2yaml.py +++ /dev/null @@ -1,124 +0,0 @@ -#!/usr/bin/env python - -import ast -import yaml -import os -import sys -from ansible.parsing.yaml.dumper import AnsibleDumper - -things = {} -stuff = {} - -op_map = { - ast.Add: '+', - ast.Sub: '-', - ast.Mult: '*', - ast.Div: '/', -} - - - -def get_values(values): - if not isinstance(values, list): - return get_value(values) - ret = [] - for value in values: - ret.append(get_value(value)) - return ret - - -def get_value(value): - if hasattr(value, 'id'): - ret = value.id - elif hasattr(value, 's'): - ret = value.s - elif hasattr(value, 'n'): - ret = value.n - elif hasattr(value, 'left'): - operator = op_map[type(value.op)] - left = get_values(value.left) - right = get_values(value.right) - return '%s %s %s' % (left, operator, right) - elif hasattr(value, 'value'): - ret = value.value - elif hasattr(value, 'elts'): - ret = get_values(value.elts) - elif isinstance(value, ast.Call): - func, args, kwargs = get_call(value) - args[:] = [repr(arg) for arg in args] - for k, v in kwargs.items(): - args.append('%s=%s' % (k, repr(v))) - return '%s(%s)' % (func, ', '.join(args)) - else: - return value - - return get_value(ret) - - -def get_call(value): - args = [] - for arg in value.args: - v = get_value(arg) - try: - v = getattr(C, v, v) - except: - pass - args.append(v) - kwargs = {} - for keyword in value.keywords: - v = get_value(keyword.value) - try: - v = getattr(C, v, v) - except: - pass - kwargs[keyword.arg] = v - - func = get_value(value.func) - try: - attr = '.%s' % value.func.attr - except: - attr = '' - return '%s%s' % (func, attr), args, kwargs - - -with open(sys.argv[1]) as f: - tree = ast.parse(f.read()) - -for item in tree.body: - if hasattr(item, 'value') and isinstance(item.value, ast.Call): - try: - if item.value.func.id != 'get_config': - continue - except AttributeError: - continue - - _, args, kwargs = get_call(item.value) - - name = get_value(item.targets[0]) - section = args[1].lower() - config = args[2] - - # new form - if name not in stuff: - stuff[name] = {} - stuff[name] = { - 'desc': 'TODO: write it', - 'ini': [{'section': section, 'key': config}], - 'env': [args[3]], - 'default': args[4] if len(args) == 5 else None, - 'yaml': {'key': '%s.%s' % (section, config)}, - 'vars': [] - } - stuff[name].update(kwargs) - - ## ini like - #if section not in things: - # things[section] = {} - - #things[section][config] = { - # 'env_var': args[3], - # 'default': args[4] if len(args) == 5 else 'UNKNOWN' - #} - #things[section][config].update(kwargs) -print(yaml.dump(stuff, Dumper=AnsibleDumper, indent=2, width=170)) - diff --git a/lib/ansible/constants.py b/lib/ansible/constants.py index 53f11632dc6..3bf4a24ea8e 100644 --- a/lib/ansible/constants.py +++ b/lib/ansible/constants.py @@ -34,12 +34,8 @@ for setting in _config.data.get_settings(): def mk_boolean(value): ''' moved to module_utils''' - try: - from __main__ import display - except: - pass - else: - display.deprecated('ansible.constants.mk_boolean() is deprecated. Use ansible.module_utils.parsing.convert_bool.boolean() instead', version='2.8') + # We don't have a display here so we can't call deprecated + # display.deprecated('ansible.constants.mk_boolean() is deprecated. Use ansible.module_utils.parsing.convert_bool.boolean() instead', version='2.8') return boolean(value, strict=False) diff --git a/lib/ansible/galaxy/login.py b/lib/ansible/galaxy/login.py index d867d307b4b..3b74aaa01c5 100644 --- a/lib/ansible/galaxy/login.py +++ b/lib/ansible/galaxy/login.py @@ -26,6 +26,7 @@ import getpass import json from ansible.errors import AnsibleError, AnsibleOptionsError +from ansible.module_utils.six.moves import input from ansible.module_utils.six.moves.urllib.parse import quote as urlquote, urlparse from ansible.module_utils.six.moves.urllib.error import HTTPError from ansible.module_utils.urls import open_url @@ -61,7 +62,7 @@ class GalaxyLogin(object): " if you do not want to enter your password." + u'\n\n', screen_only=True) try: - self.github_username = raw_input("Github Username: ") + self.github_username = input("Github Username: ") except: pass diff --git a/lib/ansible/module_utils/api.py b/lib/ansible/module_utils/api.py index d05213914e9..5755eaafcd2 100644 --- a/lib/ansible/module_utils/api.py +++ b/lib/ansible/module_utils/api.py @@ -107,7 +107,8 @@ def retry(retries=None, retry_pause=1): if retries is not None: ret = None while True: - retry_count += 1 + # pylint doesn't understand this is a closure + retry_count += 1 # pylint: disable=undefined-variable if retry_count >= retries: raise Exception("Retry limit exceeded: %d" % retries) try: diff --git a/lib/ansible/module_utils/netapp.py b/lib/ansible/module_utils/netapp.py index 99bcf6dc4f5..6480097f7a7 100644 --- a/lib/ansible/module_utils/netapp.py +++ b/lib/ansible/module_utils/netapp.py @@ -24,7 +24,7 @@ except ImportError: from ansible.module_utils.six.moves.urllib.error import HTTPError -from ansible.module_utils.pycompat24 import get_exception +from ansible.module_utils.api import basic_auth_argument_spec from ansible.module_utils.urls import open_url from ansible.module_utils.api import basic_auth_argument_spec @@ -145,8 +145,7 @@ def request(url, data=None, headers=None, method='GET', use_proxy=True, force=force, last_mod_time=last_mod_time, timeout=timeout, validate_certs=validate_certs, url_username=url_username, url_password=url_password, http_agent=http_agent, force_basic_auth=force_basic_auth) - except HTTPError: - err = get_exception() + except HTTPError as err: r = err.fp try: diff --git a/lib/ansible/module_utils/pycompat24.py b/lib/ansible/module_utils/pycompat24.py index 6a8ad52ff33..53e8397868c 100644 --- a/lib/ansible/module_utils/pycompat24.py +++ b/lib/ansible/module_utils/pycompat24.py @@ -52,7 +52,7 @@ except ImportError: # which is essentially a cut/paste from an earlier (2.6) version of python's # ast.py from compiler import ast, parse - from ansible.module_utils.six import binary_type, string_types, text_type + from ansible.module_utils.six import binary_type, integer_types, string_types, text_type def literal_eval(node_or_string): """ @@ -68,8 +68,7 @@ except ImportError: node_or_string = node_or_string.node def _convert(node): - # Okay to use long here because this is only for python 2.4 and 2.5 - if isinstance(node, ast.Const) and isinstance(node.value, (text_type, binary_type, int, float, long, complex)): + if isinstance(node, ast.Const) and isinstance(node.value, (text_type, binary_type, float, complex) + integer_types): return node.value elif isinstance(node, ast.Tuple): return tuple(map(_convert, node.nodes)) diff --git a/lib/ansible/module_utils/vmware.py b/lib/ansible/module_utils/vmware.py index 4975f0f58c4..e7a88073660 100644 --- a/lib/ansible/module_utils/vmware.py +++ b/lib/ansible/module_utils/vmware.py @@ -17,8 +17,6 @@ # You should have received a copy of the GNU General Public License # along with Ansible. If not, see . -from ansible.module_utils.urls import fetch_url -from ansible.module_utils.six import iteritems import atexit import os import ssl @@ -33,6 +31,9 @@ try: except ImportError: HAS_PYVMOMI = False +from ansible.module_utils.urls import fetch_url +from ansible.module_utils.six import integer_types, iteritems, string_types + class TaskError(Exception): pass @@ -595,17 +596,7 @@ def serialize_spec(clonespec): data[x] = [] for xe in xo: data[x].append(serialize_spec(xe)) - elif issubclass(xt, str): - data[x] = xo - elif issubclass(xt, unicode): - data[x] = xo - elif issubclass(xt, int): - data[x] = xo - elif issubclass(xt, float): - data[x] = xo - elif issubclass(xt, long): - data[x] = xo - elif issubclass(xt, bool): + elif issubclass(xt, string_types + integer_types + (float, bool)): data[x] = xo elif issubclass(xt, dict): data[x] = {} diff --git a/lib/ansible/modules/cloud/amazon/ec2_vpc_endpoint.py b/lib/ansible/modules/cloud/amazon/ec2_vpc_endpoint.py index 9273bf84978..169282a1e7d 100644 --- a/lib/ansible/modules/cloud/amazon/ec2_vpc_endpoint.py +++ b/lib/ansible/modules/cloud/amazon/ec2_vpc_endpoint.py @@ -184,6 +184,7 @@ import traceback from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.ec2 import get_aws_connection_info, boto3_conn, ec2_argument_spec, HAS_BOTO3 from ansible.module_utils.ec2 import camel_dict_to_snake_dict +from ansible.module_utils.six import string_types try: import botocore @@ -309,7 +310,7 @@ def setup_removal(client, module): params = dict() changed = False params['DryRun'] = module.check_mode - if isinstance(module.params.get('vpc_endpoint_id'), basestring): + if isinstance(module.params.get('vpc_endpoint_id'), string_types): params['VpcEndpointIds'] = [module.params.get('vpc_endpoint_id')] else: params['VpcEndpointIds'] = module.params.get('vpc_endpoint_id') diff --git a/lib/ansible/modules/cloud/amazon/ec2_vpc_igw.py b/lib/ansible/modules/cloud/amazon/ec2_vpc_igw.py index c45c00efd72..3b75c455093 100644 --- a/lib/ansible/modules/cloud/amazon/ec2_vpc_igw.py +++ b/lib/ansible/modules/cloud/amazon/ec2_vpc_igw.py @@ -138,7 +138,7 @@ def ensure_tags(vpc_conn, resource_id, tags, add_only, check_mode): latest_tags = get_resource_tags(vpc_conn, resource_id) return {'changed': True, 'tags': latest_tags} except EC2ResponseError as e: - raise AnsibleTagCreationException( + raise AnsibleIGWException( 'Unable to update tags for {0}, error: {1}'.format(resource_id, e)) diff --git a/lib/ansible/modules/cloud/amazon/ec2_vpc_net_facts.py b/lib/ansible/modules/cloud/amazon/ec2_vpc_net_facts.py index 3d84337a1a8..1a75a4f9625 100644 --- a/lib/ansible/modules/cloud/amazon/ec2_vpc_net_facts.py +++ b/lib/ansible/modules/cloud/amazon/ec2_vpc_net_facts.py @@ -56,6 +56,7 @@ EXAMPLES = ''' "tag:Name": Example ''' +import traceback try: import boto.vpc @@ -66,6 +67,7 @@ except ImportError: from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.ec2 import connect_to_aws, ec2_argument_spec, get_aws_connection_info +from ansible.module_utils._text import to_native def get_vpc_info(vpc): @@ -121,8 +123,8 @@ def main(): if region: try: connection = connect_to_aws(boto.vpc, region, **aws_connect_params) - except (boto.exception.NoAuthHandlerFound, StandardError) as e: - module.fail_json(msg=str(e)) + except (boto.exception.NoAuthHandlerFound, Exception) as e: + module.fail_json(msg=to_native(e), exception=traceback.format_exc()) else: module.fail_json(msg="region must be specified") diff --git a/lib/ansible/modules/cloud/amazon/iam_policy.py b/lib/ansible/modules/cloud/amazon/iam_policy.py index add3bddc91c..0b6444c8a99 100644 --- a/lib/ansible/modules/cloud/amazon/iam_policy.py +++ b/lib/ansible/modules/cloud/amazon/iam_policy.py @@ -119,6 +119,7 @@ tasks: ''' import json import urllib + try: import boto import boto.iam @@ -127,6 +128,11 @@ try: except ImportError: HAS_BOTO = False +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.ec2 import connect_to_aws, ec2_argument_spec, get_aws_connection_info +from ansible.module_utils.six import string_types + + def boto_exception(err): '''generic error message handler''' if hasattr(err, 'error_message'): @@ -317,7 +323,7 @@ def main(): elif module.params.get('policy_json') is not None: pdoc = module.params.get('policy_json') # if its a string, assume it is already JSON - if not isinstance(pdoc, basestring): + if not isinstance(pdoc, string_types): try: pdoc = json.dumps(pdoc) except Exception as e: @@ -353,8 +359,6 @@ def main(): state) module.exit_json(changed=changed, group_name=name, policies=current_policies, msg=msg) -from ansible.module_utils.basic import * -from ansible.module_utils.ec2 import * if __name__ == '__main__': main() diff --git a/lib/ansible/modules/cloud/amazon/rds_param_group.py b/lib/ansible/modules/cloud/amazon/rds_param_group.py index 6c915974934..671c5f79bcf 100644 --- a/lib/ansible/modules/cloud/amazon/rds_param_group.py +++ b/lib/ansible/modules/cloud/amazon/rds_param_group.py @@ -116,6 +116,20 @@ EXAMPLES = ''' name: norwegian_blue ''' +try: + import boto.rds + from boto.exception import BotoServerError + HAS_BOTO = True +except ImportError: + HAS_BOTO = False + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.ec2 import connect_to_aws, ec2_argument_spec, get_aws_connection_info +from ansible.module_utils.parsing.convert_bool import BOOLEANS_TRUE +from ansible.module_utils.six import string_types +from ansible.module_utils._text import to_native + + VALID_ENGINES = [ 'aurora5.6', 'mariadb10.0', @@ -147,12 +161,12 @@ VALID_ENGINES = [ 'sqlserver-web-12.0', ] -try: - import boto.rds - from boto.exception import BotoServerError - HAS_BOTO = True -except ImportError: - HAS_BOTO = False +INT_MODIFIERS = { + 'K': 1024, + 'M': pow(1024, 2), + 'G': pow(1024, 3), + 'T': pow(1024, 4), +} # returns a tuple: (whether or not a parameter was changed, the remaining parameters that weren't found in this parameter group) @@ -168,14 +182,6 @@ class NotModifiableError(Exception): def __str__(self): return 'NotModifiableError: %s' % self.error_message -INT_MODIFIERS = { - 'K': 1024, - 'M': pow(1024, 2), - 'G': pow(1024, 3), - 'T': pow(1024, 4), -} - -TRUE_VALUES = ('on', 'true', 'yes', '1',) def set_parameter(param, value, immediate): """ @@ -187,7 +193,7 @@ def set_parameter(param, value, immediate): converted_value = str(value) elif param.type == 'integer': - if isinstance(value, basestring): + if isinstance(value, string_types): try: for modifier in INT_MODIFIERS.keys(): if value.endswith(modifier): @@ -203,8 +209,8 @@ def set_parameter(param, value, immediate): converted_value = int(value) elif param.type == 'boolean': - if isinstance(value, basestring): - converted_value = value in TRUE_VALUES + if isinstance(value, string_types): + converted_value = to_native(value) in BOOLEANS_TRUE else: converted_value = bool(value) @@ -337,9 +343,6 @@ def main(): module.exit_json(changed=changed) -# import module snippets -from ansible.module_utils.basic import * -from ansible.module_utils.ec2 import * if __name__ == '__main__': main() diff --git a/lib/ansible/modules/cloud/amazon/s3_sync.py b/lib/ansible/modules/cloud/amazon/s3_sync.py index 69f76fd7d24..195a837c3f8 100644 --- a/lib/ansible/modules/cloud/amazon/s3_sync.py +++ b/lib/ansible/modules/cloud/amazon/s3_sync.py @@ -184,22 +184,19 @@ uploaded: ''' +import datetime +import fnmatch +import hashlib +import mimetypes import os import stat as osstat # os.stat constants -import mimetypes -import datetime -from dateutil import tz -import hashlib -import fnmatch import traceback +from dateutil import tz # import module snippets -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.ec2 import ec2_argument_spec - -# import a class, otherwise we'll use a fully qualified path -# from ansible.module_utils.ec2 import AWSRetry import ansible.module_utils.ec2 +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.ec2 import camel_dict_to_snake_dict, ec2_argument_spec try: diff --git a/lib/ansible/modules/cloud/azure/azure_rm_securitygroup.py b/lib/ansible/modules/cloud/azure/azure_rm_securitygroup.py index d0a78037528..c29b00542f1 100644 --- a/lib/ansible/modules/cloud/azure/azure_rm_securitygroup.py +++ b/lib/ansible/modules/cloud/azure/azure_rm_securitygroup.py @@ -336,8 +336,8 @@ state: } ''' # NOQA -from ansible.module_utils.basic import * -from ansible.module_utils.azure_rm_common import * +from ansible.module_utils.azure_rm_common import AzureRMModuleBase +from ansible.module_utils.six import integer_types try: from msrestazure.azure_exceptions import CloudError @@ -366,7 +366,7 @@ def validate_rule(rule, rule_type=None): priority = rule.get('priority', None) if not priority: raise Exception("Rule priority is required.") - if not isinstance(priority, (int, long)): + if not isinstance(priority, integer_types): raise Exception("Rule priority attribute must be an integer.") if rule_type != 'default' and (priority < 100 or priority > 4096): raise Exception("Rule priority must be between 100 and 4096") @@ -716,5 +716,6 @@ class AzureRMSecurityGroup(AzureRMModuleBase): def main(): AzureRMSecurityGroup() + if __name__ == '__main__': main() diff --git a/lib/ansible/modules/cloud/docker/docker_container.py b/lib/ansible/modules/cloud/docker/docker_container.py index e7ddf8fd50c..a6c4a7b5450 100644 --- a/lib/ansible/modules/cloud/docker/docker_container.py +++ b/lib/ansible/modules/cloud/docker/docker_container.py @@ -681,16 +681,20 @@ docker_container: }' ''' +import os import re +import shlex -from ansible.module_utils.docker_common import * +from ansible.module_utils.basic import human_to_bytes +from ansible.module_utils.docker_common import HAS_DOCKER_PY_2, AnsibleDockerClient, DockerBaseClass +from ansible.module_utils.six import string_types try: from docker import utils if HAS_DOCKER_PY_2: - from docker.types import Ulimit + from docker.types import Ulimit, LogConfig else: - from docker.utils.types import Ulimit + from docker.utils.types import Ulimit, LogConfig except: # missing docker-py handled in ansible.module_utils.docker pass @@ -705,6 +709,7 @@ REQUIRES_CONVERSION_TO_BYTES = [ VOLUME_PERMISSIONS = ('rw', 'ro', 'z', 'Z') + class TaskParameters(DockerBaseClass): ''' Access and parse module parameters @@ -1087,14 +1092,14 @@ class TaskParameters(DockerBaseClass): # Any published port should also be exposed for publish_port in published_ports: match = False - if isinstance(publish_port, basestring) and '/' in publish_port: + if isinstance(publish_port, string_types) and '/' in publish_port: port, protocol = publish_port.split('/') port = int(port) else: protocol = 'tcp' port = int(publish_port) for exposed_port in exposed: - if isinstance(exposed_port[0], basestring) and '-' in exposed_port[0]: + if isinstance(exposed_port[0], string_types) and '-' in exposed_port[0]: start_port, end_port = exposed_port[0].split('-') if int(start_port) <= port <= int(end_port): match = True @@ -2125,8 +2130,6 @@ def main(): cm = ContainerManager(client) client.module.exit_json(**cm.results) -# import module snippets -from ansible.module_utils.basic import * if __name__ == '__main__': main() diff --git a/lib/ansible/modules/cloud/docker/docker_image.py b/lib/ansible/modules/cloud/docker/docker_image.py index 0dce525a6b7..dd1d80221d9 100644 --- a/lib/ansible/modules/cloud/docker/docker_image.py +++ b/lib/ansible/modules/cloud/docker/docker_image.py @@ -250,8 +250,12 @@ image: type: dict sample: {} ''' +import re +import os -from ansible.module_utils.docker_common import * +from ansible.module_utils.docker_common import (HAS_DOCKER_PY_2, AnsibleDockerClient, + DockerBaseClass) +from ansible.module_utils._text import to_native try: if HAS_DOCKER_PY_2: @@ -519,8 +523,7 @@ class ImageManager(DockerBaseClass): params['container_limits'] = self.container_limits if self.buildargs: for key, value in self.buildargs.items(): - if not isinstance(value, basestring): - self.buildargs[key] = str(value) + self.buildargs[key] = to_native(value) params['buildargs'] = self.buildargs for line in self.client.build(**params): @@ -604,8 +607,5 @@ def main(): client.module.exit_json(**results) -# import module snippets -from ansible.module_utils.basic import * - if __name__ == '__main__': main() diff --git a/lib/ansible/modules/cloud/google/gcp_url_map.py b/lib/ansible/modules/cloud/google/gcp_url_map.py index e865327f641..eb4620b67b8 100644 --- a/lib/ansible/modules/cloud/google/gcp_url_map.py +++ b/lib/ansible/modules/cloud/google/gcp_url_map.py @@ -147,15 +147,12 @@ url_map: ''' -try: - from ast import literal_eval - HAS_PYTHON26 = True -except ImportError: - HAS_PYTHON26 = False +from ast import literal_eval -# import module snippets from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.gcp import check_params, get_google_api_client, GCPUtils +from ansible.module_utils.six import string_types + USER_AGENT_PRODUCT = 'ansible-url_map' USER_AGENT_VERSION = '0.0.1' @@ -258,7 +255,7 @@ def _validate_host_rules_params(host_rules): try: check_params(hr, fields) for host in hr['hosts']: - if not isinstance(host, basestring): + if not isinstance(host, string_types): raise ValueError("host in hostrules must be a string") elif '*' in host: if host.index('*') != 0: @@ -459,10 +456,6 @@ def main(): project_id=dict(), ), required_together=[ ['path_matchers', 'host_rules'], ]) - if not HAS_PYTHON26: - module.fail_json( - msg="GCE module requires python's 'ast' module, python v2.6+") - client, conn_params = get_google_api_client(module, 'compute', user_agent_product=USER_AGENT_PRODUCT, user_agent_version=USER_AGENT_VERSION) @@ -515,5 +508,6 @@ def main(): json_output.update(params) module.exit_json(**json_output) + if __name__ == '__main__': main() diff --git a/lib/ansible/modules/cloud/google/gcspanner.py b/lib/ansible/modules/cloud/google/gcspanner.py index 491cbefdff5..eae28435254 100644 --- a/lib/ansible/modules/cloud/google/gcspanner.py +++ b/lib/ansible/modules/cloud/google/gcspanner.py @@ -139,6 +139,7 @@ except ImportError as e: from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.gcp import check_min_pkg_version, get_google_cloud_credentials +from ansible.module_utils.six import string_types CLOUD_CLIENT = 'google-cloud-spanner' CLOUD_CLIENT_MINIMUM_VERSION = '0.23.0' @@ -169,7 +170,7 @@ def instance_update(instance): errmsg = 'node_count must be an integer %s (%s)' % ( instance.node_count, type(instance.node_count)) if instance.display_name and not isinstance(instance.display_name, - basestring): + string_types): errmsg = 'instance_display_name must be an string %s (%s)' % ( instance.display_name, type(instance.display_name)) if errmsg: diff --git a/lib/ansible/modules/cloud/lxc/lxc_container.py b/lib/ansible/modules/cloud/lxc/lxc_container.py index 5e615514a60..b9ffea0dbac 100644 --- a/lib/ansible/modules/cloud/lxc/lxc_container.py +++ b/lib/ansible/modules/cloud/lxc/lxc_container.py @@ -449,6 +449,7 @@ else: # import module bits from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.parsing.convert_bool import BOOLEANS_FALSE, BOOLEANS_TRUE +from ansible.module_utils.six.moves import xrange # LXC_COMPRESSION_MAP is a map of available compression types when creating diff --git a/lib/ansible/modules/cloud/misc/rhevm.py b/lib/ansible/modules/cloud/misc/rhevm.py index b742ba7ec1d..c0c3bc6ceb3 100644 --- a/lib/ansible/modules/cloud/misc/rhevm.py +++ b/lib/ansible/modules/cloud/misc/rhevm.py @@ -933,13 +933,13 @@ class RHEVConn(object): VM = self.get_VM(vmname) try: if str(VM.status.state) == 'down': - cdrom = params.CdRom(file=cd_iso) + cdrom = params.CdRom(file=cd_drive) VM.cdroms.add(cdrom) setMsg("Attached the image.") setChanged() else: cdrom = VM.cdroms.get(id="00000000-0000-0000-0000-000000000000") - cdrom.set_file(cd_iso) + cdrom.set_file(cd_drive) cdrom.update(current=True) setMsg("Attached the image.") setChanged() @@ -971,7 +971,7 @@ class RHEVConn(object): HOST = self.get_Host_byid(VM.host.id) if str(HOST.name) != vmhost: try: - vm.migrate( + VM.migrate( action=params.Action( host=params.Host( name=vmhost, diff --git a/lib/ansible/modules/cloud/misc/virt_net.py b/lib/ansible/modules/cloud/misc/virt_net.py index 05b8149e1a1..6756f252114 100644 --- a/lib/ansible/modules/cloud/misc/virt_net.py +++ b/lib/ansible/modules/cloud/misc/virt_net.py @@ -161,6 +161,7 @@ else: HAS_XML = True from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils._text import to_native ALL_COMMANDS = [] @@ -278,7 +279,7 @@ class LibvirtConnection(object): if res == 0: return True # command, section, parentIndex, xml, flags=0 - self.module.fail_json(msg='updating this is not supported yet '+unicode(xml)) + self.module.fail_json(msg='updating this is not supported yet %s' % to_native(xml)) def destroy(self, entryid): if not self.module.check_mode: diff --git a/lib/ansible/modules/cloud/openstack/os_keystone_domain_facts.py b/lib/ansible/modules/cloud/openstack/os_keystone_domain_facts.py index 289f781d7ed..c21e4dad760 100644 --- a/lib/ansible/modules/cloud/openstack/os_keystone_domain_facts.py +++ b/lib/ansible/modules/cloud/openstack/os_keystone_domain_facts.py @@ -103,6 +103,9 @@ try: except ImportError: HAS_SHADE = False +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs + def main(): @@ -129,7 +132,7 @@ def main(): if name: # Let's suppose user is passing domain ID try: - domains = cloud.get_domain(name) + domains = opcloud.get_domain(name) except: domains = opcloud.search_domains(filters={'name': name}) @@ -142,8 +145,6 @@ def main(): except shade.OpenStackCloudException as e: module.fail_json(msg=str(e)) -from ansible.module_utils.basic import * -from ansible.module_utils.openstack import * if __name__ == '__main__': main() diff --git a/lib/ansible/modules/cloud/openstack/os_server_actions.py b/lib/ansible/modules/cloud/openstack/os_server_actions.py index 351672ee0ee..ca52c336337 100644 --- a/lib/ansible/modules/cloud/openstack/os_server_actions.py +++ b/lib/ansible/modules/cloud/openstack/os_server_actions.py @@ -89,6 +89,9 @@ try: except ImportError: HAS_SHADE = False +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.openstack import openstack_full_argument_spec, openstack_module_kwargs + _action_map = {'stop': 'SHUTOFF', 'start': 'ACTIVE', @@ -102,7 +105,7 @@ _action_map = {'stop': 'SHUTOFF', _admin_actions = ['pause', 'unpause', 'suspend', 'resume', 'lock', 'unlock'] -def _wait(timeout, cloud, server, action): +def _wait(timeout, cloud, server, action, module): """Wait for the server to reach the desired state for the given action.""" for count in shade._utils._iterate_timeout( @@ -166,7 +169,7 @@ def main(): cloud.nova_client.servers.stop(server=server.id) if wait: - _wait(timeout, cloud, server, action) + _wait(timeout, cloud, server, action, module) module.exit_json(changed=True) if action == 'start': @@ -175,7 +178,7 @@ def main(): cloud.nova_client.servers.start(server=server.id) if wait: - _wait(timeout, cloud, server, action) + _wait(timeout, cloud, server, action, module) module.exit_json(changed=True) if action == 'pause': @@ -184,7 +187,7 @@ def main(): cloud.nova_client.servers.pause(server=server.id) if wait: - _wait(timeout, cloud, server, action) + _wait(timeout, cloud, server, action, module) module.exit_json(changed=True) elif action == 'unpause': @@ -193,7 +196,7 @@ def main(): cloud.nova_client.servers.unpause(server=server.id) if wait: - _wait(timeout, cloud, server, action) + _wait(timeout, cloud, server, action, module) module.exit_json(changed=True) elif action == 'lock': @@ -212,7 +215,7 @@ def main(): cloud.nova_client.servers.suspend(server=server.id) if wait: - _wait(timeout, cloud, server, action) + _wait(timeout, cloud, server, action, module) module.exit_json(changed=True) elif action == 'resume': @@ -221,7 +224,7 @@ def main(): cloud.nova_client.servers.resume(server=server.id) if wait: - _wait(timeout, cloud, server, action) + _wait(timeout, cloud, server, action, module) module.exit_json(changed=True) elif action == 'rebuild': @@ -233,14 +236,12 @@ def main(): # rebuild doesn't set a state, just do it cloud.nova_client.servers.rebuild(server=server.id, image=image.id) if wait: - _wait(timeout, cloud, server, action) + _wait(timeout, cloud, server, action, module) module.exit_json(changed=True) except shade.OpenStackCloudException as e: module.fail_json(msg=str(e), extra_data=e.extra_data) -# this is magic, see lib/ansible/module_common.py -from ansible.module_utils.basic import * -from ansible.module_utils.openstack import * + if __name__ == '__main__': main() diff --git a/lib/ansible/modules/cloud/ovh/ovh_ip_loadbalancing_backend.py b/lib/ansible/modules/cloud/ovh/ovh_ip_loadbalancing_backend.py index e7c40590fde..a15b3364836 100644 --- a/lib/ansible/modules/cloud/ovh/ovh_ip_loadbalancing_backend.py +++ b/lib/ansible/modules/cloud/ovh/ovh_ip_loadbalancing_backend.py @@ -170,7 +170,7 @@ def main(): name = module.params.get('name') state = module.params.get('state') backend = module.params.get('backend') - weight = long(module.params.get('weight')) + weight = module.params.get('weight') probe = module.params.get('probe') timeout = module.params.get('timeout') diff --git a/lib/ansible/modules/cloud/profitbricks/profitbricks.py b/lib/ansible/modules/cloud/profitbricks/profitbricks.py index 5104bfbacd3..97334bf02de 100644 --- a/lib/ansible/modules/cloud/profitbricks/profitbricks.py +++ b/lib/ansible/modules/cloud/profitbricks/profitbricks.py @@ -204,6 +204,7 @@ EXAMPLES = ''' import re import uuid import time +import traceback HAS_PB_SDK = True @@ -213,7 +214,8 @@ except ImportError: HAS_PB_SDK = False from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.pycompat24 import get_exception +from ansible.module_utils.six.moves import xrange +from ansible.module_utils._text import to_native LOCATIONS = ['us/las', @@ -401,12 +403,11 @@ def create_virtual_machine(module, profitbricks): try: name % 0 - except TypeError: - e = get_exception() + except TypeError as e: if e.message.startswith('not all'): name = '%s%%d' % name else: - module.fail_json(msg=e.message) + module.fail_json(msg=e.message, exception=traceback.format_exc()) number_range = xrange(count_offset, count_offset + count + len(numbers)) available_numbers = list(set(number_range).difference(numbers)) @@ -487,9 +488,8 @@ def remove_virtual_machine(module, profitbricks): # Remove the server try: server_response = profitbricks.delete_server(datacenter_id, server_id) - except Exception: - e = get_exception() - module.fail_json(msg="failed to terminate the virtual server: %s" % str(e)) + except Exception as e: + module.fail_json(msg="failed to terminate the virtual server: %s" % to_native(e), exception=traceback.format_exc()) else: changed = True @@ -504,9 +504,8 @@ def _remove_boot_volume(module, profitbricks, datacenter_id, server_id): server = profitbricks.get_server(datacenter_id, server_id) volume_id = server['properties']['bootVolume']['id'] volume_response = profitbricks.delete_volume(datacenter_id, volume_id) - except Exception: - e = get_exception() - module.fail_json(msg="failed to remove the server's boot volume: %s" % str(e)) + except Exception as e: + module.fail_json(msg="failed to remove the server's boot volume: %s" % to_native(e), exception=traceback.format_exc()) def startstop_machine(module, profitbricks, state): @@ -638,9 +637,8 @@ def main(): try: (changed) = remove_virtual_machine(module, profitbricks) module.exit_json(changed=changed) - except Exception: - e = get_exception() - module.fail_json(msg='failed to set instance state: %s' % str(e)) + except Exception as e: + module.fail_json(msg='failed to set instance state: %s' % to_native(e), exception=traceback.format_exc()) elif state in ('running', 'stopped'): if not module.params.get('datacenter'): @@ -649,9 +647,8 @@ def main(): try: (changed) = startstop_machine(module, profitbricks, state) module.exit_json(changed=changed) - except Exception: - e = get_exception() - module.fail_json(msg='failed to set instance state: %s' % str(e)) + except Exception as e: + module.fail_json(msg='failed to set instance state: %s' % to_native(e), exception=traceback.format_exc()) elif state == 'present': if not module.params.get('name'): @@ -668,9 +665,8 @@ def main(): try: (machine_dict_array) = create_virtual_machine(module, profitbricks) module.exit_json(**machine_dict_array) - except Exception: - e = get_exception() - module.fail_json(msg='failed to set instance state: %s' % str(e)) + except Exception as e: + module.fail_json(msg='failed to set instance state: %s' % to_native(e), exception=traceback.format_exc()) if __name__ == '__main__': diff --git a/lib/ansible/modules/cloud/profitbricks/profitbricks_volume.py b/lib/ansible/modules/cloud/profitbricks/profitbricks_volume.py index 55e8896d56f..e2ed3e536fc 100644 --- a/lib/ansible/modules/cloud/profitbricks/profitbricks_volume.py +++ b/lib/ansible/modules/cloud/profitbricks/profitbricks_volume.py @@ -141,6 +141,7 @@ EXAMPLES = ''' import re import time +import traceback HAS_PB_SDK = True @@ -150,7 +151,8 @@ except ImportError: HAS_PB_SDK = False from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.pycompat24 import get_exception +from ansible.module_utils.six.moves import xrange +from ansible.module_utils._text import to_native uuid_match = re.compile( @@ -262,12 +264,11 @@ def create_volume(module, profitbricks): try: name % 0 - except TypeError: - e = get_exception() + except TypeError as e: if e.message.startswith('not all'): name = '%s%%d' % name else: - module.fail_json(msg=e.message) + module.fail_json(msg=e.message, exception=traceback.format_exc()) number_range = xrange(count_offset, count_offset + count + len(numbers)) available_numbers = list(set(number_range).difference(numbers)) @@ -326,7 +327,7 @@ def delete_volume(module, profitbricks): for n in instance_ids: if(uuid_match.match(n)): - _delete_volume(module, profitbricks, datacenter, volume) + _delete_volume(module, profitbricks, datacenter, n) changed = True else: volumes = profitbricks.list_volumes(datacenter) @@ -364,9 +365,8 @@ def _attach_volume(module, profitbricks, datacenter, volume): try: return profitbricks.attach_volume(datacenter, server, volume) - except Exception: - e = get_exception() - module.fail_json(msg='failed to attach volume: %s' % str(e)) + except Exception as e: + module.fail_json(msg='failed to attach volume: %s' % to_native(e), exception=traceback.format_exc()) def main(): @@ -414,9 +414,8 @@ def main(): try: (changed) = delete_volume(module, profitbricks) module.exit_json(changed=changed) - except Exception: - e = get_exception() - module.fail_json(msg='failed to set volume state: %s' % str(e)) + except Exception as e: + module.fail_json(msg='failed to set volume state: %s' % to_native(e), exception=traceback.format_exc()) elif state == 'present': if not module.params.get('datacenter'): @@ -427,9 +426,8 @@ def main(): try: (volume_dict_array) = create_volume(module, profitbricks) module.exit_json(**volume_dict_array) - except Exception: - e = get_exception() - module.fail_json(msg='failed to set volume state: %s' % str(e)) + except Exception as e: + module.fail_json(msg='failed to set volume state: %s' % to_native(e), exception=traceback.format_exc()) if __name__ == '__main__': diff --git a/lib/ansible/modules/cloud/rackspace/rax.py b/lib/ansible/modules/cloud/rackspace/rax.py index 4d393a405b8..201bca56958 100644 --- a/lib/ansible/modules/cloud/rackspace/rax.py +++ b/lib/ansible/modules/cloud/rackspace/rax.py @@ -240,12 +240,24 @@ EXAMPLES = ''' register: rax ''' +import os +import json +import re +import time + try: import pyrax HAS_PYRAX = True except ImportError: HAS_PYRAX = False +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.rax import (FINAL_STATUSES, rax_argument_spec, rax_find_bootable_volume, + rax_find_image, rax_find_network, rax_find_volume, + rax_required_together, rax_to_dict, setup_rax_module) +from ansible.module_utils.six.moves import xrange +from ansible.module_utils.six import string_types + def rax_find_server_image(module, server, image, boot_volume): if not image and boot_volume: @@ -515,7 +527,7 @@ def cloudservers(module, state=None, name=None, flavor=None, image=None, meta[k] = ','.join(['%s' % i for i in v]) elif isinstance(v, dict): meta[k] = json.dumps(v) - elif not isinstance(v, basestring): + elif not isinstance(v, string_types): meta[k] = '%s' % v # When using state=absent with group, the absent block won't match the @@ -890,11 +902,5 @@ def main(): boot_volume_terminate=boot_volume_terminate) -# import module snippets -from ansible.module_utils.basic import * -from ansible.module_utils.rax import * - -# invoke the module - if __name__ == '__main__': main() diff --git a/lib/ansible/modules/cloud/rackspace/rax_clb_nodes.py b/lib/ansible/modules/cloud/rackspace/rax_clb_nodes.py index 6af566538e9..b395b2b346f 100644 --- a/lib/ansible/modules/cloud/rackspace/rax_clb_nodes.py +++ b/lib/ansible/modules/cloud/rackspace/rax_clb_nodes.py @@ -131,7 +131,9 @@ except ImportError: def _activate_virtualenv(path): path = os.path.expanduser(path) activate_this = os.path.join(path, 'bin', 'activate_this.py') - execfile(activate_this, dict(__file__=activate_this)) + with open(activate_this) as f: + code = compile(f.read(), activate_this, 'exec') + exec(code) def _get_node(lb, node_id=None, address=None, port=None): diff --git a/lib/ansible/modules/cloud/rackspace/rax_meta.py b/lib/ansible/modules/cloud/rackspace/rax_meta.py index 7c55d3dd94d..7257e6341e6 100644 --- a/lib/ansible/modules/cloud/rackspace/rax_meta.py +++ b/lib/ansible/modules/cloud/rackspace/rax_meta.py @@ -74,12 +74,18 @@ EXAMPLES = ''' region: DFW ''' +import json + try: import pyrax HAS_PYRAX = True except ImportError: HAS_PYRAX = False +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.rax import rax_argument_spec, rax_required_together, setup_rax_module +from ansible.module_utils.six import string_types + def rax_meta(module, address, name, server_id, meta): changed = False @@ -128,7 +134,7 @@ def rax_meta(module, address, name, server_id, meta): meta[k] = ','.join(['%s' % i for i in v]) elif isinstance(v, dict): meta[k] = json.dumps(v) - elif not isinstance(v, basestring): + elif not isinstance(v, string_types): meta[k] = '%s' % v server = servers[0] @@ -175,11 +181,5 @@ def main(): rax_meta(module, address, name, server_id, meta) -# import module snippets -from ansible.module_utils.basic import * -from ansible.module_utils.rax import * - -### invoke the module - if __name__ == '__main__': main() diff --git a/lib/ansible/modules/cloud/rackspace/rax_scaling_group.py b/lib/ansible/modules/cloud/rackspace/rax_scaling_group.py index b7abcb2f3e0..6975ed4a5ca 100644 --- a/lib/ansible/modules/cloud/rackspace/rax_scaling_group.py +++ b/lib/ansible/modules/cloud/rackspace/rax_scaling_group.py @@ -149,6 +149,9 @@ EXAMPLES = ''' ''' import base64 +import json +import os +import time try: import pyrax @@ -156,6 +159,11 @@ try: except ImportError: HAS_PYRAX = False +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.rax import (rax_argument_spec, rax_find_image, rax_find_network, + rax_required_together, rax_to_dict, setup_rax_module) +from ansible.module_utils.six import string_types + def rax_asg(module, cooldown=300, disk_config=None, files={}, flavor=None, image=None, key_name=None, loadbalancers=[], meta={}, @@ -189,7 +197,7 @@ def rax_asg(module, cooldown=300, disk_config=None, files={}, flavor=None, meta[k] = ','.join(['%s' % i for i in v]) elif isinstance(v, dict): meta[k] = json.dumps(v) - elif not isinstance(v, basestring): + elif not isinstance(v, string_types): meta[k] = '%s' % v if image: @@ -426,11 +434,5 @@ def main(): state=state, config_drive=config_drive, user_data=user_data) -# import module snippets -from ansible.module_utils.basic import * -from ansible.module_utils.rax import * - -# invoke the module - if __name__ == '__main__': main() diff --git a/lib/ansible/modules/cloud/smartos/vmadm.py b/lib/ansible/modules/cloud/smartos/vmadm.py index 02daccf4b7d..19dd3bffd7e 100644 --- a/lib/ansible/modules/cloud/smartos/vmadm.py +++ b/lib/ansible/modules/cloud/smartos/vmadm.py @@ -346,18 +346,19 @@ state: sample: 'running' ''' -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.pycompat24 import get_exception -from ansible.module_utils._text import to_native import os import re import tempfile import traceback + try: import json except ImportError: import simplejson as json +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils._text import to_native + # While vmadm(1M) supports a -E option to return any errors in JSON, the # generated JSON does not play well with the JSON parsers of Python. # The returned message contains '\n' as part of the stacktrace, @@ -377,11 +378,10 @@ def get_vm_prop(module, uuid, prop): try: stdout_json = json.loads(stdout) - except: - e = get_exception() + except Exception as e: module.fail_json( - msg='Invalid JSON returned by vmadm for uuid lookup of {0}'.format(alias), - details=to_native(e)) + msg='Invalid JSON returned by vmadm for uuid lookup of {0}'.format(uuid), + details=to_native(e), exception=traceback.format_exc()) if len(stdout_json) > 0 and prop in stdout_json[0]: return stdout_json[0][prop] @@ -408,11 +408,10 @@ def get_vm_uuid(module, alias): else: try: stdout_json = json.loads(stdout) - except: - e = get_exception() + except Exception as e: module.fail_json( msg='Invalid JSON returned by vmadm for uuid lookup of {0}'.format(alias), - details=to_native(e)) + details=to_native(e), exception=traceback.format_exc()) if len(stdout_json) > 0 and 'uuid' in stdout_json[0]: return stdout_json[0]['uuid'] @@ -430,9 +429,9 @@ def get_all_vm_uuids(module): try: stdout_json = json.loads(stdout) return [v['uuid'] for v in stdout_json] - except: - e = get_exception() - module.fail_json(msg='Could not retrieve VM UUIDs', details=to_native(e)) + except Exception as e: + module.fail_json(msg='Could not retrieve VM UUIDs', details=to_native(e), + exception=traceback.format_exc()) def new_vm(module, uuid, vm_state): diff --git a/lib/ansible/modules/cloud/softlayer/sl_vm.py b/lib/ansible/modules/cloud/softlayer/sl_vm.py index 3130bbbb30c..4edaf8eea66 100644 --- a/lib/ansible/modules/cloud/softlayer/sl_vm.py +++ b/lib/ansible/modules/cloud/softlayer/sl_vm.py @@ -236,8 +236,22 @@ EXAMPLES = ''' # TODO: Disabled RETURN as it is breaking the build for docs. Needs to be fixed. RETURN = '''# ''' +import json import time +try: + import SoftLayer + from SoftLayer import VSManager + + HAS_SL = True + vsManager = VSManager(SoftLayer.create_client_from_env()) +except ImportError: + HAS_SL = False + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.six import string_types + + #TODO: get this info from API STATES = ['present', 'absent'] DATACENTERS = ['ams01', 'ams03', 'che01', 'dal01', 'dal05', 'dal06', 'dal09', 'dal10', 'fra02', 'hkg02', 'hou02', 'lon02', 'mel01', 'mex01', 'mil01', 'mon01', @@ -249,15 +263,6 @@ LOCALDISK_SIZES = [25, 100, 150, 200, 300] SANDISK_SIZES = [10, 20, 25, 30, 40, 50, 75, 100, 125, 150, 175, 200, 250, 300, 350, 400, 500, 750, 1000, 1500, 2000] NIC_SPEEDS = [10, 100, 1000] -try: - import SoftLayer - from SoftLayer import VSManager - - HAS_SL = True - vsManager = VSManager(SoftLayer.create_client_from_env()) -except ImportError: - HAS_SL = False - def create_virtual_instance(module): @@ -329,7 +334,7 @@ def cancel_instance(module): canceled = True if module.params.get('instance_id') is None and (module.params.get('tags') or module.params.get('hostname') or module.params.get('domain')): tags = module.params.get('tags') - if isinstance(tags, basestring): + if isinstance(tags, string_types): tags = [module.params.get('tags')] instances = vsManager.list_instances(tags = tags, hostname = module.params.get('hostname'), domain = module.params.get('domain')) for instance in instances: @@ -390,7 +395,6 @@ def main(): module.exit_json(changed=changed, instance=json.loads(json.dumps(instance, default=lambda o: o.__dict__))) -from ansible.module_utils.basic import * if __name__ == '__main__': main() diff --git a/lib/ansible/modules/cloud/vmware/vca_fw.py b/lib/ansible/modules/cloud/vmware/vca_fw.py index 8e74e70f8da..6d56634b252 100644 --- a/lib/ansible/modules/cloud/vmware/vca_fw.py +++ b/lib/ansible/modules/cloud/vmware/vca_fw.py @@ -207,9 +207,9 @@ def main(): except IndexError: additions.append(rule) - eol = len(current_rules) > len(desired_rules) + eol = len(current_rules) - len(desired_rules) if eol > 0: - for rule in current_rules[eos:]: + for rule in current_rules[eol:]: deletions.append(rule) for rule in additions: diff --git a/lib/ansible/modules/cloud/vmware/vsphere_guest.py b/lib/ansible/modules/cloud/vmware/vsphere_guest.py index 009af7058ae..2939e4df449 100644 --- a/lib/ansible/modules/cloud/vmware/vsphere_guest.py +++ b/lib/ansible/modules/cloud/vmware/vsphere_guest.py @@ -1,5 +1,4 @@ #!/usr/bin/python - # -*- coding: utf-8 -*- # This file is part of Ansible # @@ -308,10 +307,11 @@ EXAMPLES = ''' force: yes ''' -try: - import json -except ImportError: - import simplejson as json +import json +import os +import re +import ssl +import traceback HAS_PYSPHERE = False try: @@ -323,7 +323,9 @@ try: except ImportError: pass -import ssl +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.six import string_types +from ansible.module_utils._text import to_native def add_scsi_controller(module, s, config, devices, type="paravirtual", bus_num=0, disk_ctrl_key=1): @@ -1041,11 +1043,10 @@ def reconfigure_vm(vsphere_client, vm, module, esxi, resource_pool, cluster_name vm.power_off(sync_run=True) vm.get_status() - except Exception: - e = get_exception() - module.fail_json( - msg='Failed to shutdown vm %s: %s' % (guest, e) - ) + except Exception as e: + module.fail_json(msg='Failed to shutdown vm %s: %s' + % (guest, to_native(e)), + exception=traceback.format_exc()) if len(devices): spec.set_element_deviceChange(devices) @@ -1065,10 +1066,10 @@ def reconfigure_vm(vsphere_client, vm, module, esxi, resource_pool, cluster_name if vm.is_powered_off() and poweron: try: vm.power_on(sync_run=True) - except Exception: - e = get_exception() + except Exception as e: module.fail_json( - msg='Failed to power on vm %s : %s' % (guest, e) + msg='Failed to power on vm %s : %s' % (guest, to_native(e)), + exception=traceback.format_exc() ) vsphere_client.disconnect() @@ -1503,10 +1504,10 @@ def delete_vm(vsphere_client, module, guest, vm, force): vm.power_off(sync_run=True) vm.get_status() - except Exception: - e = get_exception() + except Exception as e: module.fail_json( - msg='Failed to shutdown vm %s: %s' % (guest, e)) + msg='Failed to shutdown vm %s: %s' % (guest, to_native(e)), + exception=traceback.format_exc()) else: module.fail_json( msg='You must use either shut the vm down first or ' @@ -1528,10 +1529,10 @@ def delete_vm(vsphere_client, module, guest, vm, force): module.fail_json(msg="Error removing vm: %s %s" % task.get_error_message()) module.exit_json(changed=True, changes="VM %s deleted" % guest) - except Exception: - e = get_exception() + except Exception as e: module.fail_json( - msg='Failed to delete vm %s : %s' % (guest, e)) + msg='Failed to delete vm %s : %s' % (guest, to_native(e)), + exception=traceback.format_exc()) def power_state(vm, state, force): @@ -1571,8 +1572,8 @@ def power_state(vm, state, force): % power_status return True - except Exception: - return get_exception() + except Exception as e: + return e return False @@ -1650,8 +1651,9 @@ class DefaultVMConfig(object): try: if v == int: self.check_dict[key][k] = int(self.check_dict[key][k]) - elif v == basestring: - self.check_dict[key][k] = str(self.check_dict[key][k]) + elif v == string_types: + self.check_dict[key][k] = to_native(self.check_dict[key][k], + errors='surrogate_or_strict') else: raise ValueError except ValueError: @@ -1689,29 +1691,29 @@ def main(): proto_vm_hardware = { 'memory_mb': int, 'num_cpus': int, - 'scsi': basestring, - 'osid': basestring + 'scsi': string_types, + 'osid': string_types } proto_vm_disk = { 'disk1': { - 'datastore': basestring, + 'datastore': string_types, 'size_gb': int, - 'type': basestring + 'type': string_types } } proto_vm_nic = { 'nic1': { - 'type': basestring, - 'network': basestring, - 'network_type': basestring + 'type': string_types, + 'network': string_types, + 'network_type': string_types } } proto_esxi = { - 'datacenter': basestring, - 'hostname': basestring + 'datacenter': string_types, + 'hostname': string_types } module = AnsibleModule( @@ -1816,10 +1818,10 @@ def main(): module.fail_json(msg='Unable to validate the certificate of the vcenter host %s' % vcenter_hostname) else: raise - except VIApiException: - err = get_exception() + except VIApiException as err: module.fail_json(msg="Cannot connect to %s: %s" % - (vcenter_hostname, err)) + (vcenter_hostname, to_native(err)), + exception=traceback.format_exc()) # Check if the VM exists before continuing try: @@ -1832,16 +1834,15 @@ def main(): if vmware_guest_facts: try: module.exit_json(ansible_facts=gather_facts(vm)) - except Exception: - e = get_exception() - module.fail_json( - msg="Fact gather failed with exception %s" % e) + except Exception as e: + module.fail_json(msg="Fact gather failed with exception %s" + % to_native(e), exception=traceback.format_exc()) # Power Changes elif state in ['powered_on', 'powered_off', 'restarted']: state_result = power_state(vm, state, force) # Failure - if isinstance(state_result, basestring): + if isinstance(state_result, string_types): module.fail_json(msg=state_result) else: module.exit_json(changed=state_result) @@ -1941,7 +1942,5 @@ def main(): vcenter=vcenter_hostname) -# this is magic, see lib/ansible/module_common.py -from ansible.module_utils.basic import * if __name__ == '__main__': main() diff --git a/lib/ansible/modules/clustering/consul.py b/lib/ansible/modules/clustering/consul.py index b42a66b9a17..c1048c010aa 100644 --- a/lib/ansible/modules/clustering/consul.py +++ b/lib/ansible/modules/clustering/consul.py @@ -242,6 +242,8 @@ try: except ImportError: python_consul_installed = False +from ansible.module_utils.basic import AnsibleModule + def register_with_consul(module): state = module.params.get('state') @@ -285,7 +287,7 @@ def add_check(module, check): retrieve the full metadata of an existing check through the consul api. Without this we can't compare to the supplied check and so we must assume a change. ''' - if not check.name and not service_id: + if not check.name and not check.service_id: module.fail_json(msg='a check name is required for a node level check, one not attached to a service') consul_api = get_consul_api(module) @@ -425,7 +427,7 @@ class ConsulService(): optional['port'] = self.port if len(self.checks) > 0: - optional['check'] = checks[0].check + optional['check'] = self.checks[0].check consul_api.agent.service.register( self.name, @@ -464,7 +466,7 @@ class ConsulService(): return data -class ConsulCheck(): +class ConsulCheck(object): def __init__(self, check_id, name, node=None, host='localhost', script=None, interval=None, ttl=None, notes=None, http=None, timeout=None, service_id=None): @@ -513,8 +515,8 @@ class ConsulCheck(): self.check_id == other.check_id and self.service_id == other.service_id and self.name == other.name and - self.script == script and - self.interval == interval) + self.script == other.script and + self.interval == other.interval) def __ne__(self, other): return not self.__eq__(other) @@ -586,7 +588,6 @@ def main(): except Exception as e: module.fail_json(msg=str(e)) -# import module snippets -from ansible.module_utils.basic import * + if __name__ == '__main__': main() diff --git a/lib/ansible/modules/clustering/consul_acl.py b/lib/ansible/modules/clustering/consul_acl.py index 8aaa87916bc..b7945d372e1 100644 --- a/lib/ansible/modules/clustering/consul_acl.py +++ b/lib/ansible/modules/clustering/consul_acl.py @@ -140,6 +140,10 @@ except ImportError: from requests.exceptions import ConnectionError +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils._text import to_bytes + + def execute(module): state = module.params.get('state') @@ -216,22 +220,17 @@ def load_rules_for_token(module, consul_api, token): rules = Rules() info = consul_api.acl.info(token) if info and info['Rules']: - rule_set = hcl.loads(to_ascii(info['Rules'])) + rule_set = hcl.loads(to_bytes(info['Rules'], errors='ignore', nonstring='passthru')) for rule_type in rule_set: for pattern, policy in rule_set[rule_type].items(): rules.add_rule(rule_type, Rule(pattern, policy['policy'])) - return rules except Exception as e: module.fail_json( msg="Could not load rule list from retrieved rule data %s, %s" % ( token, e)) - return json_to_rules(module, loaded) + return rules -def to_ascii(unicode_string): - if isinstance(unicode_string, unicode): - return unicode_string.encode('ascii', 'ignore') - return unicode_string def yml_to_rules(module, yml_rules): rules = Rules() @@ -275,7 +274,7 @@ class Rules: for rule_type in RULE_TYPES: for pattern, rule in self.rules[rule_type].items(): rules += template % (rule_type, pattern, rule.policy) - return to_ascii(rules) + return to_bytes(rules, errors='ignore', nonstring='passthru') def __len__(self): count = 0 @@ -362,7 +361,6 @@ def main(): except Exception as e: module.fail_json(msg=str(e)) -# import module snippets -from ansible.module_utils.basic import * + if __name__ == '__main__': main() diff --git a/lib/ansible/modules/database/mongodb/mongodb_user.py b/lib/ansible/modules/database/mongodb/mongodb_user.py index 7694b0677c8..ed9e43b7edc 100644 --- a/lib/ansible/modules/database/mongodb/mongodb_user.py +++ b/lib/ansible/modules/database/mongodb/mongodb_user.py @@ -203,6 +203,7 @@ user: import os import ssl as ssl_lib +import traceback from distutils.version import LooseVersion try: @@ -221,8 +222,9 @@ else: pymongo_found = True from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.pycompat24 import get_exception +from ansible.module_utils.six import binary_type, text_type from ansible.module_utils.six.moves import configparser +from ansible.module_utils._text import to_native # ========================================= @@ -333,7 +335,7 @@ def check_if_roles_changed(uinfo, roles, db_name): def make_sure_roles_are_a_list_of_dict(roles, db_name): output = list() for role in roles: - if isinstance(role, basestring): + if isinstance(role, (binary_type, text_type)): new_role = { "role": role, "db": db_name } output.append(new_role) else: @@ -427,9 +429,8 @@ def main(): module.fail_json(msg='The localhost login exception only allows the first admin account to be created') #else: this has to be the first admin user added - except Exception: - e = get_exception() - module.fail_json(msg='unable to connect to database: %s' % str(e)) + except Exception as e: + module.fail_json(msg='unable to connect to database: %s' % to_native(e), exception=traceback.format_exc()) if state == 'present': if password is None and update_password == 'always': @@ -447,9 +448,8 @@ def main(): module.exit_json(changed=True, user=user) user_add(module, client, db_name, user, password, roles) - except Exception: - e = get_exception() - module.fail_json(msg='Unable to add or update user: %s' % str(e)) + except Exception as e: + module.fail_json(msg='Unable to add or update user: %s' % to_native(e), exception=traceback.format_exc()) # Here we can check password change if mongo provide a query for that : https://jira.mongodb.org/browse/SERVER-22848 #newuinfo = user_find(client, user, db_name) @@ -459,9 +459,8 @@ def main(): elif state == 'absent': try: user_remove(module, client, db_name, user) - except Exception: - e = get_exception() - module.fail_json(msg='Unable to remove user: %s' % str(e)) + except Exception as e: + module.fail_json(msg='Unable to remove user: %s' % to_native(e), exception=traceback.format_exc()) module.exit_json(changed=True, user=user) diff --git a/lib/ansible/modules/database/postgresql/postgresql_privs.py b/lib/ansible/modules/database/postgresql/postgresql_privs.py index 8f8aa9d3d9d..c187909a01e 100644 --- a/lib/ansible/modules/database/postgresql/postgresql_privs.py +++ b/lib/ansible/modules/database/postgresql/postgresql_privs.py @@ -251,16 +251,25 @@ EXAMPLES = """ role: librarian """ +import traceback + try: import psycopg2 import psycopg2.extensions except ImportError: psycopg2 = None +# import module snippets +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.database import pg_quote_identifier +from ansible.module_utils._text import to_native, to_text + VALID_PRIVS = frozenset(('SELECT', 'INSERT', 'UPDATE', 'DELETE', 'TRUNCATE', 'REFERENCES', 'TRIGGER', 'CREATE', 'CONNECT', 'TEMPORARY', 'TEMP', 'EXECUTE', 'USAGE', 'ALL', 'USAGE')) + + class Error(Exception): pass @@ -306,17 +315,10 @@ class Connection(object): sslrootcert = params.ssl_rootcert if psycopg2.__version__ < '2.4.3' and sslrootcert is not None: - module.fail_json(msg='psycopg2 must be at least 2.4.3 in order to user the ssl_rootcert parameter') + raise ValueError('psycopg2 must be at least 2.4.3 in order to user the ssl_rootcert parameter') - try: - self.connection = psycopg2.connect(**kw) - self.cursor = self.connection.cursor() - - except TypeError: - e = get_exception() - if 'sslrootcert' in e.args[0]: - module.fail_json(msg='Postgresql server must be at least version 8.4 to support sslrootcert') - module.fail_json(msg="unable to connect to database: %s" % e) + self.connection = psycopg2.connect(**kw) + self.cursor = self.connection.cursor() def commit(self): @@ -611,9 +613,15 @@ def main(): module.fail_json(msg='Python module "psycopg2" must be installed.') try: conn = Connection(p) - except psycopg2.Error: - e = get_exception() - module.fail_json(msg='Could not connect to database: %s' % e) + except psycopg2.Error as e: + module.fail_json(msg='Could not connect to database: %s' % to_native(e), exception=traceback.format_exc()) + except TypeError as e: + if 'sslrootcert' in e.args[0]: + module.fail_json(msg='Postgresql server must be at least version 8.4 to support sslrootcert') + module.fail_json(msg="unable to connect to database: %s" % to_native(e), exception=traceback.format_exc()) + except ValueError as e: + # We raise this when the psycopg library is too old + module.fail_json(msg=to_native(e)) try: # privs @@ -652,17 +660,14 @@ def main(): schema_qualifier=p.schema ) - except Error: - e = get_exception() + except Error as e: conn.rollback() - module.fail_json(msg=e.message) + module.fail_json(msg=e.message, exception=traceback.format_exc()) - except psycopg2.Error: - e = get_exception() + except psycopg2.Error as e: conn.rollback() - # psycopg2 errors come in connection encoding, re-encode - msg = e.message.decode(conn.encoding).encode(sys.getdefaultencoding(), - 'replace') + # psycopg2 errors come in connection encoding + msg = to_text(e.message(encoding=conn.encoding)) module.fail_json(msg=msg) if module.check_mode: @@ -672,8 +677,5 @@ def main(): module.exit_json(changed=changed) -# import module snippets -from ansible.module_utils.basic import * -from ansible.module_utils.database import * if __name__ == '__main__': main() diff --git a/lib/ansible/modules/monitoring/boundary_meter.py b/lib/ansible/modules/monitoring/boundary_meter.py index 2088bb34480..b99d46ddd5a 100644 --- a/lib/ansible/modules/monitoring/boundary_meter.py +++ b/lib/ansible/modules/monitoring/boundary_meter.py @@ -88,17 +88,9 @@ EXAMPLES=''' ''' import base64 +import json import os -try: - import json -except ImportError: - try: - import simplejson as json - except ImportError: - # Let snippet from module_utils/basic.py return a proper error in this case - pass - from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.urls import fetch_url @@ -205,6 +197,7 @@ def delete_meter(module, name, apiid, apikey): if meter_id is None: return 1, "Meter does not exist, so can't delete it" else: + action = "delete" response, info = http_request(module, name, apiid, apikey, action, meter_id) if info['status'] != 200: module.fail_json(msg="Failed to delete meter") @@ -230,7 +223,7 @@ def download_request(module, name, apiid, apikey, cert_type): if info['status'] != 200: module.fail_json(msg="Failed to connect to api host to download certificate") - if result: + if response: try: cert_file_path = '%s/%s.pem' % (config_directory,cert_type) body = response.read() @@ -276,4 +269,3 @@ def main(): if __name__ == '__main__': main() - diff --git a/lib/ansible/modules/monitoring/librato_annotation.py b/lib/ansible/modules/monitoring/librato_annotation.py index a37627ce526..98c88ff5983 100644 --- a/lib/ansible/modules/monitoring/librato_annotation.py +++ b/lib/ansible/modules/monitoring/librato_annotation.py @@ -108,6 +108,10 @@ EXAMPLES = ''' end_time: 1395954406 ''' +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.urls import fetch_url + + def post_annotation(module): user = module.params['user'] api_key = module.params['api_key'] @@ -139,7 +143,7 @@ def post_annotation(module): module.params['url_password'] = api_key response, info = fetch_url(module, url, data=json_body, headers=headers) if info['status'] != 200: - module.fail_json(msg="Request Failed", reason=e.reason) + module.fail_json(msg="Request Failed", reason=info.get('msg', ''), status_code=info['status']) response = response.read() module.exit_json(changed=True, annotation=response) @@ -161,7 +165,6 @@ def main(): post_annotation(module) -from ansible.module_utils.basic import * -from ansible.module_utils.urls import * + if __name__ == '__main__': main() diff --git a/lib/ansible/modules/monitoring/statusio_maintenance.py b/lib/ansible/modules/monitoring/statusio_maintenance.py index 410052e2cc7..d6fb39c7f5e 100644 --- a/lib/ansible/modules/monitoring/statusio_maintenance.py +++ b/lib/ansible/modules/monitoring/statusio_maintenance.py @@ -190,6 +190,11 @@ EXAMPLES = ''' RETURN = ''' # ''' import datetime +import json + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils._text import to_native +from ansible.module_utils.urls import open_url def get_api_auth_headers(api_id, api_key, url, statuspage): @@ -210,8 +215,8 @@ def get_api_auth_headers(api_id, api_key, url, statuspage): else: auth_headers = headers auth_content = data - except: - return 1, None, None, e + except Exception as e: + return 1, None, None, to_native(e) return 0, auth_headers, auth_content, None @@ -320,9 +325,8 @@ def create_maintenance(auth_headers, url, statuspage, host_ids, if data["status"]["error"] == "yes": return 1, None, data["status"]["message"] - except Exception: - e = get_exception() - return 1, None, str(e) + except Exception as e: + return 1, None, to_native(e) return 0, None, None @@ -339,9 +343,8 @@ def delete_maintenance(auth_headers, url, statuspage, maintenance_id): data = json.loads(response.read()) if data["status"]["error"] == "yes": return 1, None, "Invalid maintenance_id" - except Exception: - e = get_exception() - return 1, None, str(e) + except Exception as e: + return 1, None, to_native(e) return 0, None, None @@ -475,7 +478,6 @@ def main(): module.fail_json( msg="Failed to delete maintenance: %s" % error) -from ansible.module_utils.basic import * -from ansible.module_utils.urls import * + if __name__ == '__main__': main() diff --git a/lib/ansible/modules/net_tools/dnsmadeeasy.py b/lib/ansible/modules/net_tools/dnsmadeeasy.py index 6632b4f7cfa..ef4d0e033f9 100644 --- a/lib/ansible/modules/net_tools/dnsmadeeasy.py +++ b/lib/ansible/modules/net_tools/dnsmadeeasy.py @@ -385,19 +385,18 @@ EXAMPLES = ''' # DNSMadeEasy module specific support methods. # +import json +import hashlib +import hmac +from time import strftime, gmtime + +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.urls import fetch_url from ansible.module_utils.six.moves.urllib.parse import urlencode +from ansible.module_utils.six import string_types -IMPORT_ERROR = None -try: - import json - from time import strftime, gmtime - import hashlib - import hmac -except ImportError: - e = get_exception() - IMPORT_ERROR = str(e) -class DME2: +class DME2(object): def __init__(self, apikey, secret, domain, module): self.module = module @@ -437,7 +436,7 @@ class DME2: def query(self, resource, method, data=None): url = self.baseurl + resource - if data and not isinstance(data, basestring): + if data and not isinstance(data, string_types): data = urlencode(data) response, info = fetch_url(self.module, url, data=data, method=method, headers=self._headers()) @@ -601,9 +600,6 @@ def main(): ] ) - if IMPORT_ERROR: - module.fail_json(msg="Import Error: " + IMPORT_ERROR) - protocols = dict(TCP=1, UDP=2, HTTP=3, DNS=4, SMTP=5, HTTPS=6) sensitivities = dict(Low=8, Medium=5, High=3) @@ -727,9 +723,6 @@ def main(): module.fail_json( msg="'%s' is an unknown value for the state argument" % state) -# import module snippets -from ansible.module_utils.basic import * -from ansible.module_utils.urls import * if __name__ == '__main__': main() diff --git a/lib/ansible/modules/net_tools/ldap/ldap_entry.py b/lib/ansible/modules/net_tools/ldap/ldap_entry.py index 0f53828fb65..1b99822a2de 100644 --- a/lib/ansible/modules/net_tools/ldap/ldap_entry.py +++ b/lib/ansible/modules/net_tools/ldap/ldap_entry.py @@ -156,8 +156,7 @@ RETURN = """ # Default return values """ -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.pycompat24 import get_exception +import traceback try: import ldap @@ -168,6 +167,10 @@ try: except ImportError: HAS_LDAP = False +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.six import string_types +from ansible.module_utils._text import to_native + class LdapEntry(object): def __init__(self, module): @@ -251,19 +254,19 @@ class LdapEntry(object): if self.start_tls: try: connection.start_tls_s() - except ldap.LDAPError: - e = get_exception() - self.module.fail_json(msg="Cannot start TLS.", details=str(e)) + except ldap.LDAPError as e: + self.module.fail_json(msg="Cannot start TLS.", details=to_native(e), + exception=traceback.format_exc()) try: if self.bind_dn is not None: connection.simple_bind_s(self.bind_dn, self.bind_pw) else: connection.sasl_interactive_bind_s('', ldap.sasl.external()) - except ldap.LDAPError: - e = get_exception() + except ldap.LDAPError as e: self.module.fail_json( - msg="Cannot bind to the server.", details=str(e)) + msg="Cannot bind to the server.", details=to_native(e), + exception=traceback.format_exc()) return connection @@ -298,7 +301,7 @@ def main(): # Check if objectClass is of the correct type if ( module.params['objectClass'] is not None and not ( - isinstance(module.params['objectClass'], basestring) or + isinstance(module.params['objectClass'], string_types) or isinstance(module.params['objectClass'], list))): module.fail_json(msg="objectClass must be either a string or a list.") @@ -326,9 +329,8 @@ def main(): if action is not None and not module.check_mode: try: action() - except Exception: - e = get_exception() - module.fail_json(msg="Entry action failed.", details=str(e)) + except Exception as e: + module.fail_json(msg="Entry action failed.", details=to_native(e), exception=traceback.format_exc()) module.exit_json(changed=(action is not None)) diff --git a/lib/ansible/modules/network/aos/aos_device.py b/lib/ansible/modules/network/aos/aos_device.py index 3ccbb737d9f..7f4f3e11e4b 100644 --- a/lib/ansible/modules/network/aos/aos_device.py +++ b/lib/ansible/modules/network/aos/aos_device.py @@ -101,7 +101,11 @@ value: ''' from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.aos import get_aos_session, check_aos_version, find_collection_item +from ansible.module_utils.aos import HAS_AOS_PYEZ, get_aos_session, check_aos_version, find_collection_item + +if HAS_AOS_PYEZ: + from apstra.aosom.exc import SessionError, SessionRqstError + def aos_device_normal(module, aos, dev): diff --git a/lib/ansible/modules/network/asa/asa_command.py b/lib/ansible/modules/network/asa/asa_command.py index 5e927cf2c67..0e8f79849d4 100644 --- a/lib/ansible/modules/network/asa/asa_command.py +++ b/lib/ansible/modules/network/asa/asa_command.py @@ -133,9 +133,12 @@ failed_conditions: type: list sample: ['...', '...'] """ +import time + from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.asa import asa_argument_spec, check_args from ansible.module_utils.asa import run_commands +from ansible.module_utils.netcli import Conditional from ansible.module_utils.six import string_types diff --git a/lib/ansible/modules/network/cloudengine/ce_command.py b/lib/ansible/modules/network/cloudengine/ce_command.py index ccdc054d19e..ee913ce3dfb 100644 --- a/lib/ansible/modules/network/cloudengine/ce_command.py +++ b/lib/ansible/modules/network/cloudengine/ce_command.py @@ -150,19 +150,21 @@ failed_conditions: import time +import traceback -from ansible.module_utils.ce import run_commands -from ansible.module_utils.pycompat24 import get_exception from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.ce import ce_argument_spec, check_args +from ansible.module_utils.ce import run_commands from ansible.module_utils.netcli import Conditional from ansible.module_utils.network_common import ComplexList -from ansible.module_utils.ce import ce_argument_spec, check_args +from ansible.module_utils.six import string_types +from ansible.module_utils._text import to_native def to_lines(stdout): lines = list() for item in stdout: - if isinstance(item, basestring): + if isinstance(item, string_types): item = str(item).split('\n') lines.append(item) return lines @@ -223,9 +225,8 @@ def main(): try: conditionals = [Conditional(c) for c in wait_for] - except AttributeError: - exc = get_exception() - module.fail_json(msg=str(exc)) + except AttributeError as exc: + module.fail_json(msg=to_native(exc), exception=traceback.format_exc()) retries = module.params['retries'] interval = module.params['interval'] diff --git a/lib/ansible/modules/network/cloudengine/ce_ntp.py b/lib/ansible/modules/network/cloudengine/ce_ntp.py index b9cf4e30556..0de1ab8d07e 100644 --- a/lib/ansible/modules/network/cloudengine/ce_ntp.py +++ b/lib/ansible/modules/network/cloudengine/ce_ntp.py @@ -353,8 +353,8 @@ class Ntp(object): if not addr_list: self.module.fail_json(msg='Error: Match ip-address fail.') - value = ((long(addr_list[0][0])) * 0x1000000) + (long(addr_list[0][1]) * 0x10000) + \ - (long(addr_list[0][2]) * 0x100) + (long(addr_list[0][3])) + value = ((int(addr_list[0][0])) * 0x1000000) + (int(addr_list[0][1]) * 0x10000) + \ + (int(addr_list[0][2]) * 0x100) + (int(addr_list[0][3])) if (value & (0xff000000) == 0x7f000000) or (value & (0xF0000000) == 0xF0000000) \ or (value & (0xF0000000) == 0xE0000000) or (value == 0): return False diff --git a/lib/ansible/modules/network/cloudengine/ce_ntp_auth.py b/lib/ansible/modules/network/cloudengine/ce_ntp_auth.py index 70c61c90cb3..3bf59ebb520 100644 --- a/lib/ansible/modules/network/cloudengine/ce_ntp_auth.py +++ b/lib/ansible/modules/network/cloudengine/ce_ntp_auth.py @@ -200,8 +200,9 @@ changed: sample: true ''' -import re import copy +import re + from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.ce import ce_argument_spec, load_config, get_nc_config, set_nc_config @@ -322,7 +323,7 @@ class NtpAuth(object): self.module.fail_json( msg='Error: key_id is not digit.') - if (long(self.key_id) < 1) or (long(self.key_id) > 4294967295): + if (int(self.key_id) < 1) or (int(self.key_id) > 4294967295): self.module.fail_json( msg='Error: The length of key_id is between 1 and 4294967295.') diff --git a/lib/ansible/modules/network/dellos10/dellos10_command.py b/lib/ansible/modules/network/dellos10/dellos10_command.py index 03bc7bab45d..900a8ac0017 100644 --- a/lib/ansible/modules/network/dellos10/dellos10_command.py +++ b/lib/ansible/modules/network/dellos10/dellos10_command.py @@ -147,11 +147,12 @@ from ansible.module_utils.dellos10 import dellos10_argument_spec, check_args from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.network_common import ComplexList from ansible.module_utils.netcli import Conditional +from ansible.module_utils.six import string_types def to_lines(stdout): for item in stdout: - if isinstance(item, basestring): + if isinstance(item, string_types): item = str(item).split('\n') yield item diff --git a/lib/ansible/modules/network/dellos10/dellos10_facts.py b/lib/ansible/modules/network/dellos10/dellos10_facts.py index b58da66ee8a..b1910ed7a30 100644 --- a/lib/ansible/modules/network/dellos10/dellos10_facts.py +++ b/lib/ansible/modules/network/dellos10/dellos10_facts.py @@ -134,21 +134,21 @@ ansible_net_neighbors: import re +try: + from lxml import etree as ET +except ImportError: + import xml.etree.ElementTree as ET + from ansible.module_utils.dellos10 import run_commands from ansible.module_utils.dellos10 import dellos10_argument_spec, check_args from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.six import iteritems from ansible.module_utils.six.moves import zip -try: - from lxml import etree as ET -except ImportError: - import xml.etree.ElementTree as ET - class FactsBase(object): - COMMANDS = list() + COMMANDS = [] def __init__(self, module): self.module = module @@ -365,7 +365,7 @@ class Interfaces(FactsBase): intf['mediatype'] = mediatype except: # fanout - for subport in xrange(1, 5): + for subport in range(1, 5): name = "ethernet" + sname + ":" + str(subport) try: intf = self.intf_facts[name] diff --git a/lib/ansible/modules/network/dellos6/dellos6_command.py b/lib/ansible/modules/network/dellos6/dellos6_command.py index 6a5cc5ddb54..14add0cc1c8 100644 --- a/lib/ansible/modules/network/dellos6/dellos6_command.py +++ b/lib/ansible/modules/network/dellos6/dellos6_command.py @@ -143,16 +143,17 @@ warnings: import time +from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.dellos6 import run_commands from ansible.module_utils.dellos6 import dellos6_argument_spec, check_args -from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.network_common import ComplexList from ansible.module_utils.netcli import Conditional +from ansible.module_utils.six import string_types def to_lines(stdout): for item in stdout: - if isinstance(item, basestring): + if isinstance(item, string_types): item = str(item).split('\n') yield item diff --git a/lib/ansible/modules/network/dellos9/dellos9_command.py b/lib/ansible/modules/network/dellos9/dellos9_command.py index 4eba06342aa..d453767d88d 100644 --- a/lib/ansible/modules/network/dellos9/dellos9_command.py +++ b/lib/ansible/modules/network/dellos9/dellos9_command.py @@ -147,16 +147,17 @@ warnings: """ import time +from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.dellos9 import run_commands from ansible.module_utils.dellos9 import dellos9_argument_spec, check_args -from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.network_common import ComplexList from ansible.module_utils.netcli import Conditional +from ansible.module_utils.six import string_types def to_lines(stdout): for item in stdout: - if isinstance(item, basestring): + if isinstance(item, string_types): item = str(item).split('\n') yield item diff --git a/lib/ansible/modules/network/f5/bigip_ucs.py b/lib/ansible/modules/network/f5/bigip_ucs.py index bcd9cefc1c4..1efc1b78576 100644 --- a/lib/ansible/modules/network/f5/bigip_ucs.py +++ b/lib/ansible/modules/network/f5/bigip_ucs.py @@ -398,7 +398,7 @@ class BaseManager(object): def wait_for_rest_api_restart(self): time.sleep(5) - for x in xrange(0, 60): + for x in range(0, 60): try: self.client.reconnect() break diff --git a/lib/ansible/modules/network/nxos/nxos_pim_interface.py b/lib/ansible/modules/network/nxos/nxos_pim_interface.py index 02bd5c83497..6be6cdb8a92 100644 --- a/lib/ansible/modules/network/nxos/nxos_pim_interface.py +++ b/lib/ansible/modules/network/nxos/nxos_pim_interface.py @@ -147,9 +147,10 @@ commands: ''' +from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.nxos import get_config, load_config, run_commands from ansible.module_utils.nxos import nxos_argument_spec, check_args -from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.six import string_types PARAM_TO_COMMAND_KEYMAP = { @@ -251,8 +252,7 @@ def get_pim_interface(module, interface): try: get_data = body[0]['TABLE_iod']['ROW_iod'] - if isinstance(get_data.get('dr-priority'), unicode) or \ - isinstance(get_data.get('dr-priority'), str): + if isinstance(get_data.get('dr-priority'), string_types): pim_interface['dr_prio'] = get_data.get('dr-priority') else: pim_interface['dr_prio'] = get_data.get('dr-priority')[0] @@ -283,8 +283,7 @@ def get_pim_interface(module, interface): if jp_in_policy == 'none configured': pim_interface['jp_policy_in'] = None - if isinstance(get_data.get('jp-out-policy-name'), unicode) or \ - isinstance(get_data.get('jp-out-policy-name'), str): + if isinstance(get_data.get('jp-out-policy-name'), string_types): pim_interface['jp_policy_out'] = get_data.get('jp-out-policy-name') else: pim_interface['jp_policy_out'] = get_data.get( diff --git a/lib/ansible/modules/network/ordnance/ordnance_facts.py b/lib/ansible/modules/network/ordnance/ordnance_facts.py index 1a4ad78ea2a..9f98ed703e2 100644 --- a/lib/ansible/modules/network/ordnance/ordnance_facts.py +++ b/lib/ansible/modules/network/ordnance/ordnance_facts.py @@ -101,12 +101,14 @@ ansible_net_interfaces: returned: when interfaces is configured type: dict """ -import re import itertools +import re +import traceback from ansible.module_utils.network import NetworkModule from ansible.module_utils.six import iteritems from ansible.module_utils.six.moves import zip +from ansible.module_utils._text import to_native class FactsBase(object): @@ -283,9 +285,8 @@ def main(): inst.populate() failed_commands.extend(inst.failed_commands) facts.update(inst.facts) - except Exception: - exc = get_exception() - module.fail_json(msg=str(exc)) + except Exception as exc: + module.fail_json(msg=to_native(exc), exception=traceback.format_exc()) ansible_facts = dict() for key, value in iteritems(facts): diff --git a/lib/ansible/modules/network/panos/panos_restart.py b/lib/ansible/modules/network/panos/panos_restart.py index 43542394036..faaebba5169 100644 --- a/lib/ansible/modules/network/panos/panos_restart.py +++ b/lib/ansible/modules/network/panos/panos_restart.py @@ -65,8 +65,8 @@ ANSIBLE_METADATA = {'metadata_version': '1.0', 'supported_by': 'community'} -from ansible.module_utils.basic import AnsibleModule import sys +import traceback try: import pan.xapi @@ -74,6 +74,10 @@ try: except ImportError: HAS_LIB = False +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils._text import to_native + + def main(): argument_spec = dict( ip_address=dict(), @@ -101,15 +105,14 @@ def main(): try: xapi.op(cmd="") - except Exception: - x = sys.exc_info()[1] - if 'succeeded' in str(x): - module.exit_json(changed=True, msg=str(msg)) + except Exception as e: + if 'succeeded' in to_native(e): + module.exit_json(changed=True, msg=to_native(e)) else: - module.fail_json(msg=x) - raise + module.fail_json(msg=to_native(e), exception=traceback.format_exc()) module.exit_json(changed=True, msg="okey dokey") + if __name__ == '__main__': main() diff --git a/lib/ansible/modules/packaging/os/homebrew.py b/lib/ansible/modules/packaging/os/homebrew.py index 21b0961fc0f..8bd795d3580 100644 --- a/lib/ansible/modules/packaging/os/homebrew.py +++ b/lib/ansible/modules/packaging/os/homebrew.py @@ -137,7 +137,8 @@ EXAMPLES = ''' import os.path import re -from ansible.module_utils.six import iteritems +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.six import iteritems, string_types # exceptions -------------------------------------------------------------- {{{ @@ -206,7 +207,7 @@ class Homebrew(object): - os.path.sep ''' - if isinstance(path, basestring): + if isinstance(path, string_types): return not cls.INVALID_PATH_REGEX.search(path) try: @@ -234,7 +235,7 @@ class Homebrew(object): return True return ( - isinstance(brew_path, basestring) + isinstance(brew_path, string_types) and not cls.INVALID_BREW_PATH_REGEX.search(brew_path) ) @@ -246,7 +247,7 @@ class Homebrew(object): return True return ( - isinstance(package, basestring) + isinstance(package, string_types) and not cls.INVALID_PACKAGE_REGEX.search(package) ) @@ -267,7 +268,7 @@ class Homebrew(object): return True else: return ( - isinstance(state, basestring) + isinstance(state, string_types) and state.lower() in ( 'installed', 'upgraded', @@ -316,7 +317,7 @@ class Homebrew(object): raise HomebrewException(self.message) else: - if isinstance(path, basestring): + if isinstance(path, string_types): self._path = path.split(':') else: self._path = path @@ -515,7 +516,7 @@ class Homebrew(object): 'update', ]) if rc == 0: - if out and isinstance(out, basestring): + if out and isinstance(out, string_types): already_updated = any( re.search(r'Already up-to-date.', s.strip(), re.IGNORECASE) for s in out.split('\n') @@ -902,8 +903,6 @@ def main(): else: module.exit_json(changed=changed, msg=message) -# this is magic, see lib/ansible/module_common.py -from ansible.module_utils.basic import * if __name__ == '__main__': main() diff --git a/lib/ansible/modules/packaging/os/homebrew_cask.py b/lib/ansible/modules/packaging/os/homebrew_cask.py index 6149ef21c22..82d09c12ab2 100644 --- a/lib/ansible/modules/packaging/os/homebrew_cask.py +++ b/lib/ansible/modules/packaging/os/homebrew_cask.py @@ -97,7 +97,8 @@ EXAMPLES = ''' import os.path import re -from ansible.module_utils.six import iteritems +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.six import iteritems, string_types # exceptions -------------------------------------------------------------- {{{ @@ -163,7 +164,7 @@ class HomebrewCask(object): - os.path.sep ''' - if isinstance(path, basestring): + if isinstance(path, (string_types)): return not cls.INVALID_PATH_REGEX.search(path) try: @@ -191,7 +192,7 @@ class HomebrewCask(object): return True return ( - isinstance(brew_path, basestring) + isinstance(brew_path, string_types) and not cls.INVALID_BREW_PATH_REGEX.search(brew_path) ) @@ -203,7 +204,7 @@ class HomebrewCask(object): return True return ( - isinstance(cask, basestring) + isinstance(cask, string_types) and not cls.INVALID_CASK_REGEX.search(cask) ) @@ -219,7 +220,7 @@ class HomebrewCask(object): return True else: return ( - isinstance(state, basestring) + isinstance(state, string_types) and state.lower() in ( 'installed', 'absent', @@ -264,7 +265,7 @@ class HomebrewCask(object): raise HomebrewCaskException(self.message) else: - if isinstance(path, basestring): + if isinstance(path, string_types): self._path = path.split(':') else: self._path = path @@ -423,7 +424,7 @@ class HomebrewCask(object): 'update', ]) if rc == 0: - if out and isinstance(out, basestring): + if out and isinstance(out, string_types): already_updated = any( re.search(r'Already up-to-date.', s.strip(), re.IGNORECASE) for s in out.split('\n') @@ -603,8 +604,6 @@ def main(): else: module.exit_json(changed=changed, msg=message) -# this is magic, see lib/ansible/module_common.py -from ansible.module_utils.basic import * if __name__ == '__main__': main() diff --git a/lib/ansible/modules/packaging/os/portinstall.py b/lib/ansible/modules/packaging/os/portinstall.py index 7b14e07c8ac..d03b90a643e 100644 --- a/lib/ansible/modules/packaging/os/portinstall.py +++ b/lib/ansible/modules/packaging/os/portinstall.py @@ -68,11 +68,14 @@ EXAMPLES = ''' state: absent ''' - -import shlex import os +import re import sys +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.six.moves import shlex_quote + + def query_package(module, name): pkg_info_path = module.get_bin_path('pkg_info', False) @@ -81,7 +84,7 @@ def query_package(module, name): if pkg_info_path: pkgng = False pkg_glob_path = module.get_bin_path('pkg_glob', True) - rc, out, err = module.run_command("%s -e `pkg_glob %s`" % (pkg_info_path, pipes.quote(name)), use_unsafe_shell=True) + rc, out, err = module.run_command("%s -e `pkg_glob %s`" % (pkg_info_path, shlex_quote(name)), use_unsafe_shell=True) else: pkgng = True pkg_info_path = module.get_bin_path('pkg', True) @@ -137,11 +140,13 @@ def remove_packages(module, packages): if not query_package(module, package): continue - rc, out, err = module.run_command("%s `%s %s`" % (pkg_delete_path, pkg_glob_path, pipes.quote(package)), use_unsafe_shell=True) + rc, out, err = module.run_command("%s `%s %s`" % (pkg_delete_path, pkg_glob_path, shlex_quote(package)), use_unsafe_shell=True) if query_package(module, package): name_without_digits = re.sub('[0-9]', '', package) - rc, out, err = module.run_command("%s `%s %s`" % (pkg_delete_path, pkg_glob_path, pipes.quote(name_without_digits)),use_unsafe_shell=True) + rc, out, err = module.run_command("%s `%s %s`" % (pkg_delete_path, pkg_glob_path, + shlex_quote(name_without_digits)), + use_unsafe_shell=True) if query_package(module, package): module.fail_json(msg="failed to remove %s: %s" % (package, out)) @@ -211,8 +216,6 @@ def main(): elif p["state"] == "absent": remove_packages(module, pkgs) -# import module snippets -from ansible.module_utils.basic import * if __name__ == '__main__': main() diff --git a/lib/ansible/modules/remote_management/hpilo/hponcfg.py b/lib/ansible/modules/remote_management/hpilo/hponcfg.py index 0f95c04af7b..9a845cbd1bc 100644 --- a/lib/ansible/modules/remote_management/hpilo/hponcfg.py +++ b/lib/ansible/modules/remote_management/hpilo/hponcfg.py @@ -93,7 +93,7 @@ def main(): # options += ' -v' if minfw: - option += ' -m %s' % minfw + options += ' -m %s' % minfw rc, stdout, stderr = module.run_command('hponcfg %s' % options) diff --git a/lib/ansible/modules/remote_management/stacki/stacki_host.py b/lib/ansible/modules/remote_management/stacki/stacki_host.py index 6cb0e46689f..1b74628fab6 100644 --- a/lib/ansible/modules/remote_management/stacki/stacki_host.py +++ b/lib/ansible/modules/remote_management/stacki/stacki_host.py @@ -108,15 +108,17 @@ stdout_lines: sample: [['...', '...'], ['...'], ['...']] ''' +import json import os import re import tempfile -import json +from ansible.module_utils.basic import AnsibleModule from ansible.module_utils.six.moves.urllib.parse import urlencode +from ansible.module_utils.urls import fetch_url, ConnectionError -class StackiHost: +class StackiHost(object): def __init__(self, module): self.module = module @@ -199,7 +201,7 @@ class StackiHost: headers=self.header, method="POST") - def stack_force_install(self): + def stack_force_install(self, result): data = dict() changed = False @@ -215,15 +217,6 @@ class StackiHost: result['changed'] = changed result['stdout'] = "api call successful".rstrip("\r\n") - - def stack_add_interface(self): - - data['cmd'] = "add host interface {0} interface={1} ip={2} network={3} mac={4} default=true"\ - .format(self.hostname, self.prim_intf, self.prim_intf_ip, self.network, self.prim_intf_mac) - res = self.do_request(self.module, self.endpoint, payload=json.dumps(data), - headers=self.header, method="POST") - - def stack_add(self, result): data = dict() @@ -305,9 +298,6 @@ def main(): module.exit_json(**result) -# import module snippets -from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.urls import fetch_url, ConnectionError if __name__ == '__main__': main() diff --git a/lib/ansible/modules/storage/netapp/netapp_e_flashcache.py b/lib/ansible/modules/storage/netapp/netapp_e_flashcache.py index 75a5c485319..8281ad07c13 100644 --- a/lib/ansible/modules/storage/netapp/netapp_e_flashcache.py +++ b/lib/ansible/modules/storage/netapp/netapp_e_flashcache.py @@ -100,13 +100,14 @@ msg: import json import logging import sys +import traceback from ansible.module_utils.api import basic_auth_argument_spec from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.pycompat24 import get_exception -from ansible.module_utils.urls import open_url - +from ansible.module_utils.six.moves import reduce from ansible.module_utils.six.moves.urllib.error import HTTPError +from ansible.module_utils._text import to_native +from ansible.module_utils.urls import open_url def request(url, data=None, headers=None, method='GET', use_proxy=True, @@ -117,8 +118,7 @@ def request(url, data=None, headers=None, method='GET', use_proxy=True, force=force, last_mod_time=last_mod_time, timeout=timeout, validate_certs=validate_certs, url_username=url_username, url_password=url_password, http_agent=http_agent, force_basic_auth=force_basic_auth) - except HTTPError: - err = get_exception() + except HTTPError as err: r = err.fp try: @@ -414,10 +414,11 @@ def main(): sp = NetAppESeriesFlashCache() try: sp.apply() - except Exception: - e = get_exception() - sp.debug("Exception in apply(): \n%s" % str(e)) - sp.module.fail_json(msg="Failed to create flash cache. Error[%s]" % str(e)) + except Exception as e: + sp.debug("Exception in apply(): \n%s" % to_native(e)) + sp.module.fail_json(msg="Failed to create flash cache. Error[%s]" % to_native(e), + exception=traceback.format_exc()) + if __name__ == '__main__': main() diff --git a/lib/ansible/modules/system/alternatives.py b/lib/ansible/modules/system/alternatives.py index 92b4c8b7c81..a9571db063a 100644 --- a/lib/ansible/modules/system/alternatives.py +++ b/lib/ansible/modules/system/alternatives.py @@ -81,8 +81,9 @@ EXAMPLES = ''' ''' import re -from ansible.module_utils.basic import * -from ansible.module_utils.pycompat24 import get_exception +import subprocess + +from ansible.module_utils.basic import AnsibleModule def main(): @@ -161,8 +162,7 @@ def main(): ) module.exit_json(changed=True) - except subprocess.CalledProcessError: - e = get_exception() + except subprocess.CalledProcessError as cpe: module.fail_json(msg=str(dir(cpe))) else: module.exit_json(changed=False) diff --git a/lib/ansible/modules/system/osx_defaults.py b/lib/ansible/modules/system/osx_defaults.py index dfaf7721006..b53e5aadc84 100644 --- a/lib/ansible/modules/system/osx_defaults.py +++ b/lib/ansible/modules/system/osx_defaults.py @@ -120,7 +120,8 @@ import datetime import re from ansible.module_utils.basic import AnsibleModule -from ansible.module_utils.pycompat24 import get_exception +from ansible.module_utils.six import binary_type, text_type + # exceptions --------------------------------------------------------------- {{{ class OSXDefaultsException(Exception): @@ -169,7 +170,7 @@ class OSXDefaults(object): if type == "string": return str(value) elif type in ["bool", "boolean"]: - if isinstance(value, basestring): + if isinstance(value, (binary_type, text_type)): value = value.lower() if value in [True, 1, "true", "1", "yes"]: return True @@ -414,8 +415,7 @@ def main(): array_add=array_add, value=value, state=state, path=path) changed = defaults.run() module.exit_json(changed=changed) - except OSXDefaultsException: - e = get_exception() + except OSXDefaultsException as e: module.fail_json(msg=e.message) # /main ------------------------------------------------------------------- }}} diff --git a/lib/ansible/modules/system/seboolean.py b/lib/ansible/modules/system/seboolean.py index b18d0dc9755..833456e10af 100644 --- a/lib/ansible/modules/system/seboolean.py +++ b/lib/ansible/modules/system/seboolean.py @@ -61,6 +61,8 @@ EXAMPLES = ''' persistent: yes ''' +import os + try: import selinux HAVE_SELINUX=True @@ -73,6 +75,11 @@ try: except ImportError: HAVE_SEMANAGE=False +from ansible.module_utils.basic import AnsibleModule +from ansible.module_utils.six import binary_type +from ansible.module_utils._text import to_bytes + + def has_boolean_value(module, name): bools = [] try: @@ -151,8 +158,7 @@ def semanage_boolean_value(module, name, state): semanage.semanage_disconnect(handle) semanage.semanage_handle_destroy(handle) - except Exception: - e = get_exception() + except Exception as e: module.fail_json(msg="Failed to manage policy for boolean %s: %s" % (name, str(e))) return True @@ -219,17 +225,13 @@ def main(): result['changed'] = r if not r: - module.fail_json(msg="Failed to set boolean %s to %s" % (name, value)) + module.fail_json(msg="Failed to set boolean %s to %s" % (name, state)) try: selinux.security_commit_booleans() except: module.fail_json(msg="Failed to commit pending boolean %s value" % name) module.exit_json(**result) -# import module snippets -from ansible.module_utils.basic import * -from ansible.module_utils._text import to_bytes -from ansible.module_utils.six import binary_type if __name__ == '__main__': main() diff --git a/lib/ansible/modules/utilities/helper/_accelerate.py b/lib/ansible/modules/utilities/helper/_accelerate.py index e1d09bc48c6..54e3406b96a 100644 --- a/lib/ansible/modules/utilities/helper/_accelerate.py +++ b/lib/ansible/modules/utilities/helper/_accelerate.py @@ -197,7 +197,7 @@ def daemonize_self(module, password, port, minutes, pid_file): log('fork #2 failed: %d (%s)' % (e.errno, e.strerror)) sys.exit(1) - dev_null = file('/dev/null','rw') + dev_null = open('/dev/null','rw') os.dup2(dev_null.fileno(), sys.stdin.fileno()) os.dup2(dev_null.fileno(), sys.stdout.fileno()) os.dup2(dev_null.fileno(), sys.stderr.fileno()) @@ -502,7 +502,7 @@ class ThreadedTCPRequestHandler(SocketServer.BaseRequestHandler): return dict(failed=True, msg='internal error: in_path is required') try: - fd = file(data['in_path'], 'rb') + fd = open(data['in_path'], 'rb') fstat = os.stat(data['in_path']) vvv("FETCH file is %d bytes" % fstat.st_size) while fd.tell() < fstat.st_size: diff --git a/lib/ansible/parsing/yaml/objects.py b/lib/ansible/parsing/yaml/objects.py index d7b9c2fd652..bd02090c01d 100644 --- a/lib/ansible/parsing/yaml/objects.py +++ b/lib/ansible/parsing/yaml/objects.py @@ -22,7 +22,7 @@ __metaclass__ = type import yaml from ansible.module_utils.six import text_type -from ansible.module_utils._text import to_bytes +from ansible.module_utils._text import to_bytes, to_text class AnsibleBaseYAMLObject(object): @@ -131,7 +131,7 @@ class AnsibleVaultEncryptedUnicode(yaml.YAMLObject, AnsibleBaseYAMLObject): return str(self.data) def __unicode__(self): - return unicode(self.data) + return to_text(self.data, errors='surrogate_or_strict') def encode(self, encoding=None, errors=None): return self.data.encode(encoding, errors) diff --git a/lib/ansible/playbook/play_context.py b/lib/ansible/playbook/play_context.py index c8f6e55a75c..0d595bef852 100644 --- a/lib/ansible/playbook/play_context.py +++ b/lib/ansible/playbook/play_context.py @@ -319,6 +319,10 @@ class PlayContext(Base): ''' Sets attributes from the task if they are set, which will override those from the play. + + :arg task: the task object with the parameters that were set on it + :arg variables: variables from inventory + :arg templar: templar instance if templating variables is needed ''' new_info = self.copy() @@ -403,9 +407,9 @@ class PlayContext(Base): # become legacy updates -- from commandline if not new_info.become_pass: if new_info.become_method == 'sudo' and new_info.sudo_pass: - setattr(new_info, 'become_pass', new_info.sudo_pass) + new_info.become_pass = new_info.sudo_pass elif new_info.become_method == 'su' and new_info.su_pass: - setattr(new_info, 'become_pass', new_info.su_pass) + new_info.become_pass = new_info.su_pass # become legacy updates -- from inventory file (inventory overrides # commandline) diff --git a/lib/ansible/plugins/callback/logentries.py b/lib/ansible/plugins/callback/logentries.py index 8264453a4d2..8d013ced0b1 100644 --- a/lib/ansible/plugins/callback/logentries.py +++ b/lib/ansible/plugins/callback/logentries.py @@ -75,17 +75,10 @@ except ImportError: HAS_FLATDICT = False from ansible.module_utils.six.moves import configparser +from ansible.module_utils._text import to_bytes, to_text from ansible.plugins.callback import CallbackBase -def is_unicode(ch): - return isinstance(ch, unicode) - - -def create_unicode(ch): - return unicode(ch, 'utf-8') - - class PlainTextSocketAppender(object): def __init__(self, verbose=True, @@ -141,15 +134,13 @@ class PlainTextSocketAppender(object): def put(self, data): # Replace newlines with Unicode line separator # for multi-line events - if not is_unicode(data): - multiline = create_unicode(data).replace('\n', self.LINE_SEP) - else: - multiline = data.replace('\n', self.LINE_SEP) - multiline += "\n" + data = to_text(data, errors='surrogate_or_strict') + multiline = data.replace(u'\n', self.LINE_SEP) + multiline += u"\n" # Send data, reconnect if needed while True: try: - self._conn.send(multiline.encode('utf-8')) + self._conn.send(to_bytes(multiline, errors='surrogate_or_strict')) except socket.error: self.reopen_connection() continue diff --git a/lib/ansible/plugins/connection/accelerate.py b/lib/ansible/plugins/connection/accelerate.py index fd53649c450..e38365dfd11 100644 --- a/lib/ansible/plugins/connection/accelerate.py +++ b/lib/ansible/plugins/connection/accelerate.py @@ -227,7 +227,7 @@ class Connection(ConnectionBase): if not os.path.exists(in_path): raise AnsibleFileNotFound("file or module does not exist: %s" % in_path) - fd = file(in_path, 'rb') + fd = open(in_path, 'rb') fstat = os.stat(in_path) try: display.vvv("PUT file is %d bytes" % fstat.st_size, host=self._play_context.remote_addr) diff --git a/lib/ansible/plugins/lookup/shelvefile.py b/lib/ansible/plugins/lookup/shelvefile.py index a210d1e3fea..383d55dd31c 100644 --- a/lib/ansible/plugins/lookup/shelvefile.py +++ b/lib/ansible/plugins/lookup/shelvefile.py @@ -64,11 +64,11 @@ class LookupModule(LookupBase): if shelvefile: res = self.read_shelve(shelvefile, key) if res is None: - raise AnsibleError("Key %s not found in shelve file %s" % (key, file)) + raise AnsibleError("Key %s not found in shelve file %s" % (key, shelvefile)) # Convert the value read to string ret.append(to_text(res)) break else: - raise AnsibleError("Could not locate shelve file in lookup: %s" % file) + raise AnsibleError("Could not locate shelve file in lookup: %s" % paramvals['file']) return ret diff --git a/lib/ansible/plugins/strategy/debug.py b/lib/ansible/plugins/strategy/debug.py index 1a9f906740c..0b5a1ccc4e0 100644 --- a/lib/ansible/plugins/strategy/debug.py +++ b/lib/ansible/plugins/strategy/debug.py @@ -177,6 +177,5 @@ class Debugger(cmd.Cmd): def default(self, line): try: self.execute(line) - display.display(pprint.pformat(result)) except: pass diff --git a/lib/ansible/utils/unsafe_proxy.py b/lib/ansible/utils/unsafe_proxy.py index 6f01660cee0..5c379032fb9 100644 --- a/lib/ansible/utils/unsafe_proxy.py +++ b/lib/ansible/utils/unsafe_proxy.py @@ -85,7 +85,8 @@ class UnsafeProxy(object): class AnsibleJSONUnsafeEncoder(json.JSONEncoder): def encode(self, obj): if isinstance(obj, AnsibleUnsafe): - return super(AnsibleJSONUnsafeEncoder, self).encode(dict(__ansible_unsafe=True, value=unicode(obj))) + return super(AnsibleJSONUnsafeEncoder, self).encode(dict(__ansible_unsafe=True, + value=to_text(obj, errors='surrogate_or_strict', nonstring='strict'))) else: return super(AnsibleJSONUnsafeEncoder, self).encode(obj) diff --git a/test/integration/cleanup_ec2.py b/test/integration/cleanup_ec2.py index 755ae09bb8b..734fd15f001 100644 --- a/test/integration/cleanup_ec2.py +++ b/test/integration/cleanup_ec2.py @@ -14,6 +14,8 @@ import sys import time import yaml +from ansible.module_utils.six.moves import input + def delete_aws_resources(get_func, attr, opts): for item in get_func(): @@ -29,7 +31,7 @@ def delete_autoscaling_group(get_func, attr, opts): group_name = getattr(item, attr) if re.search(opts.match_re, group_name): if not opts.assumeyes: - assumeyes = raw_input("Delete matching %s? [y/n]: " % (item).lower()) == 'y' + assumeyes = input("Delete matching %s? [y/n]: " % (item).lower()) == 'y' break if assumeyes and group_name: groups = asg.get_all_groups(names=[group_name]) @@ -77,7 +79,7 @@ def delete_aws_instances(reservation, opts): def prompt_and_delete(item, prompt, assumeyes): if not assumeyes: - assumeyes = raw_input(prompt).lower() == 'y' + assumeyes = input(prompt).lower() == 'y' assert hasattr(item, 'delete') or hasattr(item, 'terminate'), "Class <%s> has no delete or terminate attribute" % item.__class__ if assumeyes: if hasattr(item, 'delete'): diff --git a/test/integration/cleanup_gce.py b/test/integration/cleanup_gce.py index 76728374b6b..bb6f4e879ce 100644 --- a/test/integration/cleanup_gce.py +++ b/test/integration/cleanup_gce.py @@ -27,6 +27,8 @@ except ImportError: import gce_credentials +from ansible.module_utils.six.moves import input + def delete_gce_resources(get_func, attr, opts): for item in get_func(): @@ -37,7 +39,7 @@ def delete_gce_resources(get_func, attr, opts): def prompt_and_delete(item, prompt, assumeyes): if not assumeyes: - assumeyes = raw_input(prompt).lower() == 'y' + assumeyes = input(prompt).lower() == 'y' assert hasattr(item, 'destroy'), "Class <%s> has no delete attribute" % item.__class__ if assumeyes: item.destroy() diff --git a/test/integration/cleanup_rax.py b/test/integration/cleanup_rax.py index a2b3893204a..1d7b1309a7e 100755 --- a/test/integration/cleanup_rax.py +++ b/test/integration/cleanup_rax.py @@ -11,6 +11,8 @@ try: except ImportError: HAS_PYRAX = False +from ansible.module_utils.six.moves import input + def rax_list_iterator(svc, *args, **kwargs): method = kwargs.pop('method', 'list') @@ -53,7 +55,7 @@ def authenticate(): def prompt_and_delete(item, prompt, assumeyes): if not assumeyes: - assumeyes = raw_input(prompt).lower() == 'y' + assumeyes = input(prompt).lower() == 'y' assert hasattr(item, 'delete') or hasattr(item, 'terminate'), \ "Class <%s> has no delete or terminate attribute" % item.__class__ if assumeyes: diff --git a/test/integration/targets/module_utils/library/test.py b/test/integration/targets/module_utils/library/test.py index 4b09bed5e32..fbb7e6e224f 100644 --- a/test/integration/targets/module_utils/library/test.py +++ b/test/integration/targets/module_utils/library/test.py @@ -1,5 +1,7 @@ #!/usr/bin/python - +# Most of these names are only available via PluginLoader so pylint doesn't +# know they exist +# pylint: disable=no-name-in-module results = {} # Test import with no from diff --git a/test/sanity/code-smell/ansible-var-precedence-check.py b/test/sanity/code-smell/ansible-var-precedence-check.py index 6c06ef19016..375d87dfc5b 100755 --- a/test/sanity/code-smell/ansible-var-precedence-check.py +++ b/test/sanity/code-smell/ansible-var-precedence-check.py @@ -509,7 +509,7 @@ def main(): try: print("CHECKING: %s (%s)" % (features[0], fdesc.get(features[0], ''))) - VTM.run() + res = VTM.run() if options.show_stdout: VTM.show_stdout() diff --git a/test/sanity/pep8/legacy-files.txt b/test/sanity/pep8/legacy-files.txt index 1eec2da252c..83e3e4a6336 100644 --- a/test/sanity/pep8/legacy-files.txt +++ b/test/sanity/pep8/legacy-files.txt @@ -1,4 +1,3 @@ -hacking/conf2yaml.py lib/ansible/cli/config.py lib/ansible/config/data.py lib/ansible/config/manager.py @@ -172,7 +171,6 @@ lib/ansible/modules/cloud/rackspace/rax_dns_record.py lib/ansible/modules/cloud/rackspace/rax_facts.py lib/ansible/modules/cloud/rackspace/rax_files.py lib/ansible/modules/cloud/rackspace/rax_keypair.py -lib/ansible/modules/cloud/rackspace/rax_meta.py lib/ansible/modules/cloud/rackspace/rax_mon_alarm.py lib/ansible/modules/cloud/rackspace/rax_mon_check.py lib/ansible/modules/cloud/rackspace/rax_mon_entity.py @@ -396,7 +394,6 @@ lib/ansible/modules/network/panos/panos_interface.py lib/ansible/modules/network/panos/panos_loadcfg.py lib/ansible/modules/network/panos/panos_mgtconfig.py lib/ansible/modules/network/panos/panos_pg.py -lib/ansible/modules/network/panos/panos_restart.py lib/ansible/modules/network/panos/panos_service.py lib/ansible/modules/net_tools/snmp_facts.py lib/ansible/modules/network/sros/sros_command.py diff --git a/test/units/playbook/test_play_context.py b/test/units/playbook/test_play_context.py index 56cab943e1b..47b69582317 100644 --- a/test/units/playbook/test_play_context.py +++ b/test/units/playbook/test_play_context.py @@ -1,19 +1,7 @@ # (c) 2012-2014, Michael DeHaan +# (c) 2017 Ansible Project # -# This file is part of Ansible -# -# Ansible is free software: you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Ansible is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with Ansible. If not, see . +# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) # Make coding more python3-ish from __future__ import (absolute_import, division, print_function) @@ -21,10 +9,11 @@ __metaclass__ = type import os +import pytest + from ansible import constants as C from ansible.cli import CLI from ansible.compat.tests import unittest -from ansible.compat.tests.mock import patch, MagicMock from ansible.errors import AnsibleError, AnsibleParserError from ansible.module_utils.six.moves import shlex_quote from ansible.playbook.play_context import PlayContext @@ -32,336 +21,157 @@ from ansible.playbook.play_context import PlayContext from units.mock.loader import DictDataLoader -class TestPlayContext(unittest.TestCase): - - def setUp(self): - self._parser = CLI.base_parser( - runas_opts=True, - meta_opts=True, - runtask_opts=True, - vault_opts=True, - async_opts=True, - connect_opts=True, - subset_opts=True, - check_opts=True, - inventory_opts=True, - ) - - def tearDown(self): - pass - - def test_play_context(self): - (options, args) = self._parser.parse_args(['-vv', '--check']) - play_context = PlayContext(options=options) - self.assertEqual(play_context._attributes['connection'], C.DEFAULT_TRANSPORT) - self.assertEqual(play_context.remote_addr, None) - self.assertEqual(play_context.remote_user, None) - self.assertEqual(play_context.password, '') - self.assertEqual(play_context.port, None) - self.assertEqual(play_context.private_key_file, C.DEFAULT_PRIVATE_KEY_FILE) - self.assertEqual(play_context.timeout, C.DEFAULT_TIMEOUT) - self.assertEqual(play_context.shell, None) - self.assertEqual(play_context.verbosity, 2) - self.assertEqual(play_context.check_mode, True) - self.assertEqual(play_context.no_log, None) - - mock_play = MagicMock() - mock_play.connection = 'mock' - mock_play.remote_user = 'mock' - mock_play.port = 1234 - mock_play.become = True - mock_play.become_method = 'mock' - mock_play.become_user = 'mockroot' - mock_play.no_log = True - - play_context = PlayContext(play=mock_play, options=options) - self.assertEqual(play_context.connection, 'mock') - self.assertEqual(play_context.remote_user, 'mock') - self.assertEqual(play_context.password, '') - self.assertEqual(play_context.port, 1234) - self.assertEqual(play_context.become, True) - self.assertEqual(play_context.become_method, "mock") - self.assertEqual(play_context.become_user, "mockroot") - - mock_task = MagicMock() - mock_task.connection = 'mocktask' - mock_task.remote_user = 'mocktask' - mock_task.no_log = mock_play.no_log - mock_task.become = True - mock_task.become_method = 'mocktask' - mock_task.become_user = 'mocktaskroot' - mock_task.become_pass = 'mocktaskpass' - mock_task._local_action = False - mock_task.delegate_to = None - - all_vars = dict( - ansible_connection='mock_inventory', - ansible_ssh_port=4321, - ) - - mock_templar = MagicMock() - - play_context = PlayContext(play=mock_play, options=options) - play_context = play_context.set_task_and_variable_override(task=mock_task, variables=all_vars, templar=mock_templar) - self.assertEqual(play_context.connection, 'mock_inventory') - self.assertEqual(play_context.remote_user, 'mocktask') - self.assertEqual(play_context.port, 4321) - self.assertEqual(play_context.no_log, True) - self.assertEqual(play_context.become, True) - self.assertEqual(play_context.become_method, "mocktask") - self.assertEqual(play_context.become_user, "mocktaskroot") - self.assertEqual(play_context.become_pass, "mocktaskpass") - - mock_task.no_log = False - play_context = play_context.set_task_and_variable_override(task=mock_task, variables=all_vars, templar=mock_templar) - self.assertEqual(play_context.no_log, False) - - def test_play_context_make_become_cmd(self): - (options, args) = self._parser.parse_args([]) - play_context = PlayContext(options=options) - - default_cmd = "/bin/foo" - default_exe = "/bin/bash" - sudo_exe = C.DEFAULT_SUDO_EXE or 'sudo' - sudo_flags = C.DEFAULT_SUDO_FLAGS - su_exe = C.DEFAULT_SU_EXE or 'su' - su_flags = C.DEFAULT_SU_FLAGS or '' - pbrun_exe = 'pbrun' - pbrun_flags = '' - pfexec_exe = 'pfexec' - pfexec_flags = '' - doas_exe = 'doas' - doas_flags = ' -n -u foo ' - ksu_exe = 'ksu' - ksu_flags = '' - dzdo_exe = 'dzdo' - - cmd = play_context.make_become_cmd(cmd=default_cmd, executable=default_exe) - self.assertEqual(cmd, default_cmd) - - play_context.become = True - play_context.become_user = 'foo' - - play_context.become_method = 'sudo' - cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") - self.assertEqual( - cmd, - """%s %s -u %s %s -c 'echo %s; %s'""" % (sudo_exe, sudo_flags, play_context.become_user, default_exe, play_context.success_key, default_cmd) - ) - play_context.become_pass = 'testpass' - cmd = play_context.make_become_cmd(cmd=default_cmd, executable=default_exe) - self.assertEqual( - cmd, - """%s %s -p "%s" -u %s %s -c 'echo %s; %s'""" % (sudo_exe, sudo_flags.replace('-n', ''), play_context.prompt, play_context.become_user, default_exe, - play_context.success_key, default_cmd) - ) - - play_context.become_pass = None - - play_context.become_method = 'su' - cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") - self.assertEqual( - cmd, - """%s %s -c '%s -c '"'"'echo %s; %s'"'"''""" % (su_exe, play_context.become_user, default_exe, play_context.success_key, default_cmd) - ) - - play_context.become_method = 'pbrun' - cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") - self.assertEqual(cmd, """%s %s -u %s 'echo %s; %s'""" % (pbrun_exe, pbrun_flags, play_context.become_user, play_context.success_key, default_cmd)) - - play_context.become_method = 'pfexec' - cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") - self.assertEqual(cmd, '''%s %s "'echo %s; %s'"''' % (pfexec_exe, pfexec_flags, play_context.success_key, default_cmd)) - - play_context.become_method = 'doas' - cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") - self.assertEqual( - cmd, - """%s %s echo %s && %s %s env ANSIBLE=true %s""" % (doas_exe, doas_flags, play_context.success_key, doas_exe, doas_flags, default_cmd) - ) - - play_context.become_method = 'ksu' - cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") - self.assertEqual( - cmd, - """%s %s %s -e %s -c 'echo %s; %s'""" % (ksu_exe, play_context.become_user, ksu_flags, default_exe, play_context.success_key, default_cmd) - ) - - play_context.become_method = 'bad' - self.assertRaises(AnsibleError, play_context.make_become_cmd, cmd=default_cmd, executable="/bin/bash") - - play_context.become_method = 'dzdo' - cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") - self.assertEqual(cmd, """%s -u %s %s -c 'echo %s; %s'""" % (dzdo_exe, play_context.become_user, default_exe, play_context.success_key, default_cmd)) - - play_context.become_pass = 'testpass' - play_context.become_method = 'dzdo' - cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") - self.assertEqual( - cmd, - """%s -p %s -u %s %s -c 'echo %s; %s'""" % (dzdo_exe, shlex_quote(play_context.prompt), play_context.become_user, default_exe, - play_context.success_key, default_cmd) - ) +@pytest.fixture +def parser(): + parser = CLI.base_parser(runas_opts=True, meta_opts=True, + runtask_opts=True, vault_opts=True, + async_opts=True, connect_opts=True, + subset_opts=True, check_opts=True, + inventory_opts=True,) + return parser -class TestTaskAndVariableOverrride(unittest.TestCase): +def test_play_context(mocker, parser): + (options, args) = parser.parse_args(['-vv', '--check']) + play_context = PlayContext(options=options) - inventory_vars = ( - ( - 'preferred_names', - dict( - ansible_connection='local', - ansible_user='ansibull', - ansible_become_user='ansibull', - ansible_become_method='su', - ansible_become_pass='ansibullwuzhere', - ), - dict( - connection='local', - remote_user='ansibull', - become_user='ansibull', - become_method='su', - become_pass='ansibullwuzhere', - ) - ), - ( - 'alternate_names', - dict(ansible_become_password='ansibullwuzhere',), - dict(become_pass='ansibullwuzhere',) - ), - ( - 'deprecated_names', - dict( - ansible_ssh_user='ansibull', - ansible_sudo_user='ansibull', - ansible_sudo_pass='ansibullwuzhere', - ), - dict( - remote_user='ansibull', - become_method='sudo', - become_user='ansibull', - become_pass='ansibullwuzhere', - ) - ), - ( - 'deprecated_names2', - dict( - ansible_ssh_user='ansibull', - ansible_su_user='ansibull', - ansible_su_pass='ansibullwuzhere', - ), - dict( - remote_user='ansibull', - become_method='su', - become_user='ansibull', - become_pass='ansibullwuzhere', - ) - ), - ( - 'deprecated_alt_names', - dict(ansible_sudo_password='ansibullwuzhere',), - dict( - become_method='sudo', - become_pass='ansibullwuzhere', - ) - ), - ( - 'deprecated_alt_names2', - dict(ansible_su_password='ansibullwuzhere',), - dict( - become_method='su', - become_pass='ansibullwuzhere', - ) - ), - ( - 'deprecated_and_preferred_names', - dict( - ansible_user='ansibull', - ansible_ssh_user='badbull', - ansible_become_user='ansibull', - ansible_sudo_user='badbull', - ansible_become_method='su', - ansible_become_pass='ansibullwuzhere', - ansible_sudo_pass='badbull', - ), - dict( - connection='local', - remote_user='ansibull', - become_user='ansibull', - become_method='su', - become_pass='ansibullwuzhere', - ) - ), + assert play_context._attributes['connection'] == C.DEFAULT_TRANSPORT + assert play_context.remote_addr is None + assert play_context.remote_user is None + assert play_context.password == '' + assert play_context.port is None + assert play_context.private_key_file == C.DEFAULT_PRIVATE_KEY_FILE + assert play_context.timeout == C.DEFAULT_TIMEOUT + assert play_context.shell is None + assert play_context.verbosity == 2 + assert play_context.check_mode is True + assert play_context.no_log is None + + mock_play = mocker.MagicMock() + mock_play.connection = 'mock' + mock_play.remote_user = 'mock' + mock_play.port = 1234 + mock_play.become = True + mock_play.become_method = 'mock' + mock_play.become_user = 'mockroot' + mock_play.no_log = True + + play_context = PlayContext(play=mock_play, options=options) + assert play_context.connection == 'mock' + assert play_context.remote_user == 'mock' + assert play_context.password == '' + assert play_context.port == 1234 + assert play_context.become is True + assert play_context.become_method == "mock" + assert play_context.become_user == "mockroot" + + mock_task = mocker.MagicMock() + mock_task.connection = 'mocktask' + mock_task.remote_user = 'mocktask' + mock_task.no_log = mock_play.no_log + mock_task.become = True + mock_task.become_method = 'mocktask' + mock_task.become_user = 'mocktaskroot' + mock_task.become_pass = 'mocktaskpass' + mock_task._local_action = False + mock_task.delegate_to = None + + all_vars = dict( + ansible_connection='mock_inventory', + ansible_ssh_port=4321, ) - def setUp(self): - parser = CLI.base_parser( - runas_opts=True, - meta_opts=True, - runtask_opts=True, - vault_opts=True, - async_opts=True, - connect_opts=True, - subset_opts=True, - check_opts=True, - inventory_opts=True, - ) + mock_templar = mocker.MagicMock() - (options, args) = parser.parse_args(['-vv', '--check']) + play_context = PlayContext(play=mock_play, options=options) + play_context = play_context.set_task_and_variable_override(task=mock_task, variables=all_vars, templar=mock_templar) - mock_play = MagicMock() - mock_play.connection = 'mock' - mock_play.remote_user = 'mock' - mock_play.port = 1234 - mock_play.become = True - mock_play.become_method = 'mock' - mock_play.become_user = 'mockroot' - mock_play.no_log = True + assert play_context.connection == 'mock_inventory' + assert play_context.remote_user == 'mocktask' + assert play_context.port == 4321 + assert play_context.no_log is True + assert play_context.become is True + assert play_context.become_method == "mocktask" + assert play_context.become_user == "mocktaskroot" + assert play_context.become_pass == "mocktaskpass" - self.play_context = PlayContext(play=mock_play, options=options) + mock_task.no_log = False + play_context = play_context.set_task_and_variable_override(task=mock_task, variables=all_vars, templar=mock_templar) + assert play_context.no_log is False - mock_task = MagicMock() - mock_task.connection = mock_play.connection - mock_task.remote_user = mock_play.remote_user - mock_task.no_log = mock_play.no_log - mock_task.become = mock_play.become - mock_task.become_method = mock_play.becom_method - mock_task.become_user = mock_play.become_user - mock_task.become_pass = 'mocktaskpass' - mock_task._local_action = False - mock_task.delegate_to = None - self.mock_task = mock_task +def test_play_context_make_become_cmd(parser): + (options, args) = parser.parse_args([]) + play_context = PlayContext(options=options) - self.mock_templar = MagicMock() + default_cmd = "/bin/foo" + default_exe = "/bin/bash" + sudo_exe = C.DEFAULT_SUDO_EXE or 'sudo' + sudo_flags = C.DEFAULT_SUDO_FLAGS + su_exe = C.DEFAULT_SU_EXE or 'su' + su_flags = C.DEFAULT_SU_FLAGS or '' + pbrun_exe = 'pbrun' + pbrun_flags = '' + pfexec_exe = 'pfexec' + pfexec_flags = '' + doas_exe = 'doas' + doas_flags = ' -n -u foo ' + ksu_exe = 'ksu' + ksu_flags = '' + dzdo_exe = 'dzdo' - def tearDown(self): - pass + cmd = play_context.make_become_cmd(cmd=default_cmd, executable=default_exe) + assert cmd == default_cmd - def _check_vars_overridden(self): - self.assertEqual(play_context.connection, 'mock_inventory') - self.assertEqual(play_context.remote_user, 'mocktask') - self.assertEqual(play_context.port, 4321) - self.assertEqual(play_context.no_log, True) - self.assertEqual(play_context.become, True) - self.assertEqual(play_context.become_method, "mocktask") - self.assertEqual(play_context.become_user, "mocktaskroot") - self.assertEqual(play_context.become_pass, "mocktaskpass") + play_context.become = True + play_context.become_user = 'foo' - mock_task.no_log = False - play_context = play_context.set_task_and_variable_override(task=mock_task, variables=all_vars, templar=mock_templar) - self.assertEqual(play_context.no_log, False) + play_context.become_method = 'sudo' + cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") + assert (cmd == """%s %s -u %s %s -c 'echo %s; %s'""" % (sudo_exe, sudo_flags, play_context.become_user, + default_exe, play_context.success_key, default_cmd)) - def test_override_magic_variables(self): - play_context = play_context.set_task_and_variable_override(task=self.mock_task, variables=all_vars, templar=self.mock_templar) + play_context.become_pass = 'testpass' + cmd = play_context.make_become_cmd(cmd=default_cmd, executable=default_exe) + assert (cmd == """%s %s -p "%s" -u %s %s -c 'echo %s; %s'""" % (sudo_exe, sudo_flags.replace('-n', ''), + play_context.prompt, play_context.become_user, default_exe, + play_context.success_key, default_cmd)) - mock_play.connection = 'mock' - mock_play.remote_user = 'mock' - mock_play.port = 1234 - mock_play.become_method = 'mock' - mock_play.become_user = 'mockroot' - mock_task.become_pass = 'mocktaskpass' - # Inventory vars override things set from cli vars (--become, -user, - # etc... [notably, not --extravars]) - for test_name, all_vars, expected in self.inventory_vars: - yield self._check_vars_overriden, test_name, all_vars, expected + play_context.become_pass = None + play_context.become_method = 'su' + cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") + assert (cmd == """%s %s -c '%s -c '"'"'echo %s; %s'"'"''""" % (su_exe, play_context.become_user, default_exe, + play_context.success_key, default_cmd)) + + play_context.become_method = 'pbrun' + cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") + assert cmd == """%s %s -u %s 'echo %s; %s'""" % (pbrun_exe, pbrun_flags, play_context.become_user, play_context.success_key, default_cmd) + + play_context.become_method = 'pfexec' + cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") + assert cmd == '''%s %s "'echo %s; %s'"''' % (pfexec_exe, pfexec_flags, play_context.success_key, default_cmd) + + play_context.become_method = 'doas' + cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") + assert (cmd == """%s %s echo %s && %s %s env ANSIBLE=true %s""" % (doas_exe, doas_flags, play_context. + success_key, doas_exe, doas_flags, default_cmd)) + + play_context.become_method = 'ksu' + cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") + assert (cmd == """%s %s %s -e %s -c 'echo %s; %s'""" % (ksu_exe, play_context.become_user, ksu_flags, + default_exe, play_context.success_key, default_cmd)) + + play_context.become_method = 'bad' + with pytest.raises(AnsibleError): + play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") + + play_context.become_method = 'dzdo' + cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") + assert cmd == """%s -u %s %s -c 'echo %s; %s'""" % (dzdo_exe, play_context.become_user, default_exe, play_context.success_key, default_cmd) + + play_context.become_pass = 'testpass' + play_context.become_method = 'dzdo' + cmd = play_context.make_become_cmd(cmd=default_cmd, executable="/bin/bash") + assert (cmd == """%s -p %s -u %s %s -c 'echo %s; %s'""" % (dzdo_exe, shlex_quote(play_context.prompt), + play_context.become_user, default_exe, + play_context.success_key, default_cmd))