feat: display helm cmd in state output
Fixes salt-formulas/salt-formula-helm#5
diff --git a/_modules/helm.py b/_modules/helm.py
index 3e10683..c92f4d2 100644
--- a/_modules/helm.py
+++ b/_modules/helm.py
@@ -6,15 +6,10 @@
LOG = logging.getLogger(__name__)
-def ok_or_output(cmd, prefix=None):
- ret = __salt__['cmd.run_all'](**cmd)
- if ret['retcode'] == 0:
- return None
- msg = "Stdout:\n{0[stdout]}\nStderr:\n{0[stderr]}".format(ret)
- if prefix:
- msg = prefix + ':\n' + msg
- return msg
-
+class HelmExecutionError(CommandExecutionError):
+ def __init__(self, cmd, error):
+ self.cmd = cmd
+ self.error = error
def _helm_cmd(*args, **kwargs):
if kwargs.get('tiller_host'):
@@ -38,6 +33,24 @@
'env': env,
}
+def _cmd_and_result(*args, **kwargs):
+ cmd = _helm_cmd(*args, **kwargs)
+ env_string = "".join(['%s="%s" ' % (k, v) for (k, v) in cmd.get('env', {}).items()])
+ cmd_string = env_string + " ".join(cmd['cmd'])
+ result = None
+ try:
+ result = __salt__['cmd.run_all'](**cmd)
+ if result['retcode'] != 0:
+ raise CommandExecutionError(result['stderr'])
+ return {
+ 'cmd': cmd_string,
+ 'stdout': result['stdout'],
+ 'stderr': result['stderr']
+ }
+ except CommandExecutionError as e:
+ raise HelmExecutionError(cmd_string, e)
+
+
def _parse_release(output):
result = {}
chart_match = re.search(r'CHART\: ([^0-9]+)-([^\s]+)', output)
@@ -110,11 +123,7 @@
url
The url for the chart repository.
'''
- cmd = _helm_cmd('repo', 'add', name, url, **kwargs)
- ret = __salt__['cmd.run_all'](**cmd)
- if ret['retcode'] != 0:
- raise CommandExecutionError(ret['stderr'])
- return ret['stdout']
+ return _cmd_and_result('repo', 'add', name, url, **kwargs)
def remove_repo(name, **kwargs):
'''
@@ -124,11 +133,7 @@
name
The name (as registered with the Helm client) for the repository to remove
'''
- cmd = _helm_cmd('repo', 'remove', name, **kwargs)
- ret = __salt__['cmd.run_all'](**cmd)
- if ret['retcode'] != 0:
- raise CommandExecutionError(ret['stderr'])
- return ret['stdout']
+ return _cmd_and_result('repo', 'remove', name, **kwargs)
def manage_repos(present={}, absent=[], exclusive=False, **kwargs):
'''
@@ -206,7 +211,7 @@
result['added'].append({
'name': name,
'url': url,
- 'stdout': add_repo(name, url, **kwargs)
+ 'stdout': add_repo(name, url, **kwargs)['stdout']
})
existing_repos = {
n: u for (n, u) in existing_repos.iteritems() if name != n
@@ -240,7 +245,7 @@
try:
result['removed'].append({
'name': name,
- 'stdout': remove_repo(name, **kwargs)
+ 'stdout': remove_repo(name, **kwargs) ['stdout']
})
except CommandExecutionError as e:
result['failed'].append({
@@ -254,8 +259,7 @@
Ensures the local helm repository cache for each repository is up to date.
Proxies the `helm repo update` command.
'''
- cmd = _helm_cmd('repo', 'update', **kwargs)
- return __salt__['cmd.run_stdout'](**cmd)
+ return _cmd_and_result('repo', 'update', **kwargs)
def get_release(name, tiller_namespace="kube-system", **kwargs):
'''
@@ -311,19 +315,19 @@
args += ['--version', version]
if values_file is not None:
args += ['--values', values_file]
- cmd = _helm_cmd('install', '--namespace', namespace, '--name', name, chart_name,
- *args, **kwargs)
- LOG.debug('Creating release with args: %s', cmd)
- return ok_or_output(cmd, 'Failed to create release "{}"'.format(name))
-
+ return _cmd_and_result(
+ 'install', chart_name,
+ '--namespace', namespace,
+ '--name', name,
+ *args, **kwargs
+ )
def release_delete(name, tiller_namespace='kube-system', **kwargs):
'''
Delete and purge any release found with the supplied name.
'''
kwargs['tiller_namespace'] = tiller_namespace
- cmd = _helm_cmd('delete', '--purge', name, **kwargs)
- return ok_or_output(cmd, 'Failed to delete release "{}"'.format(name))
+ return _cmd_and_result('delete', '--purge', name, **kwargs)
def release_upgrade(name, chart_name, namespace='default',
@@ -343,9 +347,11 @@
args += ['--version', version]
if values_file is not None:
args += ['--values', values_file]
- cmd = _helm_cmd('upgrade', '--namespace', namespace, name, chart_name, **kwargs)
- LOG.debug('Upgrading release with args: %s', cmd)
- return ok_or_output(cmd, 'Failed to upgrade release "{}"'.format(name))
+ return _cmd_and_result(
+ 'upgrade', name, chart_name,
+ '--namespace', namespace,
+ **kwargs
+ )
def install_chart_dependencies(chart_path, **kwargs):
'''
@@ -355,8 +361,7 @@
chart_path
The path to the chart for which to install dependencies
'''
- cmd = _helm_cmd('dependency', 'build', **kwargs)
- return __salt__['cmd.run_stdout'](cwd=chart_path, **cmd)
+ return _cmd_and_result('dependency', 'build', **kwargs)
def package(path, destination = None, **kwargs):
'''
@@ -373,5 +378,4 @@
if destination:
args += ["-d", destination]
- cmd = _helm_cmd('package', path, *args, **kwargs)
- return __salt__['cmd.run_stdout'](**cmd)
+ return _cmd_and_result('package', path, *args, **kwargs)
diff --git a/_states/helm_release.py b/_states/helm_release.py
index 7a66b10..dae657a 100644
--- a/_states/helm_release.py
+++ b/_states/helm_release.py
@@ -68,23 +68,28 @@
kwargs['tiller_namespace'] = tiller_namespace
old_release = __salt__['helm.get_release'](name, **kwargs)
if not old_release:
- err = __salt__['helm.release_create'](
+ try:
+ result = __salt__['helm.release_create'](
name, chart_name, namespace, version, values_file, **kwargs
)
- if err:
- return _failure(name, err)
return {
+ 'name': name,
+ 'changes': {
'name': name,
- 'changes': {
- 'name': name,
- 'chart_name': chart_name,
- 'namespace': namespace,
- 'version': version,
- 'values': _get_values_from_file(values_file)
- },
- 'result': True,
- 'comment': 'Release "{}" was created'.format(name),
+ 'chart_name': chart_name,
+ 'namespace': namespace,
+ 'version': version,
+ 'values': _get_values_from_file(values_file),
+ 'stdout': result.get('stdout')
+ },
+ 'result': True,
+ 'comment': ('Release "%s" was created' % name +
+ '\nExecuted command: %s' % result['cmd'])
}
+ except CommandExecutionError as e:
+ msg = (("Failed to create new release: %s" % e.error) +
+ "\nExecuted command: %s" % e.cmd)
+ return _failure(name, msg)
changes = {}
warnings = []
@@ -120,29 +125,35 @@
module_fn = 'helm.release_upgrade'
if changes.get("namespace"):
LOG.debug("purging old release (%s) due to namespace change" % name)
- err = __salt__['helm.release_delete'](name, **kwargs)
- if err:
- return _failure(name, err, changes)
+ try:
+ result = __salt__['helm.release_delete'](name, **kwargs)
+ except CommandExecutionError as e:
+ msg = ("Failed to delete release for namespace change: %s" % e.error +
+ "\nExecuted command: %s" % e.cmd)
+ return _failure(name, msg, changes)
+
module_fn = 'helm.release_create'
warnings.append('Release (%s) was replaced due to namespace change' % name)
- err = __salt__[module_fn](
+ try:
+ result = __salt__[module_fn](
name, chart_name, namespace, version, values_file, **kwargs
- )
- if err:
- return _failure(name, err, changes)
-
- ret = {
+ )
+ changes.update({ 'stdout': result.get('stdout') })
+ ret = {
'name': name,
'changes': changes,
'result': True,
- 'comment': 'Release "{}" was updated'.format(name),
- }
+ 'comment': 'Release "%s" was updated\nExecuted command: %s' % (name, result['cmd'])
+ }
+ if warnings:
+ ret['warnings'] = warnings
- if warnings:
- ret['warnings'] = warnings
-
- return ret
+ return ret
+ except CommandExecutionError as e:
+ msg = ("Failed to delete release for namespace change: %s" % e.error +
+ "\nExecuted command: %s" % e.cmd)
+ return _failure(name, msg, changes)
def absent(name, tiller_namespace='kube-system', **kwargs):
@@ -160,14 +171,16 @@
'name': name,
'changes': {},
'result': True,
- 'comment': 'Release "{}" doesn\'t exist'.format(name),
+ 'comment': 'Release "%s" doesn\'t exist' % name
}
- err = __salt__['helm.release_delete'](name, **kwargs)
- if err:
- return _failure(name, err)
- return {
+ try:
+ result = __salt__['helm.release_delete'](name, **kwargs)
+ return {
'name': name,
- 'changes': {name: 'DELETED'},
+ 'changes': { name: 'DELETED', 'stdout': result['stdout'] },
'result': True,
- 'comment': 'Release "{}" was deleted'.format(name),
- }
+ 'comment': 'Release "%s" was deleted\nExecuted command: %s' % (name, result['cmd'])
+ }
+ except CommandExecutionError as e:
+ return _failure(e.cmd, e.error)
+
diff --git a/_states/helm_repos.py b/_states/helm_repos.py
index ee1d556..5c41c0b 100644
--- a/_states/helm_repos.py
+++ b/_states/helm_repos.py
@@ -77,25 +77,29 @@
'result': True,
'comment': 'Successfully synced repositories: ' }
- output = None
+
try:
- output = __salt__['helm.update_repos'](helm_home=helm_home)
+ result = __salt__['helm.update_repos'](helm_home=helm_home)
+ cmd_str = "\nExecuted command: %s" % result['cmd']
+
+ success_repos = re.findall(
+ r'Successfully got an update from the \"([^\"]+)\"', result['stdout'])
+ failed_repos = re.findall(
+ r'Unable to get an update from the \"([^\"]+)\"', result['stdout'])
+
+ if failed_repos and len(failed_repos) > 0:
+ ret['result'] = False
+ ret['changes']['succeeded'] = success_repos
+ ret['changes']['failed'] = failed_repos
+ ret['comment'] = 'Failed to sync against some repositories' + cmd_str
+ else:
+ ret['comment'] += "%s" % success_repos + cmd_str
+
except CommandExecutionError as e:
+ ret['name'] = e.cmd
ret['result'] = False
- ret['comment'] = "Failed to update repos: %s" % e
+ ret['comment'] = ("Failed to update repos: %s" % e.error +
+ "\nExecuted command: %s" % e.cmd)
return ret
- success_repos = re.findall(
- r'Successfully got an update from the \"([^\"]+)\"', output)
- failed_repos = re.findall(
- r'Unable to get an update from the \"([^\"]+)\"', output)
-
- if failed_repos and len(failed_repos) > 0:
- ret['result'] = False
- ret['changes']['succeeded'] = success_repos
- ret['changes']['failed'] = failed_repos
- ret['comment'] = 'Failed to sync against some repositories'
- else:
- ret['comment'] += "%s" % success_repos
-
return ret
\ No newline at end of file