ansible/library/authorized_key

137 lines
3.6 KiB
Text
Raw Normal View History

#!/usr/bin/env 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/>.
"""
# 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
def keyfile(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
"""
user_entry = pwd.getpwnam(user)
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)
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()
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( filename, keys):
f = open(filename,"w")
f.writelines( (key + "\n" for key in keys) )
f.close()
def enforce_state(module, params):
"""
Add or remove key.
"""
user = params["user"]
key = params["key"]
state = params.get("state", "present")
# check current state -- just get the filename, don't create file
params["keyfile"] = keyfile(user, write=False)
keys = readkeys(params["keyfile"])
present = key in keys
# handle idempotent state=present
if state=="present":
if present:
module.exit_json(changed=False)
keys.append(key)
writekeys(keyfile(user,write=True), keys)
elif state=="absent":
if not present:
module.exit_json(changed=False)
keys.remove(key)
writekeys(keyfile(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'])
)
)
params = module.params
results = enforce_state(module, module.params)
module.exit_json(**results)
# this is magic, see lib/ansible/module_common.py
#<<INCLUDE_ANSIBLE_MODULE_COMMON>>
main()