blob: 4ee8cf5aa477800c40b0aa9cbeaa7a3055155f5d [file] [log] [blame]
kairat_kushaev66852622018-06-07 17:27:35 +04001# Import Python libs
2from __future__ import absolute_import, print_function, unicode_literals
3import logging
4import time
5
6LOG = logging.getLogger(__name__)
7
8
9def __virtual__():
10 return 'heatv1'
11
12
13def _heat_call(fname, *args, **kwargs):
14 return __salt__['heatv1.{}'.format(fname)](*args, **kwargs)
15
16
17def _poll_for_complete(stack_name, cloud_name=None, action=None,
18 poll_period=5, timeout=60):
19 if action:
20 stop_status = ('{0}_FAILED'.format(action), '{0}_COMPLETE'.format(action))
21 stop_check = lambda a: a in stop_status
22 else:
23 stop_check = lambda a: a.endswith('_COMPLETE') or a.endswith('_FAILED')
24 timeout_sec = timeout * 60
25 msg_template = '\n Stack %(name)s %(status)s \n'
26 while True:
27 stack = _heat_call('stack_show',
28 name=stack_name,
29 cloud_name=cloud_name)
30 if not stack["result"]:
31 raise Exception("request for stack failed")
32
33 stack = stack["body"]["stack"]
34 stack_status = stack["stack_status"]
35 msg = msg_template % dict(
36 name=stack_name, status=stack_status)
37 if stop_check(stack_status):
38 return stack_status, msg
39
40 time.sleep(poll_period)
41 timeout_sec -= poll_period
42 if timeout_sec <= 0:
43 stack_status = '{0}_FAILED'.format(action)
44 msg = 'Timeout expired'
45 return stack_status, msg
46
47
48def stack_present(name, cloud_name, template=None,
49 environment=None, params=None, poll=5, rollback=False,
50 timeout=60, profile=None, **connection_args):
51 LOG.debug('Deployed with(' +
52 '{0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}, {8} {9})'
53 .format(name, cloud_name, template, environment, params,
54 poll, rollback, timeout, profile, connection_args))
55 ret = {'name': None,
56 'comment': '',
57 'changes': {},
58 'result': True}
59
60 if not name:
61 ret['result'] = False
62 ret['comment'] = 'Name is not valid'
63 return ret
64
65 ret['name'] = name,
66
67 existing_stack = _heat_call('stack_show', name=name,
68 cloud_name=cloud_name)
69
70 if existing_stack['result']:
71 _heat_call('stack_update', name=name,
72 template=template,
73 cloud_name=cloud_name,
74 environment=environment,
75 parameters=params,
76 disable_rollback=not rollback,
77 timeout=timeout)
78 ret['changes']['comment'] = 'Updated stack'
79 status, res = _poll_for_complete(stack_name=name,
80 cloud_name=cloud_name,
81 action="UPDATE", timeout=timeout)
82 ret["result"] = status == "UPDATE_COMPLETE"
83 ret['comment'] = res
84 else:
85 _heat_call('stack_create',
86 name=name,
87 template=template,
88 cloud_name=cloud_name,
89 environment=environment,
90 parameters=params,
91 disable_rollback=not rollback,
92 timeout=timeout)
93 status, res = _poll_for_complete(stack_name=name,
94 cloud_name=cloud_name,
95 action="CREATE", timeout=timeout)
96 ret["result"] = status == "CREATE_COMPLETE"
97 ret['comment'] = res
98 ret['changes']['stack_name'] = name
99 return ret
100
101
102def stack_absent(name, cloud_name, poll=5, timeout=60):
103 LOG.debug('Absent with(' +
104 '{0}, {1}, {2})'.format(name, poll, cloud_name))
105 ret = {'name': None,
106 'comment': '',
107 'changes': {},
108 'result': True}
109 if not name:
110 ret['result'] = False
111 ret['comment'] = 'Name is not valid'
112 return ret
113
114 ret['name'] = name,
115
116 existing_stack = _heat_call('stack_show',
117 name=name, cloud_name=cloud_name)
118
119 if not existing_stack['result']:
120 ret['result'] = True
121 ret['comment'] = 'Stack does not exist'
122 return ret
123
124 _heat_call('stack_delete', name=name, cloud_name=cloud_name)
125 status, comment = _poll_for_complete(stack_name=name,
126 cloud_name=cloud_name,
127 action="DELETE", timeout=timeout)
128 ret['result'] = status == "DELETE_COMPLETE"
129 ret['comment'] = comment
130 ret['changes']['stack_name'] = name
131 return ret