add the newest authorized_key module
remove the old add_host since the new one is upstream now
This commit is contained in:
parent
f6b7ed16af
commit
99cf535801
2 changed files with 187 additions and 23 deletions
|
@ -1,23 +0,0 @@
|
|||
# -*- mode: python -*-
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: add_host
|
||||
short_description: add a host (and alternatively a group) to the ansible-playbook in-memory inventory
|
||||
description:
|
||||
- Use variables to create new hosts and groups in inventory for use in later plays of the same playbook
|
||||
version_added: 0.9
|
||||
options:
|
||||
hostname:
|
||||
description:
|
||||
- The hostname/ip of the host to add to the inventory
|
||||
required: true
|
||||
groupname:
|
||||
description:
|
||||
- The groupname to add the hostname to.
|
||||
required: false
|
||||
author: Seth Vidal
|
||||
examples:
|
||||
- description: add host to group 'just_created'
|
||||
code: add_host hostname=${ip_from_ec2create} groupname=just_created
|
||||
'''
|
187
library/authorized_key
Normal file
187
library/authorized_key
Normal file
|
@ -0,0 +1,187 @@
|
|||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Ansible module to add authorized_keys for ssh logins.
|
||||
(c) 2012, Brad Olson <brado@movedbylight.com>
|
||||
|
||||
This file is part of Ansible
|
||||
|
||||
Ansible 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.
|
||||
|
||||
Ansible 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 Ansible. If not, see <http://www.gnu.org/licenses/>.
|
||||
"""
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: authorized_key
|
||||
short_description: Adds or removes an SSH authorized key
|
||||
description:
|
||||
- Adds or removes an SSH authorized key for a user from a remote host.
|
||||
version_added: "0.5"
|
||||
options:
|
||||
user:
|
||||
description:
|
||||
- Name of the user who should have access to the remote host
|
||||
required: true
|
||||
default: null
|
||||
aliases: []
|
||||
key:
|
||||
description:
|
||||
- the SSH public key, as a string
|
||||
required: true
|
||||
default: null
|
||||
state:
|
||||
description:
|
||||
- whether the given key should or should not be in the file
|
||||
required: false
|
||||
choices: [ "present", "absent" ]
|
||||
default: "present"
|
||||
examples:
|
||||
- code: 'authorized_key: user=charlie key="ssh-dss ASDF1234L+8BTwaRYr/rycsBF1D8e5pTxEsXHQs4iq+mZdyWqlW++L6pMiam1A8yweP+rKtgjK2httVS6GigVsuWWfOd7/sdWippefq74nppVUELHPKkaIOjJNN1zUHFoL/YMwAAAEBALnAsQN10TNGsRDe5arBsW8cTOjqLyYBcIqgPYTZW8zENErFxt7ij3fW3Jh/sCpnmy8rkS7FyK8ULX0PEy/2yDx8/5rXgMIICbRH/XaBy9Ud5bRBFVkEDu/r+rXP33wFPHjWjwvHAtfci1NRBAudQI/98DbcGQw5HmE89CjgZRo5ktkC5yu/8agEPocVjdHyZr7PaHfxZGUDGKtGRL2QzRYukCmWo1cZbMBHcI5FzImvTHS9/8B3SATjXMPgbfBuEeBwuBK5EjL+CtHY5bWs9kmYjmeo0KfUMH8hY4MAXDoKhQ7DhBPIrcjS5jPtoGxIREZjba67r6/P2XKXaCZH6Fc= charlie@example.org 2011-01-17"'
|
||||
description: "Example from Ansible Playbooks"
|
||||
- code: "authorized_key: user=charlie key='$FILE(/home/charlie/.ssh/id_rsa.pub)'"
|
||||
description: "Shorthand available in Ansible 0.8 and later"
|
||||
author: Brad Olson
|
||||
'''
|
||||
|
||||
# Makes sure the public key line is present or absent in the user's .ssh/authorized_keys.
|
||||
#
|
||||
# Arguments
|
||||
# =========
|
||||
# user = username
|
||||
# key = line to add to authorized_keys for user
|
||||
# state = absent|present (default: present)
|
||||
#
|
||||
# see example in examples/playbooks
|
||||
|
||||
import sys
|
||||
import os
|
||||
import pwd
|
||||
import os.path
|
||||
import tempfile
|
||||
import shutil
|
||||
|
||||
def keyfile(module, user, write=False):
|
||||
"""
|
||||
Calculate name of authorized keys file, optionally creating the
|
||||
directories and file, properly setting permissions.
|
||||
|
||||
:param str user: name of user in passwd file
|
||||
:param bool write: if True, write changes to authorized_keys file (creating directories if needed)
|
||||
:return: full path string to authorized_keys for user
|
||||
"""
|
||||
|
||||
try:
|
||||
user_entry = pwd.getpwnam(user)
|
||||
except KeyError, e:
|
||||
module.fail_json(msg="Failed to lookup user %s: %s" % (user, str(e)))
|
||||
homedir = user_entry.pw_dir
|
||||
sshdir = os.path.join(homedir, ".ssh")
|
||||
keysfile = os.path.join(sshdir, "authorized_keys")
|
||||
|
||||
if not write:
|
||||
return keysfile
|
||||
|
||||
uid = user_entry.pw_uid
|
||||
gid = user_entry.pw_gid
|
||||
|
||||
if not os.path.exists(sshdir):
|
||||
os.mkdir(sshdir, 0700)
|
||||
if module.selinux_enabled():
|
||||
module.set_default_selinux_context(sshdir, False)
|
||||
os.chown(sshdir, uid, gid)
|
||||
os.chmod(sshdir, 0700)
|
||||
|
||||
if not os.path.exists( keysfile):
|
||||
try:
|
||||
f = open(keysfile, "w") #touches file so we can set ownership and perms
|
||||
finally:
|
||||
f.close()
|
||||
if module.selinux_enabled():
|
||||
module.set_default_selinux_context(keysfile, False)
|
||||
|
||||
os.chown(keysfile, uid, gid)
|
||||
os.chmod(keysfile, 0600)
|
||||
return keysfile
|
||||
|
||||
def readkeys(filename):
|
||||
|
||||
if not os.path.isfile(filename):
|
||||
return []
|
||||
f = open(filename)
|
||||
keys = [line.rstrip() for line in f.readlines()]
|
||||
f.close()
|
||||
return keys
|
||||
|
||||
def writekeys(module, filename, keys):
|
||||
|
||||
fd, tmp_path = tempfile.mkstemp('', 'tmp', os.path.dirname(filename))
|
||||
f = open(tmp_path,"w")
|
||||
try:
|
||||
f.writelines( (key + "\n" for key in keys) )
|
||||
except IOError, e:
|
||||
module.fail_json(msg="Failed to write to file %s: %s" % (tmp_path, str(e)))
|
||||
f.close()
|
||||
module.atomic_replace(tmp_path, filename)
|
||||
|
||||
def enforce_state(module, params):
|
||||
"""
|
||||
Add or remove key.
|
||||
"""
|
||||
|
||||
user = params["user"]
|
||||
key = params["key"]
|
||||
state = params.get("state", "present")
|
||||
|
||||
key = key.split('\n')
|
||||
|
||||
# check current state -- just get the filename, don't create file
|
||||
params["keyfile"] = keyfile(module, user, write=False)
|
||||
keys = readkeys(params["keyfile"])
|
||||
|
||||
# Check our new keys, if any of them exist we'll continue.
|
||||
for new_key in key:
|
||||
present = new_key in keys
|
||||
# handle idempotent state=present
|
||||
if state=="present":
|
||||
if present:
|
||||
continue
|
||||
keys.append(new_key)
|
||||
writekeys(module, keyfile(module, user,write=True), keys)
|
||||
params['changed'] = True
|
||||
|
||||
elif state=="absent":
|
||||
if not present:
|
||||
continue
|
||||
keys.remove(new_key)
|
||||
writekeys(module, keyfile(module, user,write=True), keys)
|
||||
params['changed'] = True
|
||||
|
||||
return params
|
||||
|
||||
def main():
|
||||
|
||||
module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
user = dict(required=True),
|
||||
key = dict(required=True),
|
||||
state = dict(default='present', choices=['absent','present'])
|
||||
)
|
||||
)
|
||||
|
||||
results = enforce_state(module, module.params)
|
||||
module.exit_json(**results)
|
||||
|
||||
# this is magic, see lib/ansible/module_common.py
|
||||
#<<INCLUDE_ANSIBLE_MODULE_COMMON>>
|
||||
main()
|
Loading…
Add table
Add a link
Reference in a new issue