summaryrefslogtreecommitdiff
path: root/lib/ansible/modules/cloud/helm.py
blob: e12d0bc1e8b6bbc0248a78d3273576d83671f543 (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
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
#!/usr/bin/python
# (c) 2016, Flavio Percoco <flavio@redhat.com>
#
# This module 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.
#
# This software 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 this software.  If not, see <http://www.gnu.org/licenses/>.

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

DOCUMENTATION = '''
---
module: helm
short_description: Manages Kubernetes packages with the Helm package manager
version_added: "2.4"
author: "Flavio Percoco (flaper87)"
description:
   - Install, upgrade, delete and list packages with the Helm package manage
requirements:
  - "pyhelm"
  - "grpcio"
options:
  host:
    description:
      - Tiller's server host
    required: false
    default: "localhost"
  port:
    description:
      - Tiller's server port
    required: false
    default: 44134
  namespace:
    description:
      - Kubernetes namespace where the chart should be installed
    required: false
    default: "default"
  name:
    description:
      - Release name to manage
    required: false
    default: null
  state:
    description:
      - Whether to install C(present), remove C(absent), or purge C(purged) a package.
    required: false
    choices: ['absent', 'purged', 'present']
    default: "installed"
  chart:
    description: |
      A map describing the chart to install. For example:
      chart:
        name: memcached
        version: 0.4.0
        source:
          type: repo
          location: https://kubernetes-charts.storage.googleapis.com
    required: false
    default: {}
  values:
    description:
      - A map of value options for the chart.
    required: false
    default: {}
  disable_hooks:
    description:
      - Whether to disable hooks during the uninstall process
    required: false
    default: false
'''

RETURN = ''' # '''

EXAMPLES = '''
- name: Install helm chart
  helm:
    host: localhost
    chart:
      name: memcached
      version: 0.4.0
      source:
        type: repo
        location: https://kubernetes-charts.storage.googleapis.com
    state: installed
    name: my-memcached
    namespace: default

- name: Uninstall helm chart
  helm:
    host: localhost
    state: absent
    name: my-memcached
'''


import os

try:
    import grpc
    from pyhelm import tiller
    from pyhelm import chartbuilder
    HAS_PYHELM = True
except ImportError as exc:
    HAS_PYHELM = False


from ansible.module_utils.basic import AnsibleModule


def install(module, tserver):
    changed = False
    params = module.params
    name = params['name']
    values = params['values']
    chart = module.params['chart']
    namespace = module.params['namespace']

    chartb = chartbuilder.ChartBuilder(chart)
    try:
        result = tserver.install_release(chartb.get_helm_chart(), namespace,
                                         dry_run=False, name=name,
                                         values=values)
        changed = True
    except grpc._channel._Rendezvous as exc:
        if "already exists" not in str(exc):
            raise exc

    return dict(changed=changed)


def delete(module, tserver, purge=False):
    changed = False
    params = module.params

    if not module.params['name']:
        module.fail_json(msg='Missing required field name')

    name = module.params['name']
    disable_hooks = params['disable_hooks']

    try:
        result = tserver.uninstall_release(name, disable_hooks, purge)
        changed = True
    except grpc._channel._Rendezvous as exc:
        if 'not found' not in str(exc):
            raise exc

    return dict(changed=changed)


def main():
    """The main function."""
    module = AnsibleModule(
        argument_spec=dict(
            host=dict(type='str', default='localhost'),
            port=dict(type='int', default=44134),
            name=dict(type='str', default=''),
            chart=dict(type='dict'),
            state=dict(
                choices=['absent', 'purged', 'present'],
                default='present'
            ),
            # Install options
            values=dict(type='dict'),
            namespace=dict(type='str', default='default'),

            # Uninstall options
            disable_hooks=dict(type='bool', default=False),
        ),
        supports_check_mode=True)

    if not HAS_PYHELM:
        module.fail_json(msg="Could not import the pyhelm python module. "
                         "Please install `pyhelm` package.")

    host = module.params['host']
    port = module.params['port']
    state = module.params['state']
    tserver = tiller.Tiller(host, port)

    if state == 'present':
        rst = install(module, tserver)

    if state in 'absent':
        rst = delete(module, tserver)

    if state in 'purged':
        rst = delete(module, tserver, True)

    module.exit_json(**rst)


if __name__ == '__main__':
    main()