From 1695b26c4ed855cdb707335b15495c2552938aa1 Mon Sep 17 00:00:00 2001 From: jpic Date: Fri, 6 May 2016 15:51:28 +0200 Subject: Beautiful -v output from ansible When supporting openshift-ansible, users share pastes like:: TASK: [openshift_serviceaccounts | Grant the user access to the privileged scc] *** changed: [li1491-86.members.linode.com] => (item=['router', {'cmd': ['oc', 'get', 'scc', 'privileged', '-o', 'yaml'], 'end': '2016-05-05 13:31:50.216857', 'stderr': u'', 'stdout': 'allowHostDirVolumePlugin: true\nallowHostIPC: true\nallowHostNetwork: true\nallowHostPID: true\nallowHostPorts: true\nallowPrivilegedContainer: true\nallowedCapabilities: null\napiVersion: v1\ndefaultAddCapabilities: null\nfsGroup:\n type: RunAsAny\ngroups:\n- system:cluster-admins\n- system:nodes\nkind: SecurityContextConstraints\nmetadata:\n annotations:\n kubernetes.io/description: \'privileged allows access to all privileged and host\n features and the ability to run as any user, any group, any fsGroup, and with\n any SELinux context. WARNING: this is the most relaxed SCC and should be used\n only for cluster administration. Grant with caution.\'\n creationTimestamp: 2016-05-05T13:30:06Z\n name: privileged\n resourceVersion: "371"\n selfLink: /api/v1/securitycontextconstraints/privileged\n uid: 7ae22005-12c5-11e6-9bc5-06174e73e52a\npriority: null\nreadOnlyRootFilesystem: false\nrequiredDropCapabilities: null\nrunAsUser:\n type: RunAsAny\nseLinuxContext:\n type: RunAsAny\nsupplementalGroups:\n type: RunAsAny\nusers:\n- system:serviceaccount:openshift-infra:build-controller\n- system:serviceaccount:management-infra:management-admin\n- system:serviceaccount:management-infra:inspector-admin\nvolumes:\n- \'*\'', 'item': 'privileged', 'changed': False, 'rc': 0, 'failed': False, 'warnings': [], 'delta': '0:00:00.264340', 'invocation': {'module_name': u'command', 'module_complex_args': {}, 'module_args': u'oc get scc privileged -o yaml'}, 'stdout_lines': ['allowHostDirVolumePlugin: true', 'allowHostIPC: true', 'allowHostNetwork: true', 'allowHostPID: true', 'allowHostPorts: true', 'allowPrivilegedContainer: true', 'allowedCapabilities: null', 'apiVersion: v1', 'defaultAddCapabilities: null', 'fsGroup:', ' type: RunAsAny', 'groups:', '- system:cluster-admins', '- system:nodes', 'kind: SecurityContextConstraints', 'metadata:', ' annotations:', " kubernetes.io/description: 'privileged allows access to all privileged and host", ' features and the ability to run as any user, any group, any fsGroup, and with', ' any SELinux context. WARNING: this is the most relaxed SCC and should be used', " only for cluster administration. Grant with caution.'", ' creationTimestamp: 2016-05-05T13:30:06Z', ' name: privileged', ' resourceVersion: "371"', ' selfLink: /api/v1/securitycontextconstraints/privileged', ' uid: 7ae22005-12c5-11e6-9bc5-06174e73e52a', 'priority: null', 'readOnlyRootFilesystem: false', 'requiredDropCapabilities: null', 'runAsUser:', ' type: RunAsAny', 'seLinuxContext:', ' type: RunAsAny', 'supplementalGroups:', ' type: RunAsAny', 'users:', '- system:serviceaccount:openshift-infra:build-controller', '- system:serviceaccount:management-infra:management-admin', '- system:serviceaccount:management-infra:inspector-admin', 'volumes:', "- '*'"], 'failed_when_result': False, 'start': '2016-05-05 13:31:49.952517'}]) changed: [li1491-86.members.linode.com] => (item=['registry', {'cmd': ['oc', 'get', 'scc', 'privileged', '-o', 'yaml'], 'end': '2016-05-05 13:31:50.216857', 'stderr': u'', 'stdout': 'allowHostDirVolumePlugin: true\nallowHostIPC: true\nallowHostNetwork: true\nallowHostPID: true\nallowHostPorts: true\nallowPrivilegedContainer: true\nallowedCapabilities: null\napiVersion: v1\ndefaultAddCapabilities: null\nfsGroup:\n type: RunAsAny\ngroups:\n- system:cluster-admins\n- system:nodes\nkind: SecurityContextConstraints\nmetadata:\n annotations:\n kubernetes.io/description: \'privileged allows access to all privileged and host\n features and the ability to run as any user, any group, any fsGroup, and with\n any SELinux context. WARNING: this is the most relaxed SCC and should be used\n only for cluster administration. Grant with caution.\'\n creationTimestamp: 2016-05-05T13:30:06Z\n name: privileged\n resourceVersion: "371"\n selfLink: /api/v1/securitycontextconstraints/privileged\n uid: 7ae22005-12c5-11e6-9bc5-06174e73e52a\npriority: null\nreadOnlyRootFilesystem: false\nrequiredDropCapabilities: null\nrunAsUser:\n type: RunAsAny\nseLinuxContext:\n type: RunAsAny\nsupplementalGroups:\n type: RunAsAny\nusers:\n- system:serviceaccount:openshift-infra:build-controller\n- system:serviceaccount:management-infra:management-admin\n- system:serviceaccount:management-infra:inspector-admin\nvolumes:\n- \'*\'', 'item': 'privileged', 'changed': False, 'rc': 0, 'failed': False, 'warnings': [], 'delta': '0:00:00.264340', 'invocation': {'module_name': u'command', 'module_complex_args': {}, 'module_args': u'oc get scc privileged -o yaml'}, 'stdout_lines': ['allowHostDirVolumePlugin: true', 'allowHostIPC: true', 'allowHostNetwork: true', 'allowHostPID: true', 'allowHostPorts: true', 'allowPrivilegedContainer: true', 'allowedCapabilities: null', 'apiVersion: v1', 'defaultAddCapabilities: null', 'fsGroup:', ' type: RunAsAny', 'groups:', '- system:cluster-admins', '- system:nodes', 'kind: SecurityContextConstraints', 'metadata:', ' annotations:', " kubernetes.io/description: 'privileged allows access to all privileged and host", ' features and the ability to run as any user, any group, any fsGroup, and with', ' any SELinux context. WARNING: this is the most relaxed SCC and should be used', " only for cluster administration. Grant with caution.'", ' creationTimestamp: 2016-05-05T13:30:06Z', ' name: privileged', ' resourceVersion: "371"', ' selfLink: /api/v1/securitycontextconstraints/privileged', ' uid: 7ae22005-12c5-11e6-9bc5-06174e73e52a', 'priority: null', 'readOnlyRootFilesystem: false', 'requiredDropCapabilities: null', 'runAsUser:', ' type: RunAsAny', 'seLinuxContext:', ' type: RunAsAny', 'supplementalGroups:', ' type: RunAsAny', 'users:', '- system:serviceaccount:openshift-infra:build-controller', '- system:serviceaccount:management-infra:management-admin', '- system:serviceaccount:management-infra:inspector-admin', 'volumes:', "- '*'"], 'failed_when_result': False, 'start': '2016-05-05 13:31:49.952517'}]) With this patch, the json is nicely indented and std{err,out} are properly printed by default with -v. --- callback_plugins/default.py | 60 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 callback_plugins/default.py (limited to 'callback_plugins') diff --git a/callback_plugins/default.py b/callback_plugins/default.py new file mode 100644 index 000000000..31e3d7d4c --- /dev/null +++ b/callback_plugins/default.py @@ -0,0 +1,60 @@ +'''Plugin to override the default output logic.''' + +# upstream: https://gist.github.com/cliffano/9868180 + +# This program 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 program 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 program. If not, see . + + +# For some reason this has to be done +import imp +import os + +ANSIBLE_PATH = imp.find_module('ansible')[1] +DEFAULT_PATH = os.path.join(ANSIBLE_PATH, 'plugins/callback/default.py') +DEFAULT_MODULE = imp.load_source( + 'ansible.plugins.callback.default', + DEFAULT_PATH +) + + +class CallbackModule(DEFAULT_MODULE.CallbackModule): # pylint: disable=too-few-public-methods,no-init + ''' + Override for the default callback module. + + Render std err/out outside of the rest of the result which it prints with + indentation. + ''' + CALLBACK_VERSION = 2.0 + CALLBACK_TYPE = 'stdout' + CALLBACK_NAME = 'default' + + def _dump_results(self, result): + '''Return the text to output for a result.''' + result['_ansible_verbose_always'] = True + + save = {} + for key in ['stdout', 'stdout_lines', 'stderr', 'stderr_lines', 'msg']: + if key in result: + save[key] = result.pop(key) + + output = DEFAULT_MODULE.CallbackModule._dump_results(self, result) + + for key in ['stdout', 'stderr', 'msg']: + if key in save and save[key]: + output += '\n\n%s:\n\n%s\n' % (key.upper(), save[key]) + + for key, value in save.items(): + result[key] = value + + return output -- cgit v1.2.3