Created
February 23, 2024 00:55
-
-
Save jborean93/7b195b7e22fad70605a3a702e05eb205 to your computer and use it in GitHub Desktop.
POC for Ansible callback that calls kinit
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Copyright (c) 2024 Jordan Borean | |
# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) | |
from __future__ import annotations | |
DOCUMENTATION = """ | |
name: kinit | |
type: aggregate | |
short_description: POC to run kinit on a playbook run. | |
description: | |
- Runs kinit to retrieve a Kerberos ticket for the playbook connection plugins | |
to use. | |
- This stores the Kerberos ccache as a temporary file and is automatically used | |
by any Kerberos C clients through the KRB5CCNAME env var. | |
author: Jordan Borean (@jborean93) | |
options: | |
username: | |
description: | |
- The username to retrieve the ticket for. | |
type: str | |
required: true | |
env: | |
# Allow you to override with a custom user if need be | |
- name: ANSIBLE_KINIT_USERNAME | |
# Fallback env vars used by ssh | |
- name: ANSIBLE_REMOTE_USER | |
password: | |
description: | |
- The password for the user. | |
type: str | |
required: true | |
env: | |
- name: ANSIBLE_KINIT_PASSWORD | |
forwardable: | |
description: | |
- Request a forwardable ticket used for delegation. | |
type: bool | |
default: false | |
env: | |
- name: ANSIBLE_KINIT_FORWARDABLE | |
""" | |
import os | |
import shlex | |
import subprocess | |
import tempfile | |
from ansible.errors import AnsibleCallbackError | |
from ansible.playbook import Playbook | |
from ansible.plugins.callback import CallbackBase | |
class CallbackModule(CallbackBase): | |
CALLBACK_VERSION = 2.0 | |
CALLBACK_TYPE = "aggregate" | |
CALLBACK_NAME = "kinit" | |
CALLBACK_NEEDS_ENABLED = True | |
def __init__(self) -> None: | |
super().__init__() | |
# We need to keep a reference to the temp file so it stays available | |
# throughout the whole run. | |
self._ccache = tempfile.NamedTemporaryFile() | |
def v2_playbook_on_start( | |
self, | |
playbook: Playbook, | |
) -> None: | |
username = self.get_option("username") | |
password = self.get_option("password") | |
forwardable = self.get_option("forwardable") | |
sysname = os.uname()[0] | |
kinit_args = ["kinit"] | |
if sysname == "Darwin": | |
kinit_args.append("--password-file=STDIN") | |
if forwardable: | |
kinit_args.append("-f") | |
kinit_args.append(username) | |
os.environ["KRB5CCNAME"] = f"FILE:{self._ccache.name}" | |
process = subprocess.Popen( | |
kinit_args, | |
stdin=subprocess.PIPE, | |
stdout=subprocess.PIPE, | |
stderr=subprocess.PIPE, | |
) | |
stdout, stderr = process.communicate(password.encode() + b"\n") | |
rc = process.returncode | |
if rc: | |
msg = f"Kinit [{shlex.join(kinit_args)}] failed with RC: {rc}. STDOUT: {stdout.decode()}. STDERR: {stderr.decode()}" | |
raise AnsibleCallbackError(msg) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment