-
Notifications
You must be signed in to change notification settings - Fork 3.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Successfully test collection of event_query.yml
data
#15761
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
# (C) 2012, Michael DeHaan, <[email protected]> | ||
# (c) 2017 Ansible Project | ||
# 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 | ||
|
||
|
||
DOCUMENTATION = ''' | ||
callback: host_query | ||
type: notification | ||
short_description: for demo of indirect host data and counting, this produces collection data | ||
version_added: historical | ||
description: | ||
- Saves collection data to artifacts folder | ||
requirements: | ||
- Whitelist in configuration | ||
- Set AWX_ISOLATED_DATA_DIR, AWX will do this | ||
''' | ||
|
||
import os | ||
import json | ||
|
||
from ansible.plugins.callback import CallbackBase | ||
|
||
|
||
# NOTE: in Ansible 1.2 or later general logging is available without | ||
# this plugin, just set ANSIBLE_LOG_PATH as an environment variable | ||
# or log_path in the DEFAULTS section of your ansible configuration | ||
# file. This callback is an example of per hosts logging for those | ||
# that want it. | ||
|
||
|
||
# Taken from https://github.com/ansible/ansible/blob/devel/lib/ansible/cli/galaxy.py#L1624 | ||
|
||
from ansible.cli.galaxy import with_collection_artifacts_manager | ||
from ansible.release import __version__ | ||
|
||
from ansible.galaxy.collection import find_existing_collections | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. TODO: will have to wrap this in a try-except, not currently a public API. Do simple warning of some type if it doesn't work. |
||
from ansible.utils.collection_loader import AnsibleCollectionConfig | ||
import ansible.constants as C | ||
|
||
from ansible.module_utils.common.text.converters import to_text | ||
|
||
|
||
@with_collection_artifacts_manager | ||
def list_collections(artifacts_manager=None): | ||
artifacts_manager.require_build_metadata = False | ||
|
||
default_collections_path = set(C.COLLECTIONS_PATHS) | ||
collections_search_paths = default_collections_path | set(AnsibleCollectionConfig.collection_paths) | ||
collections = list(find_existing_collections(list(collections_search_paths), artifacts_manager, dedupe=False)) | ||
return collections | ||
|
||
|
||
class CallbackModule(CallbackBase): | ||
""" | ||
logs playbook results, per host, in /var/log/ansible/hosts | ||
""" | ||
|
||
CALLBACK_VERSION = 2.0 | ||
CALLBACK_TYPE = 'notification' | ||
CALLBACK_NAME = 'indirect_instance_count' | ||
CALLBACK_NEEDS_WHITELIST = True | ||
|
||
TIME_FORMAT = "%b %d %Y %H:%M:%S" | ||
MSG_FORMAT = "%(now)s - %(category)s - %(data)s\n\n" | ||
|
||
def v2_playbook_on_stats(self, stats): | ||
artifact_dir = os.getenv('AWX_ISOLATED_DATA_DIR') | ||
if not artifact_dir: | ||
raise RuntimeError('Only suitable in AWX, did not find private_data_dir') | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what does There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We're writing a plugin that is usable generally in an |
||
|
||
collections_print = {} | ||
for collection_obj in list_collections(): | ||
collection_print = { | ||
'version': collection_obj.ver, | ||
} | ||
host_query_path = os.path.join(to_text(collection_obj.src), 'meta', 'event_query.yml') | ||
if os.path.exists(host_query_path): | ||
with open(host_query_path, 'r') as f: | ||
collection_print['host_query'] = f.read() | ||
collections_print[collection_obj.fqcn] = collection_print | ||
|
||
ansible_data = {'installed_collections': collections_print, 'ansible_version': __version__} | ||
|
||
write_path = os.path.join(artifact_dir, 'ansible_data.json') | ||
with open(write_path, "w") as fd: | ||
fd.write(json.dumps(ansible_data, indent=2)) | ||
|
||
super().v2_playbook_on_stats(stats) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So this mechanism already exists? Or was it unused so far?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It existed, but was broken with a particular ansible-runner version.
The design problem is that we can't honestly collect the event_query data without also indirectly collecting the collection list (which is what this did, but is broken). So it would be awfully neglectful to throw in the new loading logic right next to the old, broken, artifact file loading which is the same in form.
We still have a software coordination problem, which is that supposed there is a shared problem which will lead to ansible-runner developing a new solution, and that the collection listing this uses is a non-public API... but categorically, if there is no public API for the collection list, this sub-collection detail of the event_query can't be gathered in a kosher manner.
Let me jump to the conclusion - we finish up this approach and call it the "beta" version. It will be fully functional, but use non-public APIs. Then, we will have a TODO when the public API (new callback methods) are delivered from ansible-runner. We may need to have an import test / fallback to switch between the "beta" behavior and the accepted solution.