- Converted user list to user dict to allow exclusion of the default user
on Ubuntu systems via cloud-config (LP: #1041384). - Fixed bug with user creation on Ubuntu where the default user groups are not set properly (LP: #1044044). - Fixed documentation for user creation (LP: #1044508).
This commit is contained in:
parent
7d2c506bae
commit
dbc030b2ab
@ -107,7 +107,7 @@ def handle(_name, cfg, cloud, log, _args):
|
|||||||
user = cloud.distro.get_default_user()
|
user = cloud.distro.get_default_user()
|
||||||
|
|
||||||
if 'users' in cfg:
|
if 'users' in cfg:
|
||||||
user_zero = cfg['users'].keys()[0]
|
user_zero = cfg['users'][0]
|
||||||
|
|
||||||
if user_zero != "default":
|
if user_zero != "default":
|
||||||
user = user_zero
|
user = user_zero
|
||||||
|
@ -40,18 +40,31 @@ def handle(_name, cfg, cloud, log, args):
|
|||||||
|
|
||||||
# import for cloudinit created users
|
# import for cloudinit created users
|
||||||
elist = []
|
elist = []
|
||||||
for user in cfg['users'].keys():
|
for user_cfg in cfg['users']:
|
||||||
if user == "default":
|
user = None
|
||||||
|
import_ids = []
|
||||||
|
|
||||||
|
if isinstance(user_cfg, str) and user_cfg == "default":
|
||||||
user = cloud.distro.get_default_user()
|
user = cloud.distro.get_default_user()
|
||||||
if not user:
|
if not user:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
import_ids = util.get_cfg_option_list(cfg, "ssh_import_id", [])
|
import_ids = util.get_cfg_option_list(cfg, "ssh_import_id", [])
|
||||||
else:
|
|
||||||
if not isinstance(cfg['users'][user], dict):
|
elif isinstance(user_cfg, dict):
|
||||||
log.debug("cfg['users'][%s] not a dict, skipping ssh_import",
|
user = None
|
||||||
user)
|
import_ids = []
|
||||||
import_ids = util.get_cfg_option_list(cfg['users'][user],
|
|
||||||
"ssh_import_id", [])
|
try:
|
||||||
|
user = user_cfg['name']
|
||||||
|
import_ids = user_cfg['ssh_import_id']
|
||||||
|
|
||||||
|
if import_ids and isinstance(import_ids, str):
|
||||||
|
import_ids = import_ids.split(',')
|
||||||
|
|
||||||
|
except:
|
||||||
|
log.debug("user %s is not configured for ssh_import" % user)
|
||||||
|
continue
|
||||||
|
|
||||||
if not len(import_ids):
|
if not len(import_ids):
|
||||||
continue
|
continue
|
||||||
@ -59,8 +72,8 @@ def handle(_name, cfg, cloud, log, args):
|
|||||||
try:
|
try:
|
||||||
import_ssh_ids(import_ids, user, log)
|
import_ssh_ids(import_ids, user, log)
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
util.logexc(exc, "ssh-import-id failed for: %s %s" %
|
util.logexc(log, "ssh-import-id failed for: %s %s" %
|
||||||
(user, import_ids))
|
(user, import_ids), exc)
|
||||||
elist.append(exc)
|
elist.append(exc)
|
||||||
|
|
||||||
if len(elist):
|
if len(elist):
|
||||||
@ -68,6 +81,7 @@ def handle(_name, cfg, cloud, log, args):
|
|||||||
|
|
||||||
|
|
||||||
def import_ssh_ids(ids, user, log):
|
def import_ssh_ids(ids, user, log):
|
||||||
|
|
||||||
if not (user and ids):
|
if not (user and ids):
|
||||||
log.debug("empty user(%s) or ids(%s). not importing", user, ids)
|
log.debug("empty user(%s) or ids(%s). not importing", user, ids)
|
||||||
return
|
return
|
||||||
|
@ -38,19 +38,17 @@ def handle(name, cfg, cloud, log, _args):
|
|||||||
if 'users' in cfg:
|
if 'users' in cfg:
|
||||||
user_zero = None
|
user_zero = None
|
||||||
|
|
||||||
for name, user_config in cfg['users'].iteritems():
|
for user_config in cfg['users']:
|
||||||
if not user_zero:
|
|
||||||
user_zero = name
|
|
||||||
|
|
||||||
# Handle the default user creation
|
# Handle the default user creation
|
||||||
if name == "default" and user_config:
|
if 'default' in user_config:
|
||||||
log.info("Creating default user")
|
log.info("Creating default user")
|
||||||
|
|
||||||
# Create the default user if so defined
|
# Create the default user if so defined
|
||||||
try:
|
try:
|
||||||
cloud.distro.add_default_user()
|
cloud.distro.add_default_user()
|
||||||
|
|
||||||
if user_zero == name:
|
if not user_zero:
|
||||||
user_zero = cloud.distro.get_default_user()
|
user_zero = cloud.distro.get_default_user()
|
||||||
|
|
||||||
except NotImplementedError:
|
except NotImplementedError:
|
||||||
@ -60,11 +58,21 @@ def handle(name, cfg, cloud, log, _args):
|
|||||||
|
|
||||||
log.warn("Distro has not implemented default user "
|
log.warn("Distro has not implemented default user "
|
||||||
"creation. No default user will be created")
|
"creation. No default user will be created")
|
||||||
else:
|
|
||||||
|
elif isinstance(user_config, dict) and 'name' in user_config:
|
||||||
|
|
||||||
|
name = user_config['name']
|
||||||
|
if not user_zero:
|
||||||
|
user_zero = name
|
||||||
|
|
||||||
# Make options friendly for distro.create_user
|
# Make options friendly for distro.create_user
|
||||||
new_opts = {}
|
new_opts = {}
|
||||||
if isinstance(user_config, dict):
|
if isinstance(user_config, dict):
|
||||||
for opt in user_config:
|
for opt in user_config:
|
||||||
new_opts[opt.replace('-', '')] = user_config[opt]
|
new_opts[opt.replace('-', '_')] = user_config[opt]
|
||||||
|
|
||||||
cloud.distro.create_user(name, **new_opts)
|
cloud.distro.create_user(**new_opts)
|
||||||
|
|
||||||
|
else:
|
||||||
|
# create user with no configuration
|
||||||
|
cloud.distro.create_user(user_config)
|
||||||
|
@ -47,6 +47,7 @@ class Distro(object):
|
|||||||
|
|
||||||
__metaclass__ = abc.ABCMeta
|
__metaclass__ = abc.ABCMeta
|
||||||
default_user = None
|
default_user = None
|
||||||
|
default_user_groups = None
|
||||||
|
|
||||||
def __init__(self, name, cfg, paths):
|
def __init__(self, name, cfg, paths):
|
||||||
self._paths = paths
|
self._paths = paths
|
||||||
@ -59,16 +60,25 @@ class Distro(object):
|
|||||||
# - nopasswd sudo access
|
# - nopasswd sudo access
|
||||||
|
|
||||||
user = self.get_default_user()
|
user = self.get_default_user()
|
||||||
|
groups = self.get_default_user_groups()
|
||||||
|
|
||||||
if not user:
|
if not user:
|
||||||
raise NotImplementedError("No Default user")
|
raise NotImplementedError("No Default user")
|
||||||
|
|
||||||
self.create_user(user,
|
user_dict = {
|
||||||
plain_text_passwd=user,
|
'name': user,
|
||||||
home="/home/%s" % user,
|
'plain_text_passwd': user,
|
||||||
shell="/bin/bash",
|
'home': "/home/%s" % user,
|
||||||
lockpasswd=True,
|
'shell': "/bin/bash",
|
||||||
gecos="%s%s" % (user[0:1].upper(), user[1:]),
|
'lock_passwd': True,
|
||||||
sudo="ALL=(ALL) NOPASSWD:ALL")
|
'gecos': "%s%s" % (user[0:1].upper(), user[1:]),
|
||||||
|
'sudo': "ALL=(ALL) NOPASSWD:ALL",
|
||||||
|
}
|
||||||
|
|
||||||
|
if groups:
|
||||||
|
user_dict['groups'] = groups
|
||||||
|
|
||||||
|
self.create_user(**user_dict)
|
||||||
|
|
||||||
LOG.info("Added default '%s' user with passwordless sudo", user)
|
LOG.info("Added default '%s' user with passwordless sudo", user)
|
||||||
|
|
||||||
@ -204,6 +214,9 @@ class Distro(object):
|
|||||||
def get_default_user(self):
|
def get_default_user(self):
|
||||||
return self.default_user
|
return self.default_user
|
||||||
|
|
||||||
|
def get_default_user_groups(self):
|
||||||
|
return self.default_user_groups
|
||||||
|
|
||||||
def create_user(self, name, **kwargs):
|
def create_user(self, name, **kwargs):
|
||||||
"""
|
"""
|
||||||
Creates users for the system using the GNU passwd tools. This
|
Creates users for the system using the GNU passwd tools. This
|
||||||
@ -220,7 +233,7 @@ class Distro(object):
|
|||||||
adduser_opts = {
|
adduser_opts = {
|
||||||
"gecos": '--comment',
|
"gecos": '--comment',
|
||||||
"homedir": '--home',
|
"homedir": '--home',
|
||||||
"primarygroup": '--gid',
|
"primary_group": '--gid',
|
||||||
"groups": '--groups',
|
"groups": '--groups',
|
||||||
"passwd": '--password',
|
"passwd": '--password',
|
||||||
"shell": '--shell',
|
"shell": '--shell',
|
||||||
@ -229,10 +242,10 @@ class Distro(object):
|
|||||||
}
|
}
|
||||||
|
|
||||||
adduser_opts_flags = {
|
adduser_opts_flags = {
|
||||||
"nousergroup": '--no-user-group',
|
"no_user_group": '--no-user-group',
|
||||||
"system": '--system',
|
"system": '--system',
|
||||||
"nologinit": '--no-log-init',
|
"no_log_init": '--no-log-init',
|
||||||
"nocreatehome": "-M",
|
"no_create_home": "-M",
|
||||||
}
|
}
|
||||||
|
|
||||||
# Now check the value and create the command
|
# Now check the value and create the command
|
||||||
@ -254,7 +267,7 @@ class Distro(object):
|
|||||||
|
|
||||||
# Default to creating home directory unless otherwise directed
|
# Default to creating home directory unless otherwise directed
|
||||||
# Also, we do not create home directories for system users.
|
# Also, we do not create home directories for system users.
|
||||||
if "nocreatehome" not in kwargs and "system" not in kwargs:
|
if "no_create_home" not in kwargs and "system" not in kwargs:
|
||||||
adduser_cmd.append('-m')
|
adduser_cmd.append('-m')
|
||||||
|
|
||||||
# Create the user
|
# Create the user
|
||||||
@ -273,8 +286,8 @@ class Distro(object):
|
|||||||
self.set_passwd(name, kwargs['plain_text_passwd'])
|
self.set_passwd(name, kwargs['plain_text_passwd'])
|
||||||
|
|
||||||
# Default locking down the account.
|
# Default locking down the account.
|
||||||
if ('lockpasswd' not in kwargs and
|
if ('lock_passwd' not in kwargs and
|
||||||
('lockpasswd' in kwargs and kwargs['lockpasswd']) or
|
('lock_passwd' in kwargs and kwargs['lock_passwd']) or
|
||||||
'system' not in kwargs):
|
'system' not in kwargs):
|
||||||
try:
|
try:
|
||||||
util.subp(['passwd', '--lock', name])
|
util.subp(['passwd', '--lock', name])
|
||||||
@ -288,8 +301,8 @@ class Distro(object):
|
|||||||
self.write_sudo_rules(name, kwargs['sudo'])
|
self.write_sudo_rules(name, kwargs['sudo'])
|
||||||
|
|
||||||
# Import SSH keys
|
# Import SSH keys
|
||||||
if 'sshauthorizedkeys' in kwargs:
|
if 'ssh_authorized_keys' in kwargs:
|
||||||
keys = set(kwargs['sshauthorizedkeys']) or []
|
keys = set(kwargs['ssh_authorized_keys']) or []
|
||||||
ssh_util.setup_user_keys(keys, name, None, self._paths)
|
ssh_util.setup_user_keys(keys, name, None, self._paths)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
@ -31,3 +31,5 @@ class Distro(debian.Distro):
|
|||||||
|
|
||||||
distro_name = 'ubuntu'
|
distro_name = 'ubuntu'
|
||||||
default_user = 'ubuntu'
|
default_user = 'ubuntu'
|
||||||
|
default_user_groups = ("adm,admin,audio,cdrom,dialout,floppy,video,"
|
||||||
|
"plugdev,dip,netdev,sudo")
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
# Implement for Ubuntu only: create the default 'ubuntu' user
|
# Implement for Ubuntu only: create the default 'ubuntu' user
|
||||||
users:
|
users:
|
||||||
default: true
|
- default
|
||||||
|
|
||||||
# If this is set, 'root' will not be able to ssh in and they
|
# If this is set, 'root' will not be able to ssh in and they
|
||||||
# will get a message to login instead as the above $user (ubuntu)
|
# will get a message to login instead as the above $user (ubuntu)
|
||||||
|
@ -7,6 +7,7 @@ groups:
|
|||||||
|
|
||||||
# add users to the system. Users are added after groups are added.
|
# add users to the system. Users are added after groups are added.
|
||||||
users:
|
users:
|
||||||
|
- default
|
||||||
- name: foobar
|
- name: foobar
|
||||||
gecos: Foo B. Bar
|
gecos: Foo B. Bar
|
||||||
primary-group: foobar
|
primary-group: foobar
|
||||||
@ -24,12 +25,13 @@ users:
|
|||||||
ssh-authorized-keys:
|
ssh-authorized-keys:
|
||||||
- <ssh pub key 1>
|
- <ssh pub key 1>
|
||||||
- <ssh pub key 2>
|
- <ssh pub key 2>
|
||||||
cloudy:
|
- name cloudy
|
||||||
gecos: Magic Cloud App Daemon User
|
gecos: Magic Cloud App Daemon User
|
||||||
inactive: true
|
inactive: true
|
||||||
system: true
|
system: true
|
||||||
|
|
||||||
# Valid Values:
|
# Valid Values:
|
||||||
|
# name: The user's login name
|
||||||
# gecos: The user name's real name, i.e. "Bob B. Smith"
|
# gecos: The user name's real name, i.e. "Bob B. Smith"
|
||||||
# homedir: Optional. Set to the local path you want to use. Defaults to
|
# homedir: Optional. Set to the local path you want to use. Defaults to
|
||||||
# /home/<username>
|
# /home/<username>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user