functional cloud-config-ssh.conf now

This fixes LP: #506599 , LP: #507070 .

Also, here, we move config parsing out of the EC2Init class.
Instead the parsing of /etc/ec2-init/ec2-init.cfg is now done in the
CloudConfig class, and prepended to the cloud-config that comes in
from user data.  This means that values in user data will over-ride
the settings in /etc/ec2-init.

Still TODO is support reading the public and private key files from
the cloud-config
This commit is contained in:
Scott Moser 2010-01-14 17:00:28 -05:00
parent a6b9c37d67
commit 5be0f941fc
3 changed files with 103 additions and 53 deletions

View File

@ -28,15 +28,42 @@ class CloudConfig():
cfgfile = None
handlers = { }
cfg = None
old_conffile = '/etc/ec2-init/ec2-config.cfg'
def __init__(self,cfgfile):
import pprint; pprint.pprint(self.cfg)
self.cfg=read_conf(cfgfile)
self.cfg = self.get_config_obj(cfgfile)
self.cloud = ec2init.EC2Init()
self.cloud.get_data_source()
self.add_handler('apt-update-upgrade', self.h_apt_update_upgrade)
self.add_handler('config-ssh')
def get_config_obj(self,cfgfile):
str=""
# support reading the old ConfigObj format file and turning it
# into a yaml string
try:
f = file(self.old_conffile)
str+=file.read().replace('=',': ')
f.close()
except:
pass
f = file(cfgfile)
cfg=yaml.load(str + f.read())
f.close()
return(cfg)
def convert_old_config(self):
# support reading the old ConfigObj format file and turning it
# into a yaml string
try:
f = file(self.conffile)
str=file.read().replace('=',': ')
f.close()
return str
except:
return("")
def add_handler(self, name, handler=None, freq=None):
if handler is None:
try:
@ -124,6 +151,29 @@ class CloudConfig():
def h_config_ssh(self,name,args):
print "Warning, not doing anything for config %s" % name
if False:
# if there are keys in cloud-config, use them
# TODO: need to get keys from cloud-config if present
# and replace those in /etc/ssh
pass
else:
# if not, generate them
clean_and_gen='rm -f /etc/ssh/ssh_host_*_key*; ' + \
'ssh-keygen -f /etc/ssh/ssh_host_rsa_key -t rsa -N ""; ' + \
'ssh-keygen -f /etc/ssh/ssh_host_dsa_key -t rsa -N ""; '
subprocess.call(('sh', '-c', clean_and_gen))
try:
user = get_cfg_option_str(self.cfg,'user')
disable_root = get_cfg_option_bool(self.cfg, "disable_root", True)
keys = self.cloud.get_public_ssh_keys()
apply_credentials(keys,user,disable_root)
except:
warn("applying credentials failed!\n")
send_ssh_keys_to_console()
subprocess.call(('restart', 'ssh'))
def h_ec2_ebs_mounts(self,name,args):
print "Warning, not doing anything for config %s" % name
@ -136,7 +186,6 @@ class CloudConfig():
def get_cfg_option_bool(yobj, key, default=False):
print "searching for %s" % key
if not yobj.has_key(key): return default
val = yobj[key]
if yobj[key] in [ True, '1', 'on', 'yes', 'true']:
@ -152,3 +201,53 @@ def read_conf(fname):
conf = yaml.load(stream)
stream.close()
return conf
def apply_credentials(keys, user, disable_root):
if user:
setup_user_keys(keys, user, '')
if disable_root:
key_prefix = 'command="echo \'Please login as the %s user rather than root user.\';echo;sleep 10" ' % user
else:
key_prefix = ''
setup_user_keys(keys, 'root', key_prefix)
def setup_user_keys(keys, user, key_prefix):
import pwd
saved_umask = os.umask(077)
pwent = pwd.getpwnam(user)
ssh_dir = '%s/.ssh' % pwent.pw_dir
if not os.path.exists(ssh_dir):
os.mkdir(ssh_dir)
os.chown(ssh_dir, pwent.pw_uid, pwent.pw_gid)
authorized_keys = '%s/.ssh/authorized_keys' % pwent.pw_dir
fp = open(authorized_keys, 'a')
fp.write(''.join(['%s%s\n' % (key_prefix, key) for key in keys]))
fp.close()
os.chown(authorized_keys, pwent.pw_uid, pwent.pw_gid)
os.umask(saved_umask)
def send_ssh_keys_to_console():
send_keys_sh = """
{
echo
echo "#############################################################"
echo "-----BEGIN SSH HOST KEY FINGERPRINTS-----"
ssh-keygen -l -f /etc/ssh/ssh_host_rsa_key.pub
ssh-keygen -l -f /etc/ssh/ssh_host_dsa_key.pub
echo "-----END SSH HOST KEY FINGERPRINTS-----"
echo "#############################################################"
} | logger -p user.info -s -t "ec2"
"""
subprocess.call(('sh', '-c', send_keys_sh))
def warn(str):
sys.stderr.write("Warning:%s\n" % str)

View File

@ -43,7 +43,6 @@ import UserDataHandler
class EC2Init:
datasource_list = [ DataSourceEc2.DataSourceEc2 ]
part_handlers = { }
conffile = '/etc/ec2-init/ec2-config.cfg'
def __init__(self):
self.part_handlers = {
@ -53,8 +52,6 @@ class EC2Init:
'text/part-handler' : self.handle_handler
}
self.config = ConfigObj(self.conffile)
def restore_from_cache(self):
try:
f=open(data_source_cache, "rb")
@ -97,15 +94,6 @@ class EC2Init:
write_file(userdata_raw, self.datasource.get_userdata_raw(), 0644)
write_file(userdata, self.datasource.get_userdata(), 0644)
def get_cfg_option_bool(self, key, default=None):
val = self.config.get(key, default)
if val.lower() in ['1', 'on', 'yes']:
return True
return False
def get_cfg_option_str(self, key, default=None):
return self.config.get(key, default)
def initctl_emit(self):
subprocess.Popen(['initctl', 'emit', 'cloud-config',
'%s=%s' % (cfg_env_name,cloud_config)]).communicate()
@ -233,22 +221,6 @@ class EC2Init:
def get_hostname(self):
return(self.datasource.get_hostname())
def apply_credentials(self):
user = self.get_cfg_option_str('user')
disable_root = self.get_cfg_option_bool('disable_root', True)
keys = self.get_public_ssh_keys()
if user:
setup_user_keys(keys, user, '')
if disable_root:
key_prefix = 'command="echo \'Please login as the ubuntu user rather than root user.\';echo;sleep 10" '
else:
key_prefix = ''
setup_user_keys(keys, 'root', key_prefix)
def enable_swap(self):
swaps=[]
try:
@ -302,22 +274,3 @@ def write_file(file,content,mode=0644):
f.close()
os.chmod(file,mode)
def setup_user_keys(keys, user, key_prefix):
saved_umask = os.umask(077)
pwent = pwd.getpwnam(user)
ssh_dir = '%s/.ssh' % pwent.pw_dir
if not os.path.exists(ssh_dir):
os.mkdir(ssh_dir)
os.chown(ssh_dir, pwent.pw_uid, pwent.pw_gid)
authorized_keys = '%s/.ssh/authorized_keys' % pwent.pw_dir
fp = open(authorized_keys, 'a')
fp.write(''.join(['%s%s\n' % (key_prefix, key) for key in keys]))
fp.close()
os.chown(authorized_keys, pwent.pw_uid, pwent.pw_gid)
os.umask(saved_umask)

View File

@ -4,9 +4,7 @@
description "Download preconfigured ssh keys"
start on (cloud-config
and local-filesystems
and net-device-ifup IFACE=eth0 and starting ssh)
start on (cloud-config and local-filesystems)
console output
task