summaryrefslogtreecommitdiff
path: root/lib/ansible/modules/web_infrastructure/ansible_tower/tower_send.py
blob: d8011806fe951fd3dde926b38f961c90f176ad01 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
#!/usr/bin/python
# coding: utf-8 -*-

# (c) 2017, John Westcott IV <john.westcott.iv@redhat.com>
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

from __future__ import absolute_import, division, print_function
__metaclass__ = type


ANSIBLE_METADATA = {'metadata_version': '1.1',
                    'status': ['preview'],
                    'supported_by': 'community'}


DOCUMENTATION = '''
---
module: tower_send
author: "John Westcott IV (@john-westcott-iv)"
version_added: "2.8"
short_description: Send assets to Ansible Tower.
description:
    - Send assets to Ansible Tower. See
      U(https://www.ansible.com/tower) for an overview.
options:
    assets:
      description:
        - The assets to import.
        - This can be the output of tower_receive or loaded from a file
      required: False
    files:
      description:
        - List of files to import.
      required: False
      default: []
    prevent:
      description:
        - A list of asset types to prevent import for
      required: false
      default: []
    password_management:
      description:
        - The password management option to use.
        - The prompt option is not supported.
      required: false
      default: 'default'
      choices: ["default", "random"]

notes:
  - One of assets or files needs to be passed in

requirements:
  - "ansible-tower-cli >= 3.3.0"
  - six.moves.StringIO
  - sys

extends_documentation_fragment: tower
'''

EXAMPLES = '''
- name: Import all tower assets
  tower_send:
    assets: "{{ export_output.assets }}"
    tower_config_file: "~/tower_cli.cfg"
'''

RETURN = '''
output:
    description: The import messages
    returned: success, fail
    type: list
    sample: [ 'Message 1', 'Message 2' ]
'''

import os
import sys

from ansible.module_utils.six.moves import StringIO
from ansible.module_utils.ansible_tower import TowerModule, tower_auth_config, HAS_TOWER_CLI

from tempfile import mkstemp

try:
    from tower_cli.cli.transfer.send import Sender
    from tower_cli.utils.exceptions import TowerCLIError

    from tower_cli.conf import settings
    TOWER_CLI_HAS_EXPORT = True
except ImportError:
    TOWER_CLI_HAS_EXPORT = False


def main():
    argument_spec = dict(
        assets=dict(required=False),
        files=dict(required=False, default=[], type='list'),
        prevent=dict(required=False, default=[], type='list'),
        password_management=dict(required=False, default='default', choices=['default', 'random']),
    )

    module = TowerModule(argument_spec=argument_spec, supports_check_mode=False)

    if not HAS_TOWER_CLI:
        module.fail_json(msg='ansible-tower-cli required for this module')

    if not TOWER_CLI_HAS_EXPORT:
        module.fail_json(msg='ansible-tower-cli version does not support export')

    assets = module.params.get('assets')
    prevent = module.params.get('prevent')
    password_management = module.params.get('password_management')
    files = module.params.get('files')

    result = dict(
        changed=False,
        msg='',
        output='',
    )

    if not assets and not files:
        result['msg'] = "Assets or files must be specified"
        module.fail_json(**result)

    path = None
    if assets:
        # We got assets so we need to dump this out to a temp file and append that to files
        handle, path = mkstemp(prefix='', suffix='', dir='')
        with open(path, 'w') as f:
            f.write(assets)
        files.append(path)

    tower_auth = tower_auth_config(module)
    failed = False
    with settings.runtime_values(**tower_auth):
        try:
            sender = Sender(no_color=False)
            old_stdout = sys.stdout
            sys.stdout = captured_stdout = StringIO()
            try:
                sender.send(files, prevent, password_management)
            except TypeError as e:
                # Newer versions of TowerCLI require 4 parameters
                sender.send(files, prevent, [], password_management)

            if sender.error_messages > 0:
                failed = True
                result['msg'] = "Transfer Failed with %d errors" % sender.error_messages
            if sender.changed_messages > 0:
                result['changed'] = True
        except TowerCLIError as e:
            result['msg'] = e.message
            failed = True
        finally:
            if path is not None:
                os.remove(path)
            result['output'] = captured_stdout.getvalue().split("\n")
            sys.stdout = old_stdout

    # Return stdout so that module returns will work
    if failed:
        module.fail_json(**result)
    else:
        module.exit_json(**result)


if __name__ == '__main__':
    main()